Run a container as a non-root user
container security hardening.
create a dedicated group and user, chown app files to them, then USER to drop privileges before the process runs.
WHAT THIS TESTS It checks whether you treat least privilege as default and know the concrete Dockerfile mechanics, not just the slogan.
A GOOD ANSWER COVERS The steps: create a dedicated group and user, for example RUN groupadd -r app && useradd -r -g app app (or addgroup/adduser on Alpine). Ensure the application directory is owned by that user, either with COPY --chown=app:app . /app or a RUN chown -R. Then switch context with USER app placed before CMD or ENTRYPOINT so the main process runs unprivileged. Bind to a non-privileged port (above 1024) since a non-root user cannot bind low ports. Why it matters: by default a container runs as root, and that root is often the same UID as host root; combined with a kernel or runtime vulnerability, a compromised root process is far more dangerous. Dropping to a non-root user shrinks the blast radius of any escape or exploit.
COMMON WRONG ANSWERS Leaving the default root user in production. Adding USER but not chowning files, so the process cannot read or write its own directory. Trying to bind port 80 as non-root and failing. Assuming USER alone fully sandboxes the container.
LIKELY FOLLOW-UPS How does this interact with volume mount ownership? What about read-only root filesystem and dropping Linux capabilities? Why bind to a high port?
ONE CONCRETE EXAMPLE A Node image: RUN addgroup -S app && adduser -S app -G app, COPY --chown=app:app . /app, then USER app, then CMD ["node", "server.js"] listening on 3000. If an attacker achieves RCE, they land as the unprivileged app user, unable to install packages, edit system files, or trivially escalate.
Read the original → docker.com
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.