fix: run container as host PUID/PGID for workspace mounts
node uid 1000 could not read /home/frank (frank=1002); build and compose now use configurable PUID/PGID. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+8
-4
@@ -3,8 +3,12 @@
|
||||
# OpenRouter (recommended default provider for this stack)
|
||||
OPENROUTER_API_KEY=sk-or-v1-replace-me
|
||||
|
||||
# Match host user that owns the workspace mount (boka: id -u / id -g → 1002)
|
||||
PUID=1002
|
||||
PGID=1002
|
||||
|
||||
# Host directory mounted at /workspaces inside the containers.
|
||||
# On boka, point at the projects Pi should see, e.g.:
|
||||
# WORKSPACE_HOST_PATH=/home/frank
|
||||
# For local smoke tests, leave unset to use ./workspaces
|
||||
WORKSPACE_HOST_PATH=./workspaces
|
||||
# On boka:
|
||||
WORKSPACE_HOST_PATH=/home/frank
|
||||
# For local smoke tests without /home/frank projects:
|
||||
# WORKSPACE_HOST_PATH=./workspaces
|
||||
|
||||
@@ -19,15 +19,18 @@ cd /home/frank/pi.schwenk.online
|
||||
|
||||
cp .env.example .env
|
||||
# edit OPENROUTER_API_KEY
|
||||
# set WORKSPACE_HOST_PATH to the host dirs Pi should edit, e.g. /home/frank
|
||||
# PUID/PGID = host user (frank on boka: 1002) — must match `id -u` / `id -g`
|
||||
# WORKSPACE_HOST_PATH=/home/frank
|
||||
|
||||
mkdir -p data/pi-web data/pi-agent workspaces
|
||||
# Container runs as uid 1000 (node); fix ownership if needed:
|
||||
sudo chown -R 1000:1000 data workspaces
|
||||
mkdir -p data/pi-web data/pi-agent
|
||||
chown -R "$(id -u):$(id -g)" data
|
||||
|
||||
docker compose build
|
||||
docker compose up -d
|
||||
docker compose logs -f --tail=100
|
||||
|
||||
# smoke: should list your projects, not Permission denied
|
||||
docker compose exec web ls /workspaces/eselhoefe.de
|
||||
```
|
||||
|
||||
## Verify
|
||||
@@ -56,3 +59,4 @@ docker compose build --no-cache && docker compose up -d
|
||||
- No host port publish; only Traefik on network `traefik` reaches `:8504`
|
||||
- Middleware is referenced only (`authelia@docker`); ForwardAuth is defined on Authelia
|
||||
- `pi-coding-agent` pinned to `0.82.1` for current `pi-web` peer range
|
||||
- Container runs as `PUID`/`PGID` (default 1002) so bind mounts under `/home/frank` are readable
|
||||
|
||||
+15
-10
@@ -1,7 +1,14 @@
|
||||
# Pi Coding Agent + PI WEB (Plain Docker)
|
||||
# Peer pin: pi-web requires pi-coding-agent >=0.82.1 <0.83
|
||||
# Run as host UID/GID so bind-mounted /home/frank (etc.) is readable.
|
||||
ARG PUID=1002
|
||||
ARG PGID=1002
|
||||
|
||||
FROM node:24-bookworm-slim
|
||||
|
||||
ARG PUID=1002
|
||||
ARG PGID=1002
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
bash \
|
||||
@@ -19,28 +26,26 @@ RUN npm install -g --ignore-scripts @earendil-works/pi-coding-agent@0.82.1 \
|
||||
&& npm install -g @jmfederico/pi-web@1.202607.3 --allow-scripts=node-pty \
|
||||
&& npm cache clean --force
|
||||
|
||||
# Drop build toolchain from runtime image layer weight is optional; keep for native package installs
|
||||
# Re-install without g++ would break future pi packages needing compile — leave tools in.
|
||||
RUN groupadd -g "${PGID}" pi \
|
||||
&& useradd -u "${PUID}" -g "${PGID}" -m -d /home/pi -s /bin/bash pi \
|
||||
&& mkdir -p /data/pi-web /workspaces /home/pi/.pi/agent /home/pi/.config/pi-web \
|
||||
&& chown -R pi:pi /data /workspaces /home/pi
|
||||
|
||||
RUN mkdir -p /data/pi-web /workspaces /home/node/.pi/agent /home/node/.config/pi-web \
|
||||
&& chown -R node:node /data /workspaces /home/node/.pi /home/node/.config
|
||||
COPY --chown=pi:pi config/pi-web.config.json /etc/pi-web/config.json
|
||||
|
||||
COPY --chown=node:node config/pi-web.config.json /etc/pi-web/config.json
|
||||
|
||||
ENV HOME=/home/node \
|
||||
ENV HOME=/home/pi \
|
||||
PI_WEB_CONFIG=/etc/pi-web/config.json \
|
||||
PI_WEB_DATA_DIR=/data/pi-web \
|
||||
PI_CODING_AGENT_DIR=/home/node/.pi/agent \
|
||||
PI_CODING_AGENT_DIR=/home/pi/.pi/agent \
|
||||
PI_WEB_SESSIOND_SOCKET=/data/pi-web/sessiond.sock \
|
||||
PI_WEB_HOST=0.0.0.0 \
|
||||
PI_WEB_PORT=8504 \
|
||||
PI_WEB_ALLOWED_HOSTS=pi.schwenk.online \
|
||||
PATH="/usr/local/bin:${PATH}"
|
||||
|
||||
USER node
|
||||
USER pi
|
||||
WORKDIR /workspaces
|
||||
|
||||
EXPOSE 8504
|
||||
|
||||
# Default overridden per-service in compose.yml
|
||||
CMD ["pi-web-server"]
|
||||
|
||||
@@ -13,7 +13,9 @@ Implemented Compose stack for PI WEB + Pi behind Traefik/Authelia. See [DEPLOY.m
|
||||
- `web` HTTP `200` on `:8504`; `pi --version` → `0.82.1`
|
||||
- Full Authelia/DNS/TOTP path: only on boka after DNS + `.env` key
|
||||
|
||||
Stack stopped locally after smoke (`docker compose down`).
|
||||
## UID fix (2026-08-01)
|
||||
|
||||
Container must run as host `frank` (1002:1002), not image `node` (1000). Rebuild with `PUID`/`PGID` after pull.
|
||||
|
||||
## Authelia handoff (locked)
|
||||
|
||||
|
||||
@@ -46,8 +46,9 @@ Fränky — single trusted user; remote control surface for agent work under `/h
|
||||
- **Compose:** `compose.yml` — services `sessiond` + `web`, image built from `Dockerfile`
|
||||
- **Networks:** external `traefik`
|
||||
- **Auth:** Authelia portal `https://auth.schwenk.online`; middleware `authelia@docker`; ACL `two_factor` for this host
|
||||
- **Data:** `./data/pi-web` (PI WEB state + sessiond socket), `./data/pi-agent` → `~/.pi/agent` (sessions, packages, auth)
|
||||
- **Data:** `./data/pi-web` (PI WEB state + sessiond socket), `./data/pi-agent` → `/home/pi/.pi/agent` (sessions, packages, auth)
|
||||
- **Workspaces:** host path via `WORKSPACE_HOST_PATH` → container `/workspaces`
|
||||
- **UID:** `PUID`/`PGID` in `.env` must match host owner of the mount (boka frank = 1002)
|
||||
- **Secrets:** `OPENROUTER_API_KEY` in `.env` (see `.env.example`)
|
||||
|
||||
### Authelia handoff (consumed)
|
||||
|
||||
+20
-9
@@ -1,54 +1,65 @@
|
||||
# PI WEB + Pi Coding Agent behind Traefik + Authelia (external)
|
||||
# Deploy: /home/frank/pi.schwenk.online → https://pi.schwenk.online
|
||||
#
|
||||
# PUID/PGID must match the host user that owns WORKSPACE_HOST_PATH (boka: frank=1002).
|
||||
|
||||
services:
|
||||
sessiond:
|
||||
build: .
|
||||
build:
|
||||
context: .
|
||||
args:
|
||||
PUID: ${PUID:-1002}
|
||||
PGID: ${PGID:-1002}
|
||||
image: pidevremote-pi:local
|
||||
container_name: pi-sessiond
|
||||
restart: unless-stopped
|
||||
user: "${PUID:-1002}:${PGID:-1002}"
|
||||
command: ["pi-web-sessiond"]
|
||||
env_file:
|
||||
- .env
|
||||
environment:
|
||||
HOME: /home/node
|
||||
HOME: /home/pi
|
||||
PI_WEB_CONFIG: /etc/pi-web/config.json
|
||||
PI_WEB_DATA_DIR: /data/pi-web
|
||||
PI_WEB_SESSIOND_SOCKET: /data/pi-web/sessiond.sock
|
||||
PI_CODING_AGENT_DIR: /home/node/.pi/agent
|
||||
PI_CODING_AGENT_DIR: /home/pi/.pi/agent
|
||||
OPENROUTER_API_KEY: ${OPENROUTER_API_KEY:-}
|
||||
volumes:
|
||||
- ./data/pi-web:/data/pi-web
|
||||
- ./data/pi-agent:/home/node/.pi/agent
|
||||
- ./data/pi-agent:/home/pi/.pi/agent
|
||||
- ${WORKSPACE_HOST_PATH:-./workspaces}:/workspaces
|
||||
networks:
|
||||
- internal
|
||||
|
||||
web:
|
||||
build: .
|
||||
build:
|
||||
context: .
|
||||
args:
|
||||
PUID: ${PUID:-1002}
|
||||
PGID: ${PGID:-1002}
|
||||
image: pidevremote-pi:local
|
||||
container_name: pi-web
|
||||
restart: unless-stopped
|
||||
user: "${PUID:-1002}:${PGID:-1002}"
|
||||
command: ["pi-web-server"]
|
||||
depends_on:
|
||||
- sessiond
|
||||
env_file:
|
||||
- .env
|
||||
environment:
|
||||
HOME: /home/node
|
||||
HOME: /home/pi
|
||||
PI_WEB_CONFIG: /etc/pi-web/config.json
|
||||
PI_WEB_DATA_DIR: /data/pi-web
|
||||
PI_WEB_SESSIOND_SOCKET: /data/pi-web/sessiond.sock
|
||||
PI_WEB_HOST: "0.0.0.0"
|
||||
PI_WEB_PORT: "8504"
|
||||
PI_WEB_ALLOWED_HOSTS: pi.schwenk.online
|
||||
PI_CODING_AGENT_DIR: /home/node/.pi/agent
|
||||
PI_CODING_AGENT_DIR: /home/pi/.pi/agent
|
||||
OPENROUTER_API_KEY: ${OPENROUTER_API_KEY:-}
|
||||
volumes:
|
||||
- ./data/pi-web:/data/pi-web
|
||||
- ./data/pi-agent:/home/node/.pi/agent
|
||||
- ./data/pi-agent:/home/pi/.pi/agent
|
||||
- ${WORKSPACE_HOST_PATH:-./workspaces}:/workspaces
|
||||
# No host port publish — Traefik reaches the container on the traefik network
|
||||
expose:
|
||||
- "8504"
|
||||
networks:
|
||||
|
||||
Reference in New Issue
Block a user