Skip to content
Open
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 65 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,75 @@ WORKDIR /src
COPY [".", "./"]
RUN dotnet build "./src/Service/Azure.DataApiBuilder.Service.csproj" -c Docker -o /out -r linux-x64

FROM mcr.microsoft.com/dotnet/aspnet:10.0-azurelinux3.0 AS runtime
# ---------------------------------------------------------------------------
# Common runtime base.
#
# Not intended as a final build target. Both the `runtime` (root, default)
# and `runtime-nonroot` (non-root, scanner-friendly) variants derive from
# this stage so the shared setup stays in one place.
# ---------------------------------------------------------------------------
FROM mcr.microsoft.com/dotnet/aspnet:10.0-azurelinux3.0 AS runtime-base

COPY --from=build /out /App
# Add default dab-config.json to /App in the image
COPY --from=build /out/dab-config.json /App/dab-config.json
WORKDIR /App
ENV ASPNETCORE_URLS=http://+:5000
EXPOSE 5000
ENTRYPOINT ["dotnet", "Azure.DataApiBuilder.Service.dll"]

# ---------------------------------------------------------------------------
# Non-root variant. Build explicitly with:
# docker build --target runtime-nonroot -t <repo>:<version>-nonroot .
#
# Runs as the "app" user that ships with the mcr.microsoft.com/dotnet/aspnet
# base image (UID/GID 1654, exposed via the APP_UID env var, on the
# azurelinux3.0 variant). DAB does not require root, and declaring USER
# explicitly sets the image's Config.User field so image scanners
# (e.g. Checkmarx One) that require a non-root user in the final stage are
# satisfied.
#
# Safeguards applied to minimize the chance of runtime breakage:
# * Pre-create /App/logs and `chown app:app /App/logs` (non-recursive) so
# the documented default file-sink path ("logs/dab-log.txt", relative to
# WORKDIR /App) is writable. Ownership of the published assemblies under
# /App is intentionally left unchanged - a recursive chown would
# duplicate every assembly layer and roughly double the image size for
Comment thread
aaronburtle marked this conversation as resolved.
# no runtime benefit, since DAB only needs write access to /App/logs.
# * Default port stays at 5000, which is above 1024, so binding works
# without CAP_NET_BIND_SERVICE. Users overriding ASPNETCORE_URLS to a
# privileged port (<1024) must add `--cap-add=NET_BIND_SERVICE` to
# `docker run` or front DAB with a reverse proxy.
#
# Notes for consumers of this image:
# * Host bind-mounts (config, logs, certs, etc.) must be readable - and
# writable, if DAB needs to write them - by UID 1654 on the host.
# Either `chown -R 1654:1654 /host/path` or, in Kubernetes, set
# `securityContext.fsGroup: 1654`.
# * `docker exec` defaults to the `app` user. Use `docker exec --user 0`
# for administrative actions inside a running container.
# * Downstream Dockerfiles (FROM <this image>) that need to install
# packages or write outside /App should add `USER 0` before those
# instructions, then restore `USER app` at the end.
# ---------------------------------------------------------------------------
FROM runtime-base AS runtime-nonroot

RUN mkdir -p /App/logs && chown app:app /App/logs
USER app

LABEL org.opencontainers.image.title="Data API builder (non-root)" \
org.opencontainers.image.description="Data API builder running as the non-root 'app' user (UID 1654 on azurelinux3.0)." \
org.opencontainers.image.source="https://github.com/Azure/data-api-builder"

# ---------------------------------------------------------------------------
# Default (root-running) variant. Build with either:
# docker build -t <repo>:<version> . # no --target needed
# docker build --target runtime -t <repo>:<version> .
#
# This is the LAST stage in the file, so a plain `docker build` with no
# --target argument produces this image. Keeping the root-running variant
# as the default preserves backwards compatibility with the previously
# published image - existing users see no behavior change. The non-root
# variant is opt-in via `--target runtime-nonroot`.
Comment thread
aaronburtle marked this conversation as resolved.
# ---------------------------------------------------------------------------
FROM runtime-base AS runtime
Comment thread
aaronburtle marked this conversation as resolved.
Comment thread
aaronburtle marked this conversation as resolved.