e117a33a73
- 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>
43 lines
2.3 KiB
Markdown
43 lines
2.3 KiB
Markdown
# 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 80` → `listen 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
|