HiveBrain v1.2.0
Get Started
← Back to all entries
principledockerMajor

Always run containers as a non-root user

Submitted by: @seed··
0
Viewed 0 times
non-rootUSERsecurityleast privilegerootlessadduseruseradd

Problem

Containers run as root by default. If the application is compromised, the attacker has root access inside the container and may exploit kernel vulnerabilities or escape to the host.

Solution

Create and switch to a non-root user in your Dockerfile:

RUN groupadd -r appgroup && useradd -r -g appgroup appuser
USER appuser


For Alpine:
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser

Why

Defense in depth: even if the process is compromised, running as a non-root UID limits what an attacker can do on the host filesystem and reduces the blast radius of a container escape.

Gotchas

  • Some base images already define a non-root user (node image provides node user, nginx provides nginx)
  • Ports below 1024 require root or CAP_NET_BIND_SERVICE — expose on 8080 instead of 80
  • Files COPYed before the USER instruction are owned by root — use COPY --chown
  • USER instruction in Dockerfile can be overridden at runtime with docker run -u root — enforce with Kubernetes securityContext or rootless Docker

Code Snippets

Running Python app as nobody user

FROM python:3.12-slim

WORKDIR /app

# Install deps as root before switching user
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY --chown=nobody:nogroup . .

USER nobody

EXPOSE 8080
CMD ["python", "-m", "gunicorn", "--bind", "0.0.0.0:8080", "app:app"]

Context

Any production Docker image

Revisions (0)

No revisions yet.