Files
Business-Management/changelog/2026-04-13_rootless-containers.md
curo1305 e117a33a73 Align all app containers to UID 1001, add infra protocol, update README
- frontend prod: USER root for adduser, then USER appuser (1001:1001); fixes
  build failure caused by nginx-unprivileged already setting USER nginx
- docker-compose: frontend user updated to 1001:1001 (was 101:101)
- CLAUDE.md: add infrastructure change protocol (update README + test both
  stacks after any Dockerfile/compose/nginx change); fix stale passlib ref
- README: container table shows nginx-unprivileged image, UID column, internal
  port 8080 note; Current State notes all containers run as non-root

Both dev and prod stacks tested and verified (health, login, /users/me,
frontend serving, all containers confirmed non-root via docker inspect).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 17:29:02 +02:00

2.3 KiB

2026-04-13 — Rootless containers

Timestamp: 2026-04-13T00:00:00

Summary

All containers now run as non-root users with explicit UID:GID assignments enforced in both Dockerfiles and docker-compose files.

User mapping

Service User UID:GID Notes
db postgres 70:70 Fixed by postgres:16-alpine; image owns PGDATA as 70:70 so named-volume seeding works
backend appuser 1001:1001 Created via useradd in runtime stage
frontend (prod) nginx 101:101 Switched to nginxinc/nginx-unprivileged:alpine; listens on 8080
frontend (dev) appuser 1001:1001 Created via adduser in builder stage

2026-04-13 — Frontend prod UID 1001, infra change protocol, README update

Timestamp: 2026-04-13T01:00:00

Summary

Aligned frontend prod container to UID 1001 (same as all other app containers), added infrastructure change protocol to CLAUDE.md, updated README with container table and rootless note. Both dev and prod stacks verified working.

Files Modified (this entry)

  • frontend/Dockerfile — prod stage: added USER root + addgroup/adduser for appuser 1001:1001, USER appuser; removed stale 101 reference
  • docker-compose.yml — frontend user: updated from "101:101" to "1001:1001"
  • CLAUDE.md — added Infrastructure change protocol section; fixed stale passlib reference in stack table
  • README.md — updated container table with nginxinc/nginx-unprivileged:alpine, UID columns, internal port note; added rootless note to Current State

Files Modified (previous entry)

  • backend/Dockerfile — added groupadd/useradd for appuser (1001:1001), --chown on all COPY directives, USER appuser
  • frontend/Dockerfile — builder stage: added addgroup/adduser for appuser (1001:1001), USER appuser; prod stage: switched to nginxinc/nginx-unprivileged:alpine, EXPOSE 8080
  • frontend/nginx.conf — changed listen 80listen 8080 to match unprivileged image default
  • docker-compose.yml — added user: "70:70" to db, user: "1001:1001" to backend, user: "101:101" to frontend; updated frontend port mapping to "80:8080"
  • docker-compose.dev.yml — added user: "1001:1001" to backend and frontend overrides
  • TODO.md — marked rootless containers item as completed