Skip to content

Commit 4cf4f53

Browse files
committed
Add non-root runtime variant to Dockerfile for image scanners
1 parent ba3fd40 commit 4cf4f53

1 file changed

Lines changed: 65 additions & 1 deletion

File tree

Dockerfile

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,75 @@ WORKDIR /src
77
COPY [".", "./"]
88
RUN dotnet build "./src/Service/Azure.DataApiBuilder.Service.csproj" -c Docker -o /out -r linux-x64
99

10-
FROM mcr.microsoft.com/dotnet/aspnet:8.0-cbl-mariner2.0 AS runtime
10+
# ---------------------------------------------------------------------------
11+
# Common runtime base.
12+
#
13+
# Not intended as a final build target. Both the `runtime` (root, default)
14+
# and `runtime-nonroot` (non-root, scanner-friendly) variants derive from
15+
# this stage so the shared setup stays in one place.
16+
# ---------------------------------------------------------------------------
17+
FROM mcr.microsoft.com/dotnet/aspnet:8.0-cbl-mariner2.0 AS runtime-base
1118

1219
COPY --from=build /out /App
1320
# Add default dab-config.json to /App in the image
1421
COPY dab-config.json /App/dab-config.json
1522
WORKDIR /App
1623
ENV ASPNETCORE_URLS=http://+:5000
24+
EXPOSE 5000
1725
ENTRYPOINT ["dotnet", "Azure.DataApiBuilder.Service.dll"]
26+
27+
# ---------------------------------------------------------------------------
28+
# Non-root variant. Build explicitly with:
29+
# docker build --target runtime-nonroot -t <repo>:<version>-nonroot .
30+
#
31+
# Runs as the "app" user that ships with the mcr.microsoft.com/dotnet/aspnet
32+
# base image (UID/GID 1654 on the cbl-mariner variant; 64198 on the
33+
# Debian/chiseled variants). DAB does not require root, and declaring USER
34+
# explicitly sets the image's Config.User field so image scanners
35+
# (e.g. Checkmarx One) that require a non-root user in the final stage are
36+
# satisfied.
37+
#
38+
# Safeguards applied to minimize the chance of runtime breakage:
39+
# * `chown -R app:app /App` so any feature that writes to a relative path
40+
# under WORKDIR works (e.g. runtime.telemetry.file with the default path
41+
# "logs/dab-log.txt", or any future relative-path artifact). File modes
42+
# are unchanged - only ownership.
43+
# * Pre-create /App/logs so the documented default file-sink path works
44+
# with no additional volume/permission setup.
45+
# * Default port stays at 5000, which is above 1024, so binding works
46+
# without CAP_NET_BIND_SERVICE. Users overriding ASPNETCORE_URLS to a
47+
# privileged port (<1024) must add `--cap-add=NET_BIND_SERVICE` to
48+
# `docker run` or front DAB with a reverse proxy.
49+
#
50+
# Notes for consumers of this image:
51+
# * Host bind-mounts (config, logs, certs, etc.) must be readable - and
52+
# writable, if DAB needs to write them - by UID 1654 on the host.
53+
# Either `chown -R 1654:1654 /host/path` or, in Kubernetes, set
54+
# `securityContext.fsGroup: 1654`.
55+
# * `docker exec` defaults to the `app` user. Use `docker exec --user 0`
56+
# for administrative actions inside a running container.
57+
# * Downstream Dockerfiles (FROM <this image>) that need to install
58+
# packages or write outside /App should add `USER 0` before those
59+
# instructions, then restore `USER app` at the end.
60+
# ---------------------------------------------------------------------------
61+
FROM runtime-base AS runtime-nonroot
62+
63+
RUN mkdir -p /App/logs && chown -R app:app /App
64+
USER app
65+
66+
LABEL org.opencontainers.image.title="Data API builder (non-root)" \
67+
org.opencontainers.image.description="Data API builder running as the non-root 'app' user (UID 1654 on cbl-mariner)." \
68+
org.opencontainers.image.source="https://github.com/Azure/data-api-builder"
69+
70+
# ---------------------------------------------------------------------------
71+
# Default (root-running) variant. Build with either:
72+
# docker build -t <repo>:<version> . # no --target needed
73+
# docker build --target runtime -t <repo>:<version> .
74+
#
75+
# This is the LAST stage in the file, so a plain `docker build` with no
76+
# --target argument produces this image. Keeping the root-running variant
77+
# as the default preserves backwards compatibility with the previously
78+
# published image - existing users see no behavior change. The non-root
79+
# variant is opt-in via `--target runtime-nonroot`.
80+
# ---------------------------------------------------------------------------
81+
FROM runtime-base AS runtime

0 commit comments

Comments
 (0)