# Pear-published bare-os booter (consumer). Build (use --progress=plain to see all steps): # docker build --progress=plain -t bare-os-booter . # # Pear CLI + Pear/Bare runtime are installed during the image build under /opt/pear-home. # That tree is chowned to user `booter` because the runtime refuses to run unless the # active user owns the Pear config directory. # # Runtime env: HOME must stay /opt/pear-home (Pear runtime lives there). bare-os state uses # BARE_OS_HOST_DATA=/data (volume). Do not set HOME=/data — Pear will not boot the app. # # Entrypoint runs `pear run --no-ask pear://…` so non-interactive starts skip Pear’s TRUST prompt. # # Run — interactive / attachable (needs TTY + stdin for the shell REPL): # docker run --rm -it -v bare-os-booter-data:/data --name bare-os-booter bare-os-booter # # Detached, then attach to the same session: # docker run -dit --name bare-os-booter -v bare-os-booter-data:/data bare-os-booter # docker attach bare-os-booter # # Or: docker compose -f docker-compose.yaml up -d booter && docker compose attach booter # # The booter needs a Hyperswarm peer (seeder on topic bare-os-v1) within BARE_OS_BOOT_TIMEOUT_MS, # or set BARE_OS_OFFLINE_LKG_BOOT + BARE_OS_LKG_SYSTEM_KEY_HEX — see bare-os docs. # # If peers never appear: UDP/hole-punch often fails behind Docker NAT — on Linux use # docker-compose.host-network.yaml (merge) so the container uses the host network stack. # Pear terminal expectations: https://docs.pears.com/guide/making-a-pear-terminal-app.html FROM node:22-bookworm-slim RUN apt-get update \ && apt-get install -y --no-install-recommends \ bash \ bsdutils \ ca-certificates \ libatomic1 \ && rm -rf /var/lib/apt/lists/* # Bootstrap CLI + runtime under a fixed HOME so paths stay inside the image. ENV HOME=/opt/pear-home RUN mkdir -p /opt/pear-home \ && set -ex \ && echo "=== npm: global pear CLI ===" \ && npm install -g pear@latest \ && npm ls -g --depth=0 pear \ && PEAR_CLI="$(command -v pear)" \ && echo "pear CLI path: ${PEAR_CLI}" \ && ls -la "${PEAR_CLI}" \ && echo "=== pear run pear://runtime (Pear/Bare runtime; requires network during build) ===" \ && pear run pear://runtime \ && echo "=== Runtime tree ===" \ && ls -la /opt/pear-home/.config/pear \ && ls -la /opt/pear-home/.config/pear/bin \ && du -sh /opt/pear-home/.config/pear \ && echo "=== PATH: runtime shim resolves ===" \ && export PATH="/opt/pear-home/.config/pear/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" \ && SHIM="$(command -v pear)" \ && echo "first pear on PATH: ${SHIM}" \ && ls -la "${SHIM}" \ && echo "=== pear help (via runtime shim; must succeed) ===" \ && pear help | head -30 \ && echo "=== npm pear CLI (explicit path; still useful for diagnostics) ===" \ && /usr/local/bin/pear --help | head -20 RUN chmod -R a+rX /opt/pear-home \ && find /opt/pear-home/.config/pear -type f \( -perm -111 -o -name 'pear-runtime' -o -name 'pear' \) \ -exec chmod a+rx {} \; 2>/dev/null || true ENV PATH="/opt/pear-home/.config/pear/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" RUN groupadd --system booter \ && useradd --system --gid booter --home-dir /data --create-home booter \ && chown -R booter:booter /opt/pear-home \ && echo "=== Ownership after chown ===" \ && id booter \ && ls -la /opt/pear-home/.config \ && echo "=== Smoke: booter user runs pear runtime shim ===" \ && su -s /bin/sh booter -c \ 'set -ex; id; command -v pear; pear help | head -20' RUN mkdir -p /usr/local/lib/bare-os-booter COPY run-pear-inner.sh /usr/local/lib/bare-os-booter/run-pear-inner.sh COPY docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh RUN chmod 755 /usr/local/lib/bare-os-booter/run-pear-inner.sh \ && chmod 755 /usr/local/bin/docker-entrypoint.sh USER booter WORKDIR /data ENV NODE_ENV=production # Pear: trust + shim under /opt/pear-home — must match install (see build-time HOME). ENV HOME=/opt/pear-home # bare-os: Corestore + host data on the mounted volume (overrides homedir for host paths). ENV BARE_OS_HOST_DATA=/data # Default wait for at least one swarm peer (seeder). Raise if needed. ENV BARE_OS_BOOT_TIMEOUT_MS=120000 # Line-oriented stderr in Docker; avoids full-screen splash on stdout obscuring docker logs. ENV BARE_OS_NO_SPLASH=1 ENV TERM=xterm-256color VOLUME ["/data"] ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]