USER Instruction - set user based on build ARG #5748
Replies: 3 comments 2 replies
-
You can create an "if/else" or "switch"-like construct by using named intermediate stages, then basing your follow-up staged on those, but selecting "which one to use" based on a build-arg. For example, the following dockerfile bases the "final" staged on either # syntax=docker/dockerfile:1
# Important; this ARG must be defined before the first `FROM` in the dockerfile
# because it's used in `FROM` lines below, which requires it to be defined in
# the "global" scope.
ARG NODE_ENV=development
FROM alpine AS mybase
FROM mybase AS base-development
FROM mybase AS base-production
RUN addgroup -S app_group && adduser -S app_user -G app_group
USER app_user:app_group
# final is the final stage, which is based on either "base-development"
# or "base-production, depending on the value of NODE_ENV
FROM base-${NODE_ENV} AS final |
Beta Was this translation helpful? Give feedback.
-
# A multi-stage image build to create a final image without uv.
ARG NODE_ENV="development"
# First, build the application in the `/app` directory.
# See `Dockerfile` for details.
FROM ghcr.io/astral-sh/uv:python3.13-alpine AS builder
ENV UV_COMPILE_BYTECODE=1 UV_LINK_MODE=copy
# Disable Python downloads, because we want to use the system interpreter
# across both images. If using a managed Python version, it needs to be
# copied from the build image into the final image; see `standalone.Dockerfile`
# for an example.
ENV UV_PYTHON_DOWNLOADS=0
WORKDIR /app
RUN --mount=type=cache,target=/root/.cache/uv \
--mount=type=bind,source=uv.lock,target=uv.lock \
--mount=type=bind,source=pyproject.toml,target=pyproject.toml \
uv sync --frozen --no-install-project --no-dev
ADD . /app
RUN --mount=type=cache,target=/root/.cache/uv \
uv sync --frozen --no-dev
# Then, use a final image without uv
FROM python:3.13-alpine as base
# It is important to use the image that matches the builder, as the path to the
# Python executable must be the same, e.g., using `python:3.11-slim-bookworm`
# will fail.
FROM base AS base-development
FROM base AS base-production
RUN addgroup -S app_group && adduser -S app_user -G app_group
USER app_user:app_group
FROM base-${NODE_ENV} AS final
# Copy the application from the builder
COPY --from=builder --chown=app_user:app_group /app /app
# Place executables in the environment at the front of the path
ENV PATH="/app/.venv/bin:$PATH"
# Run the FastAPI application by default
CMD ["fastapi", "run", "--host", "0.0.0.0", "/app/src/api"] Did this, but now the problem is I also need to run CMD based on my environment: What's the best way to do this? |
Beta Was this translation helpful? Give feedback.
-
OK, I think I finally got it right. # A multi-stage image build to create a final image without uv.
ARG NODE_ENV="development"
# First, build the application in the `/app` directory.
# See `Dockerfile` for details.
FROM ghcr.io/astral-sh/uv:python3.13-alpine AS builder
ENV UV_COMPILE_BYTECODE=1 UV_LINK_MODE=copy
# Disable Python downloads, because we want to use the system interpreter
# across both images. If using a managed Python version, it needs to be
# copied from the build image into the final image; see `standalone.Dockerfile`
# for an example.
ENV UV_PYTHON_DOWNLOADS=0
WORKDIR /app
RUN --mount=type=cache,target=/root/.cache/uv \
--mount=type=bind,source=uv.lock,target=uv.lock \
--mount=type=bind,source=pyproject.toml,target=pyproject.toml \
uv sync --frozen --no-install-project --no-dev
ADD . /app
RUN --mount=type=cache,target=/root/.cache/uv \
uv sync --frozen --no-dev
# Then, use a final image without uv
FROM python:3.13-alpine as base
# It is important to use the image that matches the builder, as the path to the
# Python executable must be the same, e.g., using `python:3.11-slim-bookworm`
# will fail.
FROM base AS base-development
COPY --from=builder /app /app
CMD ["fastapi", "dev", "--host", "0.0.0.0", "/app/src/api"]
FROM base AS base-production
RUN addgroup -S app_group && adduser -S app_user -G app_group
USER app_user:app_group
COPY --from=builder --chown=app_user:app_group /app /app
CMD ["fastapi", "run", "--host", "0.0.0.0", "/app/src/api"]
FROM base-${NODE_ENV} AS final
# Place executables in the environment at the front of the path
ENV PATH="/app/.venv/bin:$PATH" |
Beta Was this translation helpful? Give feedback.
-
I'm trying to set the USER inside my Dockerfile based on my environment.
Is this possible?
Something like this:
Beta Was this translation helpful? Give feedback.
All reactions