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.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
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