Problem
All three containers (sync-api, sync-worker, sync-web) run as root by default. This violates Docker security best practices and increases blast radius if a container is compromised.
Affected Dockerfiles
| Service |
Dockerfile |
| sync-api |
sync-api/Dockerfile |
| sync-worker |
sync-worker/Dockerfile |
| sync-web |
sync-web/Dockerfile (runner stage) |
Fix
Add a non-root user to each image. For Python images:
RUN groupadd --system app && useradd --system --gid app app
USER app
For the Alpine-based sync-web runner:
RUN addgroup --system app && adduser --system --ingroup app app
USER app
Notes
- Ensure the
WORKDIR and any mounted volumes are chown'd to the new user before the USER directive.
- The
sync-worker writes to /app/data — that directory needs to be created and owned by the new user.
- Test health checks and entrypoints still work under the non-root user.
Problem
All three containers (
sync-api,sync-worker,sync-web) run asrootby default. This violates Docker security best practices and increases blast radius if a container is compromised.Affected Dockerfiles
sync-api/Dockerfilesync-worker/Dockerfilesync-web/Dockerfile(runner stage)Fix
Add a non-root user to each image. For Python images:
For the Alpine-based
sync-webrunner:Notes
WORKDIRand any mounted volumes are chown'd to the new user before theUSERdirective.sync-workerwrites to/app/data— that directory needs to be created and owned by the new user.