Skip to content

Commit

Permalink
Add non-root user support (dotnet#4397)
Browse files Browse the repository at this point in the history
(cherry picked from commit 4fced56)
  • Loading branch information
lbussell authored and mthalman committed Feb 16, 2023
1 parent 3fdda82 commit b9bf553
Show file tree
Hide file tree
Showing 59 changed files with 690 additions and 147 deletions.
12 changes: 6 additions & 6 deletions README.runtime-deps.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ Tags | Dockerfile | OS Version
Tags | Dockerfile | OS Version
-----------| -------------| -------------
8.0.0-preview.1-bookworm-slim-amd64, 8.0-preview-bookworm-slim-amd64, 8.0.0-preview.1, 8.0.0-preview.1-bookworm-slim, 8.0-preview, 8.0-preview-bookworm-slim | [Dockerfile](https://github.com/dotnet/dotnet-docker/blob/main/src/runtime-deps/8.0/bookworm-slim/amd64/Dockerfile) | Debian 12
8.0.0-preview.1-alpine3.17-amd64, 8.0-preview-alpine3.17-amd64, 8.0-preview-alpine-amd64, 8.0.0-preview.1-alpine3.17, 8.0-preview-alpine3.17, 8.0-preview-alpine | [Dockerfile](https://github.com/dotnet/dotnet-docker/blob/main/src/runtime-deps/6.0/alpine3.17/amd64/Dockerfile) | Alpine 3.17
8.0.0-preview.1-jammy-amd64, 8.0-preview-jammy-amd64, 8.0.0-preview.1-jammy, 8.0-preview-jammy | [Dockerfile](https://github.com/dotnet/dotnet-docker/blob/main/src/runtime-deps/6.0/jammy/amd64/Dockerfile) | Ubuntu 22.04
8.0.0-preview.1-alpine3.17-amd64, 8.0-preview-alpine3.17-amd64, 8.0-preview-alpine-amd64, 8.0.0-preview.1-alpine3.17, 8.0-preview-alpine3.17, 8.0-preview-alpine | [Dockerfile](https://github.com/dotnet/dotnet-docker/blob/main/src/runtime-deps/8.0/alpine3.17/amd64/Dockerfile) | Alpine 3.17
8.0.0-preview.1-jammy-amd64, 8.0-preview-jammy-amd64, 8.0.0-preview.1-jammy, 8.0-preview-jammy | [Dockerfile](https://github.com/dotnet/dotnet-docker/blob/main/src/runtime-deps/8.0/jammy/amd64/Dockerfile) | Ubuntu 22.04
8.0.0-preview.1-jammy-chiseled-amd64, 8.0-preview-jammy-chiseled-amd64, 8.0.0-preview.1-jammy-chiseled, 8.0-preview-jammy-chiseled | [Dockerfile](https://github.com/dotnet/dotnet-docker/blob/main/src/runtime-deps/8.0/jammy-chiseled/amd64/Dockerfile) | Ubuntu 22.04

## Linux arm64 Tags
Expand All @@ -74,8 +74,8 @@ Tags | Dockerfile | OS Version
Tags | Dockerfile | OS Version
-----------| -------------| -------------
8.0.0-preview.1-bookworm-slim-arm64v8, 8.0-preview-bookworm-slim-arm64v8, 8.0.0-preview.1, 8.0.0-preview.1-bookworm-slim, 8.0-preview, 8.0-preview-bookworm-slim | [Dockerfile](https://github.com/dotnet/dotnet-docker/blob/main/src/runtime-deps/8.0/bookworm-slim/arm64v8/Dockerfile) | Debian 12
8.0.0-preview.1-alpine3.17-arm64v8, 8.0-preview-alpine3.17-arm64v8, 8.0-preview-alpine-arm64v8, 8.0.0-preview.1-alpine3.17, 8.0-preview-alpine3.17, 8.0-preview-alpine | [Dockerfile](https://github.com/dotnet/dotnet-docker/blob/main/src/runtime-deps/6.0/alpine3.17/arm64v8/Dockerfile) | Alpine 3.17
8.0.0-preview.1-jammy-arm64v8, 8.0-preview-jammy-arm64v8, 8.0.0-preview.1-jammy, 8.0-preview-jammy | [Dockerfile](https://github.com/dotnet/dotnet-docker/blob/main/src/runtime-deps/6.0/jammy/arm64v8/Dockerfile) | Ubuntu 22.04
8.0.0-preview.1-alpine3.17-arm64v8, 8.0-preview-alpine3.17-arm64v8, 8.0-preview-alpine-arm64v8, 8.0.0-preview.1-alpine3.17, 8.0-preview-alpine3.17, 8.0-preview-alpine | [Dockerfile](https://github.com/dotnet/dotnet-docker/blob/main/src/runtime-deps/8.0/alpine3.17/arm64v8/Dockerfile) | Alpine 3.17
8.0.0-preview.1-jammy-arm64v8, 8.0-preview-jammy-arm64v8, 8.0.0-preview.1-jammy, 8.0-preview-jammy | [Dockerfile](https://github.com/dotnet/dotnet-docker/blob/main/src/runtime-deps/8.0/jammy/arm64v8/Dockerfile) | Ubuntu 22.04
8.0.0-preview.1-jammy-chiseled-arm64v8, 8.0-preview-jammy-chiseled-arm64v8, 8.0.0-preview.1-jammy-chiseled, 8.0-preview-jammy-chiseled | [Dockerfile](https://github.com/dotnet/dotnet-docker/blob/main/src/runtime-deps/8.0/jammy-chiseled/arm64v8/Dockerfile) | Ubuntu 22.04

## Linux arm32 Tags
Expand All @@ -95,8 +95,8 @@ Tags | Dockerfile | OS Version
Tags | Dockerfile | OS Version
-----------| -------------| -------------
8.0.0-preview.1-bookworm-slim-arm32v7, 8.0-preview-bookworm-slim-arm32v7, 8.0.0-preview.1, 8.0.0-preview.1-bookworm-slim, 8.0-preview, 8.0-preview-bookworm-slim | [Dockerfile](https://github.com/dotnet/dotnet-docker/blob/main/src/runtime-deps/8.0/bookworm-slim/arm32v7/Dockerfile) | Debian 12
8.0.0-preview.1-alpine3.17-arm32v7, 8.0-preview-alpine3.17-arm32v7, 8.0-preview-alpine-arm32v7, 8.0.0-preview.1-alpine3.17, 8.0-preview-alpine3.17, 8.0-preview-alpine | [Dockerfile](https://github.com/dotnet/dotnet-docker/blob/main/src/runtime-deps/6.0/alpine3.17/arm32v7/Dockerfile) | Alpine 3.17
8.0.0-preview.1-jammy-arm32v7, 8.0-preview-jammy-arm32v7, 8.0.0-preview.1-jammy, 8.0-preview-jammy | [Dockerfile](https://github.com/dotnet/dotnet-docker/blob/main/src/runtime-deps/6.0/jammy/arm32v7/Dockerfile) | Ubuntu 22.04
8.0.0-preview.1-alpine3.17-arm32v7, 8.0-preview-alpine3.17-arm32v7, 8.0-preview-alpine-arm32v7, 8.0.0-preview.1-alpine3.17, 8.0-preview-alpine3.17, 8.0-preview-alpine | [Dockerfile](https://github.com/dotnet/dotnet-docker/blob/main/src/runtime-deps/8.0/alpine3.17/arm32v7/Dockerfile) | Alpine 3.17
8.0.0-preview.1-jammy-arm32v7, 8.0-preview-jammy-arm32v7, 8.0.0-preview.1-jammy, 8.0-preview-jammy | [Dockerfile](https://github.com/dotnet/dotnet-docker/blob/main/src/runtime-deps/8.0/jammy/arm32v7/Dockerfile) | Ubuntu 22.04

You can retrieve a list of all available tags for dotnet/runtime-deps at https://mcr.microsoft.com/v2/dotnet/runtime-deps/tags/list.
<!--End of generated tags-->
Expand Down
4 changes: 2 additions & 2 deletions eng/dockerfile-templates/Dockerfile.common-dotnet-envs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
set isMariner to find(OS_VERSION, "cbl-mariner") >= 0 ^
set isDistroless to find(OS_VERSION, "distroless") >= 0 || find(OS_VERSION, "chiseled") >= 0 ^
set lineContinuation to when(isWindows, "`", "\") ^
set port to when(isDistroless, "8080", "80")
set port to when(isDistroless || (dotnetVersion != "6.0" && dotnetVersion != "7.0"), "8080", "80")
}}ENV {{lineContinuation}}
# Configure web servers to bind to port {{port}} when present
ASPNETCORE_URLS=http://+:{{port}} {{lineContinuation}}
{{if dotnetVersion = "6.0" || dotnetVersion = "7.0":ASPNETCORE_URLS=http://+:{{port}}^else:ASPNETCORE_HTTP_PORTS={{port}}}} {{lineContinuation}}
{{InsertTemplate("Dockerfile.env.container")}}{{if isAlpine || (isDistroless && !(isMariner && find(OS_VERSION, "1.0") > 0)): {{lineContinuation}}
# Set the invariant mode since ICU package isn't included (see https://github.com/dotnet/announcements/issues/20)
DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=true}}
22 changes: 11 additions & 11 deletions eng/dockerfile-templates/Dockerfile.linux.install-deps
Original file line number Diff line number Diff line change
Expand Up @@ -45,17 +45,17 @@
"libstdc++6",
"zlib1g"
])) ^
set certsPkgPrefix to when(isMariner,
[
when(isDistrolessMariner, "prebuilt-ca-certificates", "ca-certificates"),
"",
dotnetDepsComment
],
[
"ca-certificates",
"",
dotnetDepsComment
]) ^
set certsPkgPrefix to when(isMariner,
[
when(isDistrolessMariner, "prebuilt-ca-certificates", "ca-certificates"),
"",
dotnetDepsComment
],
[
"ca-certificates",
"",
dotnetDepsComment
]) ^
set pkgs to when(ARGS["isSdk"], pkgs, cat(certsPkgPrefix, pkgs))
}}{{InsertTemplate("Dockerfile.linux.install-pkgs",
[
Expand Down
7 changes: 4 additions & 3 deletions eng/dockerfile-templates/Dockerfile.linux.install-pkgs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
pkgs: list of packages to install
pkg-mgr (optional): package manager to use
pkg-mgr-opts (optional): additional options to pass to the package manager
noninteractive (optional): whether to use noninteractive mode ^
noninteractive (optional): whether to use noninteractive mode
no-clean (optional): skip package manager cleanup after install ^

set isAlpine to find(OS_VERSION, "alpine") >= 0 ^
set isMariner to find(OS_VERSION, "cbl-mariner") >= 0 ^
Expand All @@ -22,10 +23,10 @@ elif isTdnf:tdnf install -y{{ARGS["pkg-mgr-opts"]}} \^
else:apt-get update \
&&{{if ARGS["noninteractive"]: DEBIAN_FRONTEND=noninteractive}} apt-get install -y --no-install-recommends{{ARGS["pkg-mgr-opts"]}} \}}{{
for index, pkg in ARGS["pkgs"]:
{{pkg}}{{if appendPkgSuffix(pkg, index):{{if pkg != "": }}\}}}}{{
{{pkg}}{{if appendPkgSuffix(pkg, index):{{if pkg != "": }}\}}}}{{if !ARGS["no-clean"]:{{
if isTdnf:
&& tdnf clean all{{ARGS["pkg-mgr-opts"]}}^
elif isDnf:
&& dnf clean all{{ARGS["pkg-mgr-opts"]}}^
elif !isApk:
&& rm -rf /var/lib/apt/lists/*}}
&& rm -rf /var/lib/apt/lists/*}}}}
29 changes: 29 additions & 0 deletions eng/dockerfile-templates/Dockerfile.linux.remove-pkgs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{{
_ ARGS:
pkgs: list of packages to remove
pkg-mgr (optional): package manager to use
pkg-mgr-opts (optional): additional options to pass to the package manager
noninteractive (optional): whether to use noninteractive mode
no-clean (optional): skip package manager cleanup after install ^

set isAlpine to find(OS_VERSION, "alpine") >= 0 ^
set isMariner to find(OS_VERSION, "cbl-mariner") >= 0 ^
set isDnf to ARGS["pkg-mgr"] = "dnf" ^
set isTdnf to ARGS["pkg-mgr"] = "tdnf" || (!isDnf && isMariner) ^
set isApk to ARGS["pkg-mgr"] = "apk" || isAlpine
}}{{
if isDnf:dnf remove -y{{ARGS["pkg-mgr-opts"]}} \^
elif isApk:apk del{{ARGS["pkg-mgr-opts"]}} \^
elif isTdnf:tdnf remove -y{{ARGS["pkg-mgr-opts"]}} \^
else:apt-get remove \
&&{{if ARGS["noninteractive"]: DEBIAN_FRONTEND=noninteractive}} apt-get remove -y {{ARGS["pkg-mgr-opts"]}} \}}{{
for index, pkg in ARGS["pkgs"]:
{{pkg}} \}}{{if !no-clean:{{
if isTdnf:
&& tdnf clean all{{ARGS["pkg-mgr-opts"]}}^
elif isDnf:
&& dnf autoremove{{ARGS["pkg-mgr-opts"]}} \
&& dnf clean all{{ARGS["pkg-mgr-opts"]}}^
elif !isApk:
&& apt-get autoremove \
&& rm -rf /var/lib/apt/lists/*}}}}
5 changes: 3 additions & 2 deletions eng/dockerfile-templates/monitor/Dockerfile.envs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
_ .NET major version matches the major version of dotnet-monitor ^
set dotnetMajor to split(PRODUCT_VERSION, ".")[0]
}}ENV \
# Unset ASPNETCORE_URLS from aspnet base image
ASPNETCORE_URLS= \
{{if dotnetMajor != "6" && dotnetMajor != "7":# Unset ASPNETCORE_HTTP_PORTS from aspnet base image
ASPNETCORE_HTTP_PORTS= \^else:# Unset ASPNETCORE_URLS from aspnet base image
ASPNETCORE_URLS= \}}
# Disable debugger and profiler diagnostics to avoid diagnosing self.
COMPlus_EnableDiagnostics=0 \
# Default Filter
Expand Down
15 changes: 14 additions & 1 deletion eng/dockerfile-templates/runtime-deps/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@
set isRpmInstall to isMariner && dotnetVersion = "6.0" ^
set isSingleStage to !(isRpmInstall && isInternal) ^
set urlSuffix to when(isInternal, "$SAS_QUERY_STRING", "") ^
set rpmFilename to "dotnet-runtime-deps.rpm"
set rpmFilename to "dotnet-runtime-deps.rpm" ^
set utilPkgs to when(isMariner && dotnetVersion != "6.0" && dotnetVersion != "7.0", ["shadow-utils"], []) ^
set username to "app" ^
set uid to 101 ^
set gid to uid
}}{{
if !isSingleStage:# Installer image
}}FROM {{baseImageRepo}}:{{baseImageTag}}{{if !isSingleStage: AS installer}}{{ if isInternal && isRpmInstall:
Expand Down Expand Up @@ -52,5 +56,14 @@ RUN {{InsertTemplate("../Dockerfile.linux.install-deps")}}
"url-suffix": urlSuffix,
"filename": rpmFilename
])}}
}}{{if dotnetVersion != "6.0" && dotnetVersion != "7.0":
# Create a non-root user and group
RUN {{InsertTemplate("Dockerfile.linux.non-root-user",
[
"name": username,
"uid": uid,
"gid": gid,
"append-cmd": len(utilPkgs) > 0
])}}
}}
{{InsertTemplate("../Dockerfile.common-dotnet-envs")}}
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,15 @@ FROM {{ARCH_VERSIONED}}/ubuntu:{{osVersionBase}} as builder
RUN apt-get update && \
apt-get install -y ca-certificates

RUN {{InsertTemplate("Dockerfile.linux.distroless-user",
[
RUN {{InsertTemplate("Dockerfile.linux.distroless-user", [
"staging-dir": "/rootfs",
"exclusive": "true",
"create-dir": "true",
"name": username,
"uid": uid,
"gid": gid,
"create-home": "true"
],
" ")}}
])}}

COPY --from=chisel /opt/chisel/chisel /usr/bin/
RUN chisel cut --release "ubuntu-{{osVersionNumber}}" --root /rootfs \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,8 @@ RUN {{InsertTemplate("Dockerfile.linux.distroless-user",
"name": username,
"uid": uid,
"gid": gid,
"create-home": createUserHome
],
" ")}}
"no-create-home": !createUserHome
])}}

# Clean up staging
RUN rm -rf {{distrolessStagingDir}}/etc/{{when(find(OS_VERSION, "1.0") >= 0, "dnf", "tdnf")}} \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,24 @@
name: Name of the user/group to create
uid: ID of the user to be created
gid: ID of the group to be created
create-home (optional): Indicates whether a home directory should be created for the user ^
no-create-home (optional): Indicates whether a home directory should be created for the user ^
set dotnetVersion to join(slice(split(PRODUCT_VERSION, "."), 0, 2), ".") ^
set isMariner to find(OS_VERSION, "cbl-mariner") >= 0
}}groupadd \
--system \
--gid={{ARGS["gid"]}} \
{{ARGS["name"]}} \
&& adduser \
--uid {{ARGS["uid"]}} \
--gid {{ARGS["gid"]}} \
--shell /bin/false \{{if !ARGS["create-home"]:
--no-create-home \}}
--system \
{{ARGS["name"]}} \{{
if ARGS["create-home"]:
&& install -d -m 0755 -o {{ARGS["uid"]}} -g {{ARGS["gid"]}} "{{ARGS["staging-dir"]}}/home/{{ARGS["name"]}}" \}}{{
if ARGS["exclusive"]:{{if ARGS["create-dir"]:
&& mkdir -p "{{ARGS["staging-dir"]}}/etc" \}}
&& rootOrAppRegex='@^\(root\|app\):' \
&& cat /etc/passwd | grep $rootOrAppRegex > "{{ARGS["staging-dir"]}}/etc/passwd" \
&& cat /etc/group | grep $rootOrAppRegex > "{{ARGS["staging-dir"]}}/etc/group"^
else:
# Copy user/group info to staging
&& cp /etc/passwd {{ARGS["staging-dir"]}}/etc/passwd \
&& cp /etc/group {{ARGS["staging-dir"]}}/etc/group}}
set isMariner to find(OS_VERSION, "cbl-mariner") >= 0 ^
set isAlpine to find(OS_VERSION, "alpine") >= 0
}}{{InsertTemplate("Dockerfile.linux.non-root-user",
[
"name": ARGS["name"],
"uid": ARGS["uid"],
"gid": ARGS["gid"],
"no-create-home": ARGS["no-create-home"]
])}} \{{if !ARGS["no-create-home"]:
&& install -d -m 0755 -o {{ARGS["uid"]}} -g {{ARGS["gid"]}} "{{ARGS["staging-dir"]}}/home/{{ARGS["name"]}}" \}}{{
if ARGS["exclusive"]:{{if ARGS["create-dir"]:
&& mkdir -p "{{ARGS["staging-dir"]}}/etc" \}}
&& rootOrAppRegex='@^\(root\|app\):' \
&& cat /etc/passwd | grep $rootOrAppRegex > "{{ARGS["staging-dir"]}}/etc/passwd" \
&& cat /etc/group | grep $rootOrAppRegex > "{{ARGS["staging-dir"]}}/etc/group"^
else:
# Copy user/group info to staging
&& cp /etc/passwd {{ARGS["staging-dir"]}}/etc/passwd \
&& cp /etc/group {{ARGS["staging-dir"]}}/etc/group}}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{{
_ Configures a non-root user
_ ARGS:
name: Name of the user/group to create
uid: ID of the user to be created
gid: ID of the group to be created
no-create-home (optional): Indicates whether a home directory should be created for the user ^
set dotnetVersion to join(slice(split(PRODUCT_VERSION, "."), 0, 2), ".") ^
set isAlpine to find(OS_VERSION, "alpine") >= 0 ^
set isDebian to find(OS_ARCH_HYPHENATED, "Debian") >= 0 ^
set isMariner to find(OS_VERSION, "cbl-mariner") >= 0 ^
set isDistrolessMariner to defined(match(OS_VERSION, "^cbl-mariner\d+\.\d+-distroless$")) ^
set utilPkgs to when(isMariner && !isDistrolessMariner && dotnetVersion != "6.0" && dotnetVersion != "7.0", ["shadow-utils"], [])
}}{{if len(utilPkgs) > 0:{{InsertTemplate("../Dockerfile.linux.install-pkgs", [
"pkgs": utilPkgs,
"no-clean": "true"
])}}
&& }}{{if isAlpine:addgroup^else:groupadd}} \
--system \
--gid={{ARGS["gid"]}} \
{{ARGS["name"]}} \
&& {{if isDebian:useradd^else:adduser}} \
--uid {{ARGS["uid"]}} \
{{if isAlpine:--ingroup={{ARGS["name"]}}^else:--gid {{ARGS["gid"]}}}} \
--shell /bin/false \{{if ARGS["no-create-home"]:
--no-create-home \^elif dotnetVersion != "6.0" && dotnetVersion != "7.0" && (isMariner || isDebian):
--create-home \}}
--system \
{{ARGS["name"]}}{{if len(utilPkgs) > 0: \
&& {{InsertTemplate("../Dockerfile.linux.remove-pkgs", [
"pkgs": utilPkgs
], " ")}}}}
4 changes: 2 additions & 2 deletions eng/dockerfile-templates/sdk/Dockerfile.envs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
set isAlpine to find(OS_VERSION, "alpine") >= 0 ^
set isWindows to find(OS_VERSION, "nanoserver") >= 0 || find(OS_VERSION, "windowsservercore") >= 0 ^
set lineContinuation to when(isWindows, "`", "\")
}}ENV {{lineContinuation}}
}}ENV {{lineContinuation}}{{if dotnetVersion = "6.0" || dotnetVersion = "7.0":
# Unset ASPNETCORE_URLS from aspnet base image
ASPNETCORE_URLS= {{lineContinuation}}
ASPNETCORE_URLS= {{lineContinuation}}}}
# Do not generate certificate
DOTNET_GENERATE_ASPNET_CERTIFICATE=false {{lineContinuation}}
# Do not show first run text
Expand Down
1 change: 0 additions & 1 deletion eng/dockerfile-templates/sdk/Dockerfile.linux.first-run
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
{{
_ ARGS
append-cmd: Indicates whether to append the command to an existing command

}}# Trigger first run experience by running arbitrary cmd
{{if ARGS["append-cmd"]:&&^else:RUN}} dotnet help
Loading

0 comments on commit b9bf553

Please sign in to comment.