Files
bare-operating-system/docker-boot-image/Dockerfile
T
Raven Scott 80485468f0 feat(booter): ephemeral port fallback on EADDRINUSE
Retry listen(0)/bind(0) when the preferred port is taken, gated by
BARE_OS_BIND_FALLBACK (default on; set 0/false for strict bind).

- Add lib/bare-os-bind-fallback.js and use it from bare-os-www-initd and
  bare-openssh (including privilege-path + holesail actual port).
- POSIX socket bridge in index.js: TCP listen and UDP bind fallbacks.
- bare-holesail + bare-holesail-managed: retry Holesail ready(); persist
  resolved listen port in managed state when it changes.
- Add test.bare-os-bind-fallback.js.
2026-04-23 20:39:50 -04:00

106 lines
4.4 KiB
Docker
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 Pears 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"]