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_MAJOR=22
ARG NODEJS_REPO=auto ARG NODEJS_REPO=auto
ARG PI_WEB_EXTRA_ZYPPER_PACKAGES="" ARG PI_WEB_EXTRA_ZYPPER_PACKAGES=""
ARG PI_WEB_UID=1000
ARG PI_WEB_GID=1000
SHELL ["/bin/bash", "-o", "pipefail", "-c"] SHELL ["/bin/bash", "-o", "pipefail", "-c"]
@@ -68,7 +70,7 @@ RUN bash -euxo pipefail -c '\
' '
WORKDIR /workspace WORKDIR /workspace
USER node USER pi-web
EXPOSE 8504 EXPOSE 8504
+2
View File
@@ -10,6 +10,8 @@ FROM ${OPENSUSE_IMAGE} AS dev
ARG NODEJS_MAJOR=22 ARG NODEJS_MAJOR=22
ARG NODEJS_REPO=auto ARG NODEJS_REPO=auto
ARG PI_WEB_EXTRA_ZYPPER_PACKAGES="" ARG PI_WEB_EXTRA_ZYPPER_PACKAGES=""
ARG PI_WEB_UID=1000
ARG PI_WEB_GID=1000
SHELL ["/bin/bash", "-o", "pipefail", "-c"] SHELL ["/bin/bash", "-o", "pipefail", "-c"]
+3 -3
View File
@@ -91,7 +91,7 @@ Common environment variables written to `.env`:
| Variable | Purpose | | 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 | | `DOCKER_GID` | extra group used for Docker socket access |
| `PI_WEB_DOCKER_DATA_DIR` | persistent data bind mount | | `PI_WEB_DOCKER_DATA_DIR` | persistent data bind mount |
| `PI_WEB_BIND_ADDR`, `PI_WEB_PORT` | host bind address and port | | `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 ### 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: 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. 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 ### Sharing runtime and development state
+30 -6
View File
@@ -4,6 +4,8 @@ set -euo pipefail
nodejs_major=${NODEJS_MAJOR:-22} nodejs_major=${NODEJS_MAJOR:-22}
nodejs_repo=${NODEJS_REPO:-auto} nodejs_repo=${NODEJS_REPO:-auto}
extra_zypper_packages=${PI_WEB_EXTRA_ZYPPER_PACKAGES:-} extra_zypper_packages=${PI_WEB_EXTRA_ZYPPER_PACKAGES:-}
runtime_uid=${PI_WEB_UID:-1000}
runtime_gid=${PI_WEB_GID:-1000}
nodejs_repo_flavor() { nodejs_repo_flavor() {
local rpm_arch local rpm_arch
@@ -120,16 +122,38 @@ npx --version
python3 --version python3 --version
git --version git --version
if ! getent group node >/dev/null 2>&1; then case "$runtime_uid" in
groupadd --gid 1000 node ""|*[!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 fi
if ! id node >/dev/null 2>&1; then if id "$runtime_user" >/dev/null 2>&1; then
useradd --uid 1000 --gid node --create-home --home-dir /home/node --shell /bin/bash node 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 fi
mkdir -p /data/home /data/config /data/npm-cache /data/pi-web /data/pi-agent /workspace mkdir -p /data/home /data/config /data/npm-cache /data/pi-web /data/pi-agent /workspace "/home/$runtime_user"
chown -R node:node /data /workspace /home/node chown -R "$runtime_uid:$runtime_gid" /data /workspace "/home/$runtime_user"
zypper clean --all zypper clean --all
rm -rf /var/cache/zypp/* 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_MAJOR: ${PI_WEB_NODEJS_MAJOR:-22}
NODEJS_REPO: ${PI_WEB_NODEJS_REPO:-auto} NODEJS_REPO: ${PI_WEB_NODEJS_REPO:-auto}
PI_WEB_EXTRA_ZYPPER_PACKAGES: ${PI_WEB_EXTRA_ZYPPER_PACKAGES:-} 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 x-pi-web-dev-environment: &pi-web-dev-environment
HOME: /data/home 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_MAJOR: ${PI_WEB_NODEJS_MAJOR:-22}
NODEJS_REPO: ${PI_WEB_NODEJS_REPO:-auto} NODEJS_REPO: ${PI_WEB_NODEJS_REPO:-auto}
PI_WEB_EXTRA_ZYPPER_PACKAGES: ${PI_WEB_EXTRA_ZYPPER_PACKAGES:-} 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_WEB_VERSION: ${PI_WEB_VERSION:-latest}
PI_VERSION: ${PI_VERSION:-latest} PI_VERSION: ${PI_VERSION:-latest}
CACHE_BUST: ${CACHE_BUST:-local} 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. # 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. # 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_UID=$pi_web_uid
PI_WEB_GID=$pi_web_gid PI_WEB_GID=$pi_web_gid
DOCKER_GID=$docker_gid DOCKER_GID=$docker_gid