Skip to main content

How to build and run rootless containers

Rootless containers reduce risk by running the app as a non-root user and the engine without root via user namespaces. Add a non-root user, fix ownership, force a UID, and enforce runAsNonRoot in Kubernetes.

Difficulty
Intermediate
Duration
35 minutes
Steps
6

Building and running rootless containers

Many containers run as root by default, so a container escape can mean host root. Rootless containers reduce this risk in two ways: building images that run as a non-root user, and running the container engine itself without root using user namespaces (Docker rootless mode or Podman).

Prerequisites

  • A Linux host with user-namespace support.
  • Docker or Podman installed.

Steps

1. Understand rootless containers

There are two layers: the process inside the container (the app user) and the daemon running containers (the engine). Hardening both gives the strongest posture.

2. Add a non-root user in the image

FROM alpine:3.20
RUN adduser -D -u 10001 appuser
WORKDIR /app
COPY --chown=appuser:appuser . .
USER appuser
ENTRYPOINT ["/app/server"]

3. Fix file ownership and permissions

Ensure directories the app writes to are owned by the non-root user. Avoid binding to ports below 1024, which require extra privilege; use port 8080 instead of 80.

4. Run with a non-root UID

Even without USER in the image, you can force a UID:

docker run --user 10001:10001 myapp

5. Set up rootless mode

With Podman, commands run rootless by default. With Docker, use the rootless installation so the daemon runs as your user inside a user namespace, mapping container root to an unprivileged host UID.

6. Enforce non-root in Kubernetes

securityContext:
  runAsNonRoot: true
  runAsUser: 10001
  allowPrivilegeEscalation: false

Kubernetes refuses to start the pod if the image would run as root.

Verification

Run the container and check the user: docker run --rm myapp id should show a non-zero UID. With rootless Docker or Podman, docker info or podman info reports rootless mode. In Kubernetes, a pod with runAsNonRoot: true should fail if the image runs as root.

Next Steps

Combine non-root execution with a read-only root filesystem, dropped capabilities, and a seccomp profile. Enforce these defaults cluster-wide with Pod Security Standards or a policy engine.

Prerequisites

  • A Linux host
  • Docker or Podman installed
  • A Dockerfile to adjust

Steps

  • 1
    Understand rootless containers
  • 2
    Add a non-root user in the image
  • 3
    Fix file ownership and permissions
  • 4
    Run with a non-root UID
  • 5
    Set up rootless mode
  • 6
    Enforce non-root in Kubernetes

Category

Containers