Skip to content

Run nginx as non-root user (switch to nginx-unprivileged base image) #68

Description

@il10241024

🔗 Mirrored from cyberfabric/cyber-insight-front#36
Originally opened by dzarlax on 2026-04-27T10:40:03Z


Context

PR #120 (security hardening) added an explicit `ENTRYPOINT` / `CMD` to the Dockerfile. Codacy/Semgrep then flagged a pre-existing condition that wasn't visible before:

`Dockerfile:83-84` — By not specifying a USER, a program in the container may run as 'root'. This is a security hazard. (`Semgrep_dockerfile.security.missing-user`)

The `nginx:1.27-alpine` base image runs the nginx master as root so it can bind privileged port 80; workers are spawned as the `nginx` user. This is the standard nginx posture but does not satisfy a strict "non-root container" policy and is a real risk: any RCE in nginx master = root in the container.

Proposed fix

Switch to `nginxinc/nginx-unprivileged:1.27-alpine` — the official non-root nginx image maintained by Nginx Inc. It:

  • Runs as user `nginx` (uid 101) end-to-end, no root.
  • Listens on port 8080 by default instead of 80.
  • Drop-in compatible with our config except for the port.

Why this is a follow-up and not part of #120

The port change (80 → 8080) ripples into deployment:

  • `EXPOSE 8080` in the Dockerfile (trivial)
  • Helm chart's `service.yaml` `targetPort` and any `containerPort` references
  • Possibly k8s ingress / docker-compose configs in customer-facing docs
  • Health-check probes (`/healthz` URL is fine, but the port number changes)

We don't want to land that without coordinating with whoever owns the deployment chart / customer docs / CI integration tests.

Acceptance criteria

  • Dockerfile uses `nginxinc/nginx-unprivileged:1.27-alpine` base
  • `listen 8080` in nginx config (or whatever port the unprivileged image expects)
  • `EXPOSE 8080`
  • Helm chart updated (`service.yaml` / values, if applicable)
  • Codacy passes — `missing-user` findings on Dockerfile resolve
  • `docker run` smoke test on a clean machine: container starts, healthz responds, security headers present, OIDC config injected
  • PR description documents the deployment-side changes downstream consumers must apply

Related


Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions