From 8d6c471b100ea3b828a5b0ceb8c5ce509794bb84 Mon Sep 17 00:00:00 2001 From: Shane Maynard Date: Thu, 30 Jul 2026 20:31:10 -0400 Subject: [PATCH] Seed writable Pi runtime config in Docker --- Dockerfile | 6 +++++- README.md | 2 +- docker-compose.yml | 4 ++-- docker-entrypoint.sh | 13 +++++++++++++ 4 files changed, 21 insertions(+), 4 deletions(-) create mode 100644 docker-entrypoint.sh diff --git a/Dockerfile b/Dockerfile index 7137f6d..ea8e094 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,10 +12,14 @@ COPY shared ./shared COPY db/migrations ./db/migrations COPY scripts ./scripts RUN node scripts/stamp-asset-version.mjs +COPY docker-entrypoint.sh /usr/local/bin/roast-command-center-entrypoint +RUN chmod 755 /usr/local/bin/roast-command-center-entrypoint -# The optional Pi agent configuration is mounted read-only here at runtime. +# The optional Pi agent configuration is mounted read-only at /run and copied to this writable +# runtime directory by the entrypoint; Pi's auth storage needs a sibling lock file. ENV HOME=/home/node RUN mkdir -p /home/node/.pi/agent && chown -R node:node /home/node/.pi USER node EXPOSE 8090 +ENTRYPOINT ["roast-command-center-entrypoint"] CMD ["node", "server/index.js"] diff --git a/README.md b/README.md index 8e3b310..ea52829 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ Generate `BOOTSTRAP_SETUP_TOKEN` with `openssl rand -base64 48`, keep it only in ### Pi agent configuration in Docker -The `app` service mounts `PI_AGENT_CONFIG_DIR` (default `./appdata/pi-agent`) read-only at `/home/node/.pi/agent`, the non-root Node user's Pi configuration directory. This lets `/api/prefill` use the same configured model at runtime without baking credentials into the image. The directory is ignored by Git and Docker build context; do not commit its contents. +The `app` service mounts `PI_AGENT_CONFIG_DIR` (default `./appdata/pi-agent`) read-only at `/run/pi-agent-config`. Its entrypoint copies that seed into the non-root Node user's writable runtime configuration directory before startup: Pi's credential storage needs to create a lock beside `auth.json`. This lets `/api/prefill` use the configured model without baking credentials into the image or mutating the host configuration. The directory is ignored by Git and Docker build context; do not commit its contents. Before bringing up the stack, sync only the local Pi agent configuration you intend to make available to the container: diff --git a/docker-compose.yml b/docker-compose.yml index 9c74a96..83d9da1 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -15,8 +15,8 @@ services: extra_hosts: - "host.docker.internal:host-gateway" volumes: - # Mount only non-secret Pi agent model/auth configuration; keep it read-only. - - ${PI_AGENT_CONFIG_DIR:-./appdata/pi-agent}:/home/node/.pi/agent:ro + # Seed Pi's writable runtime config from this read-only credential mount. + - ${PI_AGENT_CONFIG_DIR:-./appdata/pi-agent}:/run/pi-agent-config:ro depends_on: db: condition: service_healthy diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh new file mode 100644 index 0000000..62b1b5c --- /dev/null +++ b/docker-entrypoint.sh @@ -0,0 +1,13 @@ +#!/bin/sh +set -eu + +# The mounted Pi configuration contains credentials and must stay read-only. Pi's auth storage +# takes a lock beside auth.json, so seed a writable per-container copy before the app starts. +# That lets ModelRuntime read and refresh credentials without ever mutating the host mount. +if [ -d /run/pi-agent-config ]; then + mkdir -p "$HOME/.pi/agent" + cp -a /run/pi-agent-config/. "$HOME/.pi/agent/" + chmod -R u+rwX "$HOME/.pi/agent" +fi + +exec "$@"