-
Notifications
You must be signed in to change notification settings - Fork 348
Add non-root variant to Dockerfile for dual image publishing #3520
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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 | ||
| # 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`. | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Was the requirement for this PR approved by any PM in any of our scrum syncs? |
||
| # --------------------------------------------------------------------------- | ||
| FROM runtime-base AS runtime | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Followup separate PR in internal repo would need changes to both the pipeline yml as well as the docker file used in one branch. The Dockerfile that is changed here is only shown as a sample for building the image by customers
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If the FROM statement as runtime, is the last in the Dockerfile, would the ENTRYPOINT mentioned on line 25 still stay the same? Did you actually test this to build and start dab in the container? |
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment here is contradictory to the description in the PR which says that we are doing:
chown -R app:app /Apprecursive.However, not doing recursive seems the right thing to do. The PR description should be fixed.