Skip to content

fix(docker): run the test image as a non-root user - #172

Merged
rennf93 merged 2 commits into
masterfrom
fix/docksec-dockerfile
Oct 21, 2026
Merged

rennf93 merged 2 commits into
masterfrom
fix/docksec-dockerfile

Conversation

@rennf93

@rennf93 rennf93 commented Oct 21, 2026 •

Copy link
Copy Markdown
Member

The Dockerfiles that DockSec flags are fixed: the root one, the ones under examples/ and, in fastapi-guard, the live-smoke one. None installs apt packages any more, uv comes from the official image at an exact tag, every image runs as a numeric non-root USER and has a HEALTHCHECK. docksec.yml now also watches **/Dockerfile, because DockSec runs trivy config over the whole tree and keeps every file named Dockerfile (findings.py:182-185), so a change to a nested file has to trigger the scan.

Closes all open DockSec alerts (rule ids, alert numbers): DS002 (#2, #3, #4), DS026 (#10, #11, #12, #13), DS029 (#5, #6), DL3008 (#7), DL3013 (#8), DL3042 (#9), DL3009 (#14).

Root Dockerfile:

  1. The apt block (libsodium23, wget, build-essential, libffi-dev, curl) is gone. I built the image and ran the suite without it and nothing needed it, so there is nothing to pin.
  2. pip install uv became COPY --from=ghcr.io/astral-sh/uv:0.13.4 /uv /uvx /bin/, and I dropped PIP_NO_CACHE_DIR=false, which only configured that pip call.
  3. User app (uid 10001) owns /app, USER 10001 comes before uv sync so the venv and /app/data are writable.
  4. HEALTHCHECK probes http://127.0.0.1:8000/ with python and counts any HTTP answer as alive. The one-shot test runner would report a meaningless unhealthy state, so compose.yml sets healthcheck: disable: true on the test service.

Nested Dockerfiles:

  • examples/simple_app/Dockerfile: apt block dropped, user app (uid 10001), USER 10001, HEALTHCHECK. Run through its own docker-compose.yml: healthy, GET / 200 from the host and from inside the container, uid=10001.
  • examples/advanced_app/Dockerfile: numeric uid 10001 for the existing guard user, USER 10001, HEALTHCHECK on /health. I built it the way container-release.yml does (docker compose build in examples/advanced_app) and ran the stack with nginx on a high host port: app healthy, uid=10001, GET /health through nginx 200. I also ran it with the compose healthcheck reset so the Dockerfile HEALTHCHECK is the one reporting: healthy.
  • tests/live_smoke/stack/Dockerfile: user app (uid 10001), USER 10001, HEALTHCHECK on /health. I ran the whole live-smoke.yml sequence locally (wheel build, copy_example_app.py, patch_example_config.py, docker compose up --build --wait, then pytest tests/live_smoke -m live_smoke with Redis on 16379): stack healthy, 101 passed in 371.88s.
  • live-smoke.yml gets a chmod a+rwx tests/live_smoke/stack/scenario_data step: the container now writes /smoke as uid 10001 and the checkout on the runner belongs to another uid. The live-smoke check on this PR runs it on Linux.

Verification (python 3.10, own compose projects, Redis without a host port, one run at a time):

  • Test service, master image vs this branch: 446 passed, 41 failed on both, identical list of failing tests. The failures exist on master (the ones I looked at connect to localhost:6379 inside the test container, tests/conftest.py:32). I did not touch that.
  • Example service on this branch: healthy, GET / 200, uid=10001(app). The compose.yml service command works for this repo.
  • hadolint 2.15.1 (the version the pinned DockSec action installs) on master, root Dockerfile: DL3008, DL3009, DL3015, DL3013, DL3042. On this branch, every Dockerfile in the repo: no output, exit 0.
  • trivy 0.74.0 (the version the pinned action installs) config --file-patterns dockerfile:Dockerfile over the repo: 27 successes, 0 failures for every Dockerfile.
  • DockSec check on this PR: pass. Analysis on refs/pull/172/merge: results_count 0 and 0 open alerts on that ref.

Not verified: python versions other than 3.10, and the bind-mounted examples (./:/app) on a Linux host, where a host-owned directory is not writable by uid 10001.

@rennf93 rennf93 added the no-issue Chore or dependency PR that does not need an issue label Oct 21, 2026
Comment thread Dockerfile Fixed
@github-actions github-actions Bot added the build Makefile / Docker / setup.py / packaging label Oct 21, 2026
@rennf93 rennf93 self-assigned this Oct 21, 2026
@github-actions github-actions Bot added tests Test suite changes examples examples/ apps and example tests ci GitHub Actions and pre-commit labels Oct 21, 2026
@rennf93
rennf93 merged commit afdcd56 into master Oct 21, 2026
16 checks passed
@rennf93
rennf93 deleted the fix/docksec-dockerfile branch October 21, 2026 02:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

build Makefile / Docker / setup.py / packaging ci GitHub Actions and pre-commit examples examples/ apps and example tests no-issue Chore or dependency PR that does not need an issue tests Test suite changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants