ENV & USER

Separate configuration from privileges

Lesson 6 of 20 · 12 min · Module 2: Build an image contract

Configuration values and the process identity are independent decisions.

Start this lesson →

Free. No installation: you write and run the code in your browser, and it is checked automatically.

By the end, you’ll be able to…

  • Configure nonsecret behavior
  • Choose a less privileged identity

The idea

Image instructions are an ordered build contract. A later instruction can change a default established earlier; the final stage determines the output image.

FROM node:22-alpine
ENV LOG_LEVEL=info
USER node

01Configure nonsecret behavior

ENV sets defaults available to the process. A port and an environment name are configuration; credentials should not be baked into image layers.

02Choose a less privileged identity

The Node base image supplies a node user. USER selects that identity for subsequent commands and startup instead of leaving the default root account.

03Keep runtime permissions in mind

A nonroot process still needs access to its files and writable directories. USER is a useful boundary, not proof that every other security decision is correct.

Your turn

Use node:22-alpine, /app, ENV NODE_ENV=production and PORT=3000. Run as the existing node user, and start node server.js with an exec-form CMD.

What the checks look for

  • Uses a nonroot identity
  • Sets production and port defaults
  • Keeps the startup command
Try it in the editor →

Take this with you

Use nonsecret configuration defaults and deliberate process privileges.

Go a little further

Investigate COPY --chown=node:node in the official reference.

Learn Docker & Containers for free

20 short lessons with real code and instant checks.

See the whole course →