fix: name docker runtime user

This commit is contained in:
Pi Web Agent
2026-06-21 22:51:29 +00:00
parent f8982a9947
commit f94424c43b
8 changed files with 48 additions and 11 deletions
+5
View File
@@ -0,0 +1,5 @@
---
"@jmfederico/pi-web": patch
---
Create the Docker image `pi-web` user with the configured host UID/GID so container terminals show a normal username instead of `I have no name!`.
+3 -1
View File
@@ -10,6 +10,8 @@ FROM ${OPENSUSE_IMAGE} AS base
ARG NODEJS_MAJOR=22
ARG NODEJS_REPO=auto
ARG PI_WEB_EXTRA_ZYPPER_PACKAGES=""
ARG PI_WEB_UID=1000
ARG PI_WEB_GID=1000
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
@@ -68,7 +70,7 @@ RUN bash -euxo pipefail -c '\
'
WORKDIR /workspace
USER node
USER pi-web
EXPOSE 8504
+2
View File
@@ -10,6 +10,8 @@ FROM ${OPENSUSE_IMAGE} AS dev
ARG NODEJS_MAJOR=22
ARG NODEJS_REPO=auto
ARG PI_WEB_EXTRA_ZYPPER_PACKAGES=""
ARG PI_WEB_UID=1000
ARG PI_WEB_GID=1000
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
+3 -3
View File
@@ -91,7 +91,7 @@ Common environment variables written to `.env`:
| Variable | Purpose |
| --- | --- |
| `PI_WEB_UID`, `PI_WEB_GID` | user/group used by the runtime containers |
| `PI_WEB_UID`, `PI_WEB_GID` | user/group used by the runtime containers and the image's `pi-web` account |
| `DOCKER_GID` | extra group used for Docker socket access |
| `PI_WEB_DOCKER_DATA_DIR` | persistent data bind mount |
| `PI_WEB_BIND_ADDR`, `PI_WEB_PORT` | host bind address and port |
@@ -108,7 +108,7 @@ Host-derived IDs are refreshed on rerun unless you explicitly override them. Use
### Base image and tooling
The Docker runtime and development images are openSUSE Tumbleweed based by default. They install Node.js 22, npm, `npx`, and Corepack through zypper, using the openSUSE Node.js build service repository when needed for the selected architecture. The image also includes common agent/development tools such as Git/Git LFS, GitHub CLI, OpenSSH, Python with pip/virtualenv and headers, native build tooling, `jq`, `ripgrep`, `fd`, `fzf`, `bat`, ShellCheck, archive tools, network utilities, and the Docker CLI.
The Docker runtime and development images are openSUSE Tumbleweed based by default. They install Node.js 22, npm, `npx`, and Corepack through zypper, using the openSUSE Node.js build service repository when needed for the selected architecture. The image's `pi-web` account is created with `PI_WEB_UID:PI_WEB_GID`, so shells have a passwd entry instead of showing `I have no name!` when the host user is not `1000:1000`. The image also includes common agent/development tools such as Git/Git LFS, GitHub CLI, OpenSSH, Python with pip/virtualenv and headers, native build tooling, `jq`, `ripgrep`, `fd`, `fzf`, `bat`, ShellCheck, archive tools, network utilities, and the Docker CLI.
Install extra distro packages without writing a hook by setting a whitespace-delimited package list:
@@ -266,7 +266,7 @@ Restart `sessiond` manually after changes that affect `src/server/sessiond.ts`,
The dev setup intentionally has the same Docker socket and broad host mounts as the runtime setup. The same trust warnings apply.
On startup, a short `data-init` service creates the shared `/data` subdirectories and gives them to `PI_WEB_UID:PI_WEB_GID`. This handles the common Flatcar/Docker case where a missing bind-mount directory is created as root by the Docker daemon.
On startup, a short `data-init` service creates the shared `/data` subdirectories and gives them to `PI_WEB_UID:PI_WEB_GID`. This handles the common Flatcar/Docker case where a missing bind-mount directory is created as root by the Docker daemon. Because the image also builds its `pi-web` account with those IDs, rebuild the image if you change `PI_WEB_UID` or `PI_WEB_GID`.
### Sharing runtime and development state
+30 -6
View File
@@ -4,6 +4,8 @@ set -euo pipefail
nodejs_major=${NODEJS_MAJOR:-22}
nodejs_repo=${NODEJS_REPO:-auto}
extra_zypper_packages=${PI_WEB_EXTRA_ZYPPER_PACKAGES:-}
runtime_uid=${PI_WEB_UID:-1000}
runtime_gid=${PI_WEB_GID:-1000}
nodejs_repo_flavor() {
local rpm_arch
@@ -120,16 +122,38 @@ npx --version
python3 --version
git --version
if ! getent group node >/dev/null 2>&1; then
groupadd --gid 1000 node
case "$runtime_uid" in
""|*[!0-9]*)
echo "PI_WEB_UID must be a numeric user ID, got: $runtime_uid" >&2
exit 1
;;
esac
case "$runtime_gid" in
""|*[!0-9]*)
echo "PI_WEB_GID must be a numeric group ID, got: $runtime_gid" >&2
exit 1
;;
esac
runtime_user=pi-web
runtime_group=pi-web
if getent group "$runtime_gid" >/dev/null 2>&1; then
runtime_group=$(getent group "$runtime_gid" | cut -d: -f1)
elif getent group "$runtime_group" >/dev/null 2>&1; then
groupmod --gid "$runtime_gid" "$runtime_group"
else
groupadd --gid "$runtime_gid" "$runtime_group"
fi
if ! id node >/dev/null 2>&1; then
useradd --uid 1000 --gid node --create-home --home-dir /home/node --shell /bin/bash node
if id "$runtime_user" >/dev/null 2>&1; then
usermod --non-unique --uid "$runtime_uid" --gid "$runtime_group" --home "/home/$runtime_user" --shell /bin/bash "$runtime_user"
else
useradd --non-unique --uid "$runtime_uid" --gid "$runtime_group" --create-home --home-dir "/home/$runtime_user" --shell /bin/bash "$runtime_user"
fi
mkdir -p /data/home /data/config /data/npm-cache /data/pi-web /data/pi-agent /workspace
chown -R node:node /data /workspace /home/node
mkdir -p /data/home /data/config /data/npm-cache /data/pi-web /data/pi-agent /workspace "/home/$runtime_user"
chown -R "$runtime_uid:$runtime_gid" /data /workspace "/home/$runtime_user"
zypper clean --all
rm -rf /var/cache/zypp/*
+2
View File
@@ -8,6 +8,8 @@ x-pi-web-dev-build: &pi-web-dev-build
NODEJS_MAJOR: ${PI_WEB_NODEJS_MAJOR:-22}
NODEJS_REPO: ${PI_WEB_NODEJS_REPO:-auto}
PI_WEB_EXTRA_ZYPPER_PACKAGES: ${PI_WEB_EXTRA_ZYPPER_PACKAGES:-}
PI_WEB_UID: ${PI_WEB_UID:-1000}
PI_WEB_GID: ${PI_WEB_GID:-1000}
x-pi-web-dev-environment: &pi-web-dev-environment
HOME: /data/home
+2
View File
@@ -8,6 +8,8 @@ x-pi-web-build: &pi-web-build
NODEJS_MAJOR: ${PI_WEB_NODEJS_MAJOR:-22}
NODEJS_REPO: ${PI_WEB_NODEJS_REPO:-auto}
PI_WEB_EXTRA_ZYPPER_PACKAGES: ${PI_WEB_EXTRA_ZYPPER_PACKAGES:-}
PI_WEB_UID: ${PI_WEB_UID:-1000}
PI_WEB_GID: ${PI_WEB_GID:-1000}
PI_WEB_VERSION: ${PI_WEB_VERSION:-latest}
PI_VERSION: ${PI_VERSION:-latest}
CACHE_BUST: ${CACHE_BUST:-local}
+1 -1
View File
@@ -388,7 +388,7 @@ cat >"$temp_env" <<EOF
# Re-run install.sh to refresh Docker assets and update the local image.
# Persistent data lives in PI_WEB_DOCKER_DATA_DIR and is not deleted by updates.
# Host identity used for the runtime containers.
# Host identity used for the runtime containers and image user account.
PI_WEB_UID=$pi_web_uid
PI_WEB_GID=$pi_web_gid
DOCKER_GID=$docker_gid