From 5bd7d2fa4a6af0f3a73e96a4b1498fd356873d05 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Wed, 23 Apr 2025 13:45:09 -0700 Subject: [PATCH] feat: allow images to run as non-root user --- bitwarden_license/src/Scim/.dockerignore | 4 - bitwarden_license/src/Scim/Dockerfile | 72 ++++++++++++++++- bitwarden_license/src/Scim/entrypoint.sh | 51 +++++++----- bitwarden_license/src/Sso/Dockerfile | 72 ++++++++++++++++- bitwarden_license/src/Sso/entrypoint.sh | 55 +++++++------ src/Admin/.dockerignore | 4 - src/Admin/Dockerfile | 99 +++++++++++++++++++++--- src/Admin/entrypoint.sh | 45 ++++++----- src/Api/.dockerignore | 4 - src/Api/Dockerfile | 73 +++++++++++++++-- src/Api/entrypoint.sh | 45 ++++++----- src/Billing/.dockerignore | 4 - src/Billing/Dockerfile | 70 +++++++++++++++-- src/Billing/entrypoint.sh | 36 +++++---- src/Core/Settings/GlobalSettings.cs | 1 + src/Core/Utilities/CoreHelpers.cs | 4 +- src/Events/.dockerignore | 4 - src/Events/Dockerfile | 70 +++++++++++++++-- src/Events/entrypoint.sh | 45 ++++++----- src/EventsProcessor/Dockerfile | 73 +++++++++++++++-- src/EventsProcessor/entrypoint.sh | 34 ++++---- src/Icons/.dockerignore | 4 - src/Icons/Dockerfile | 68 ++++++++++++++-- src/Icons/entrypoint.sh | 44 +++++++---- src/Identity/.dockerignore | 4 - src/Identity/Dockerfile | 68 +++++++++++++++- src/Identity/entrypoint.sh | 55 +++++++------ src/Notifications/.dockerignore | 4 - src/Notifications/Dockerfile | 69 +++++++++++++++-- src/Notifications/entrypoint.sh | 35 +++++---- util/Attachments/Dockerfile | 64 +++++++++++++-- util/Attachments/entrypoint.sh | 34 ++++---- util/MsSql/Dockerfile | 6 +- util/MsSqlMigratorUtility/Dockerfile | 67 +++++++++++++++- util/Nginx/Dockerfile | 21 ++--- util/Server/Dockerfile | 5 -- util/Setup/Dockerfile | 58 +++++++++++++- 37 files changed, 1145 insertions(+), 326 deletions(-) delete mode 100644 bitwarden_license/src/Scim/.dockerignore delete mode 100644 src/Admin/.dockerignore delete mode 100644 src/Api/.dockerignore delete mode 100644 src/Billing/.dockerignore delete mode 100644 src/Events/.dockerignore delete mode 100644 src/Icons/.dockerignore delete mode 100644 src/Identity/.dockerignore delete mode 100644 src/Notifications/.dockerignore delete mode 100644 util/Server/Dockerfile diff --git a/bitwarden_license/src/Scim/.dockerignore b/bitwarden_license/src/Scim/.dockerignore deleted file mode 100644 index fc12f25146..0000000000 --- a/bitwarden_license/src/Scim/.dockerignore +++ /dev/null @@ -1,4 +0,0 @@ -* -!obj/build-output/publish/* -!obj/Docker/empty/ -!entrypoint.sh diff --git a/bitwarden_license/src/Scim/Dockerfile b/bitwarden_license/src/Scim/Dockerfile index 6970dfa7bb..87cfe9cca5 100644 --- a/bitwarden_license/src/Scim/Dockerfile +++ b/bitwarden_license/src/Scim/Dockerfile @@ -1,6 +1,71 @@ +############################################### +# Build stage # +############################################### +FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:8.0 AS build + +# Docker buildx supplies the value for this arg +ARG TARGETPLATFORM + +# Determine proper runtime value for .NET +# We put the value in a file to be read by later layers. +RUN if [ "$TARGETPLATFORM" = "linux/amd64" ]; then \ + RID=linux-x64 ; \ + elif [ "$TARGETPLATFORM" = "linux/arm64" ]; then \ + RID=linux-arm64 ; \ + elif [ "$TARGETPLATFORM" = "linux/arm/v7" ]; then \ + RID=linux-arm ; \ + fi \ + && echo "RID=$RID" > /tmp/rid.txt + +WORKDIR /source + +# Copy csproj files as distinct layers +COPY bitwarden_license/src/Scim/*.csproj ./bitwarden_license/src/Scim/ +COPY src/Core/*.csproj ./src/Core/ +COPY src/Infrastructure.Dapper/*.csproj ./src/Infrastructure.Dapper/ +COPY src/Infrastructure.EntityFramework/*.csproj ./src/Infrastructure.EntityFramework/ +COPY src/SharedWeb/*.csproj ./src/SharedWeb/ +COPY Directory.Build.props . + +# Restore project dependencies and tools +WORKDIR /source/bitwarden_license/src/Scim +RUN . /tmp/rid.txt && dotnet restore -r $RID + +WORKDIR /source/bitwarden_license/src/Scim + +# Copy required project files +WORKDIR /source +COPY .editorconfig /source +COPY bitwarden_license/src/Scim/. ./bitwarden_license/src/Scim/ +COPY src/Core/. ./src/Core/ +COPY src/Infrastructure.Dapper/. ./src/Infrastructure.Dapper/ +COPY src/Infrastructure.EntityFramework/. ./src/Infrastructure.EntityFramework/ +COPY src/SharedWeb/. ./src/SharedWeb/ +COPY .git/. ./.git/ + +# Build project +WORKDIR /source/bitwarden_license/src/Scim +RUN . /tmp/rid.txt && dotnet publish \ + -c release \ + --no-restore \ + --self-contained \ + /p:PublishSingleFile=true \ + /p:SourceRevisionId="$GIT_COMMIT" \ + -r $RID \ + -o out + +WORKDIR /app + +############################################### +# App stage # +############################################### FROM mcr.microsoft.com/dotnet/aspnet:8.0 +ARG TARGETPLATFORM LABEL com.bitwarden.product="bitwarden" +ENV ASPNETCORE_ENVIRONMENT=Production +ENV ASPNETCORE_URLS=http://+:5000 +EXPOSE 5000 RUN apt-get update \ && apt-get install -y --no-install-recommends \ @@ -9,11 +74,10 @@ RUN apt-get update \ krb5-user \ && rm -rf /var/lib/apt/lists/* -ENV ASPNETCORE_URLS http://+:5000 +# Copy app from the build stage WORKDIR /app -EXPOSE 5000 -COPY obj/build-output/publish . -COPY entrypoint.sh / +COPY --from=build /source/bitwarden_license/src/Scim/out /app +COPY ./bitwarden_license/src/Scim/entrypoint.sh /entrypoint.sh RUN chmod +x /entrypoint.sh HEALTHCHECK CMD curl -f http://localhost:5000/alive || exit 1 diff --git a/bitwarden_license/src/Scim/entrypoint.sh b/bitwarden_license/src/Scim/entrypoint.sh index edc3bbe14a..41930504d3 100644 --- a/bitwarden_license/src/Scim/entrypoint.sh +++ b/bitwarden_license/src/Scim/entrypoint.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # Setup @@ -19,31 +19,42 @@ then LGID=65534 fi -# Create user and group +if [ "$(id -u)" = "0" ] +then + # Create user and group -groupadd -o -g $LGID $GROUPNAME >/dev/null 2>&1 || -groupmod -o -g $LGID $GROUPNAME >/dev/null 2>&1 -useradd -o -u $LUID -g $GROUPNAME -s /bin/false $USERNAME >/dev/null 2>&1 || -usermod -o -u $LUID -g $GROUPNAME -s /bin/false $USERNAME >/dev/null 2>&1 -mkhomedir_helper $USERNAME + groupadd -o -g $LGID $GROUPNAME >/dev/null 2>&1 || + groupmod -o -g $LGID $GROUPNAME >/dev/null 2>&1 + useradd -o -u $LUID -g $GROUPNAME -s /bin/false $USERNAME >/dev/null 2>&1 || + usermod -o -u $LUID -g $GROUPNAME -s /bin/false $USERNAME >/dev/null 2>&1 + mkhomedir_helper $USERNAME -# The rest... + # The rest... -chown -R $USERNAME:$GROUPNAME /app -mkdir -p /etc/bitwarden/core -mkdir -p /etc/bitwarden/logs -mkdir -p /etc/bitwarden/ca-certificates -chown -R $USERNAME:$GROUPNAME /etc/bitwarden + chown -R $USERNAME:$GROUPNAME /app + mkdir -p /etc/bitwarden/core + mkdir -p /etc/bitwarden/logs + mkdir -p /etc/bitwarden/ca-certificates + chown -R $USERNAME:$GROUPNAME /etc/bitwarden -if [[ $globalSettings__selfHosted == "true" ]]; then - cp /etc/bitwarden/ca-certificates/*.crt /usr/local/share/ca-certificates/ >/dev/null 2>&1 \ - && update-ca-certificates + if [[ -f "/etc/bitwarden/kerberos/bitwarden.keytab" && -f "/etc/bitwarden/kerberos/krb5.conf" ]]; then + chown -R $USERNAME:$GROUPNAME /etc/bitwarden/kerberos + fi + + gosu_cmd="gosu $USERNAME:$GROUPNAME" +else + gosu_cmd="" fi if [[ -f "/etc/bitwarden/kerberos/bitwarden.keytab" && -f "/etc/bitwarden/kerberos/krb5.conf" ]]; then - chown -R $USERNAME:$GROUPNAME /etc/bitwarden/kerberos - cp -f /etc/bitwarden/kerberos/krb5.conf /etc/krb5.conf - gosu $USERNAME:$GROUPNAME kinit $globalSettings__kerberosUser -k -t /etc/bitwarden/kerberos/bitwarden.keytab + cp -f /etc/bitwarden/kerberos/krb5.conf /etc/krb5.conf + $gosu_cmd kinit $globalSettings__kerberosUser -k -t /etc/bitwarden/kerberos/bitwarden.keytab fi -exec gosu $USERNAME:$GROUPNAME dotnet /app/Scim.dll +if [[ $globalSettings__selfHosted == "true" ]]; then + if [[ -z $globalSettings__identityServer__certificateLocation ]]; then + export globalSettings__identityServer__certificateLocation=/etc/bitwarden/identity/identity.pfx + fi +fi + +exec $gosu_cmd /app/Scim diff --git a/bitwarden_license/src/Sso/Dockerfile b/bitwarden_license/src/Sso/Dockerfile index 6970dfa7bb..b5ff0dfab1 100644 --- a/bitwarden_license/src/Sso/Dockerfile +++ b/bitwarden_license/src/Sso/Dockerfile @@ -1,6 +1,71 @@ +############################################### +# Build stage # +############################################### +FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:8.0 AS build + +# Docker buildx supplies the value for this arg +ARG TARGETPLATFORM + +# Determine proper runtime value for .NET +# We put the value in a file to be read by later layers. +RUN if [ "$TARGETPLATFORM" = "linux/amd64" ]; then \ + RID=linux-x64 ; \ + elif [ "$TARGETPLATFORM" = "linux/arm64" ]; then \ + RID=linux-arm64 ; \ + elif [ "$TARGETPLATFORM" = "linux/arm/v7" ]; then \ + RID=linux-arm ; \ + fi \ + && echo "RID=$RID" > /tmp/rid.txt + +WORKDIR /source + +# Copy csproj files as distinct layers +COPY bitwarden_license/src/Sso/*.csproj ./bitwarden_license/src/Sso/ +COPY src/Core/*.csproj ./src/Core/ +COPY src/Infrastructure.Dapper/*.csproj ./src/Infrastructure.Dapper/ +COPY src/Infrastructure.EntityFramework/*.csproj ./src/Infrastructure.EntityFramework/ +COPY src/SharedWeb/*.csproj ./src/SharedWeb/ +COPY Directory.Build.props . + +# Restore project dependencies and tools +WORKDIR /source/bitwarden_license/src/Sso +RUN . /tmp/rid.txt && dotnet restore -r $RID + +WORKDIR /source/bitwarden_license/src/Sso + +# Copy required project files +WORKDIR /source +COPY .editorconfig /source +COPY bitwarden_license/src/Sso/. ./bitwarden_license/src/Sso/ +COPY src/Core/. ./src/Core/ +COPY src/Infrastructure.Dapper/. ./src/Infrastructure.Dapper/ +COPY src/Infrastructure.EntityFramework/. ./src/Infrastructure.EntityFramework/ +COPY src/SharedWeb/. ./src/SharedWeb/ +COPY .git/. ./.git/ + +# Build project +WORKDIR /source/bitwarden_license/src/Sso +RUN . /tmp/rid.txt && dotnet publish \ + -c release \ + --no-restore \ + --self-contained \ + /p:PublishSingleFile=true \ + /p:SourceRevisionId="$GIT_COMMIT" \ + -r $RID \ + -o out + +WORKDIR /app + +############################################### +# App stage # +############################################### FROM mcr.microsoft.com/dotnet/aspnet:8.0 +ARG TARGETPLATFORM LABEL com.bitwarden.product="bitwarden" +ENV ASPNETCORE_ENVIRONMENT=Production +ENV ASPNETCORE_URLS=http://+:5000 +EXPOSE 5000 RUN apt-get update \ && apt-get install -y --no-install-recommends \ @@ -9,11 +74,10 @@ RUN apt-get update \ krb5-user \ && rm -rf /var/lib/apt/lists/* -ENV ASPNETCORE_URLS http://+:5000 +# Copy app from the build stage WORKDIR /app -EXPOSE 5000 -COPY obj/build-output/publish . -COPY entrypoint.sh / +COPY --from=build /source/bitwarden_license/src/Sso/out /app +COPY ./bitwarden_license/src/Sso/entrypoint.sh /entrypoint.sh RUN chmod +x /entrypoint.sh HEALTHCHECK CMD curl -f http://localhost:5000/alive || exit 1 diff --git a/bitwarden_license/src/Sso/entrypoint.sh b/bitwarden_license/src/Sso/entrypoint.sh index 2c7bd18b84..c762659fb3 100644 --- a/bitwarden_license/src/Sso/entrypoint.sh +++ b/bitwarden_license/src/Sso/entrypoint.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # Setup @@ -19,37 +19,42 @@ then LGID=65534 fi -# Create user and group +if [ "$(id -u)" = "0" ] +then + # Create user and group -groupadd -o -g $LGID $GROUPNAME >/dev/null 2>&1 || -groupmod -o -g $LGID $GROUPNAME >/dev/null 2>&1 -useradd -o -u $LUID -g $GROUPNAME -s /bin/false $USERNAME >/dev/null 2>&1 || -usermod -o -u $LUID -g $GROUPNAME -s /bin/false $USERNAME >/dev/null 2>&1 -mkhomedir_helper $USERNAME + groupadd -o -g $LGID $GROUPNAME >/dev/null 2>&1 || + groupmod -o -g $LGID $GROUPNAME >/dev/null 2>&1 + useradd -o -u $LUID -g $GROUPNAME -s /bin/false $USERNAME >/dev/null 2>&1 || + usermod -o -u $LUID -g $GROUPNAME -s /bin/false $USERNAME >/dev/null 2>&1 + mkhomedir_helper $USERNAME -# The rest... + # The rest... -mkdir -p /etc/bitwarden/identity -mkdir -p /etc/bitwarden/core -mkdir -p /etc/bitwarden/logs -mkdir -p /etc/bitwarden/ca-certificates -chown -R $USERNAME:$GROUPNAME /etc/bitwarden + chown -R $USERNAME:$GROUPNAME /app + mkdir -p /etc/bitwarden/core + mkdir -p /etc/bitwarden/logs + mkdir -p /etc/bitwarden/ca-certificates + chown -R $USERNAME:$GROUPNAME /etc/bitwarden -if [[ $globalSettings__selfHosted == "true" ]]; then - cp /etc/bitwarden/identity/identity.pfx /app/identity.pfx -fi + if [[ -f "/etc/bitwarden/kerberos/bitwarden.keytab" && -f "/etc/bitwarden/kerberos/krb5.conf" ]]; then + chown -R $USERNAME:$GROUPNAME /etc/bitwarden/kerberos + fi -chown -R $USERNAME:$GROUPNAME /app - -if [[ $globalSettings__selfHosted == "true" ]]; then - cp /etc/bitwarden/ca-certificates/*.crt /usr/local/share/ca-certificates/ >/dev/null 2>&1 \ - && update-ca-certificates + gosu_cmd="gosu $USERNAME:$GROUPNAME" +else + gosu_cmd="" fi if [[ -f "/etc/bitwarden/kerberos/bitwarden.keytab" && -f "/etc/bitwarden/kerberos/krb5.conf" ]]; then - chown -R $USERNAME:$GROUPNAME /etc/bitwarden/kerberos - cp -f /etc/bitwarden/kerberos/krb5.conf /etc/krb5.conf - gosu $USERNAME:$GROUPNAME kinit $globalSettings__kerberosUser -k -t /etc/bitwarden/kerberos/bitwarden.keytab + cp -f /etc/bitwarden/kerberos/krb5.conf /etc/krb5.conf + $gosu_cmd kinit $globalSettings__kerberosUser -k -t /etc/bitwarden/kerberos/bitwarden.keytab fi -exec gosu $USERNAME:$GROUPNAME dotnet /app/Sso.dll +if [[ $globalSettings__selfHosted == "true" ]]; then + if [[ -z $globalSettings__identityServer__certificateLocation ]]; then + export globalSettings__identityServer__certificateLocation=/etc/bitwarden/identity/identity.pfx + fi +fi + +exec $gosu_cmd /app/Sso diff --git a/src/Admin/.dockerignore b/src/Admin/.dockerignore deleted file mode 100644 index fc12f25146..0000000000 --- a/src/Admin/.dockerignore +++ /dev/null @@ -1,4 +0,0 @@ -* -!obj/build-output/publish/* -!obj/Docker/empty/ -!entrypoint.sh diff --git a/src/Admin/Dockerfile b/src/Admin/Dockerfile index 79d117681c..f2810c6c81 100644 --- a/src/Admin/Dockerfile +++ b/src/Admin/Dockerfile @@ -1,21 +1,102 @@ -FROM mcr.microsoft.com/dotnet/aspnet:8.0 +############################################### +# Build stage # +############################################### +FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:8.0 AS build +ARG GIT_COMMIT +# Docker buildx supplies the value for this arg +ARG TARGETPLATFORM + +# Determine proper runtime value for .NET +RUN if [ "$TARGETPLATFORM" = "linux/amd64" ]; then \ + RID=linux-x64 ; \ + elif [ "$TARGETPLATFORM" = "linux/arm64" ]; then \ + RID=linux-arm64 ; \ + elif [ "$TARGETPLATFORM" = "linux/arm/v7" ]; then \ + RID=linux-arm ; \ + fi \ + && echo "RID=$RID" > /tmp/rid.txt + +# Copy csproj files as distinct layers +WORKDIR /source +COPY src/Admin/*.csproj ./src/Admin/ +COPY src/Core/*.csproj ./src/Core/ +COPY src/Infrastructure.Dapper/*.csproj ./src/Infrastructure.Dapper/ +COPY src/Infrastructure.EntityFramework/*.csproj ./src/Infrastructure.EntityFramework/ +COPY src/SharedWeb/*.csproj ./src/SharedWeb/ +COPY util/Migrator/*.csproj ./util/Migrator/ +COPY util/MySqlMigrations/*.csproj ./util/MySqlMigrations/ +COPY util/PostgresMigrations/*.csproj ./util/PostgresMigrations/ +COPY util/SqliteMigrations/*.csproj ./util/SqliteMigrations/ +COPY bitwarden_license/src/Commercial.Core/*.csproj ./bitwarden_license/src/Commercial.Core/ +COPY bitwarden_license/src/Commercial.Infrastructure.EntityFramework/*.csproj ./bitwarden_license/src/Commercial.Infrastructure.EntityFramework/ +COPY Directory.Build.props . + +# Set up Node +ARG NODE_VERSION=20 +RUN curl -fsSL https://deb.nodesource.com/setup_${NODE_VERSION}.x | bash - \ + && apt-get update \ + && apt-get install -y nodejs \ + && npm install -g npm@latest && \ + rm -rf /var/lib/apt/lists/* + +# Copying package.json, package-lock.json, and packages.lock.json +WORKDIR /source/src/Admin +COPY src/Admin/package*.json . +RUN npm ci + +# Restore project dependencies and tools +RUN . /tmp/rid.txt && dotnet restore -r $RID + +# Copy required project files +WORKDIR /source +COPY src/Admin/. ./src/Admin/ +COPY src/Core/. ./src/Core/ +COPY src/Infrastructure.Dapper/. ./src/Infrastructure.Dapper/ +COPY src/Infrastructure.EntityFramework/. ./src/Infrastructure.EntityFramework/ +COPY src/SharedWeb/. ./src/SharedWeb/ +COPY util/Migrator/. ./util/Migrator/ +COPY util/MySqlMigrations/. ./util/MySqlMigrations/ +COPY util/PostgresMigrations/. ./util/PostgresMigrations/ +COPY util/SqliteMigrations/. ./util/SqliteMigrations/ +COPY util/EfShared/. ./util/EfShared/ +COPY bitwarden_license/src/Commercial.Core/. ./bitwarden_license/src/Commercial.Core/ +COPY bitwarden_license/src/Commercial.Infrastructure.EntityFramework/. ./bitwarden_license/src/Commercial.Infrastructure.EntityFramework/ +COPY .git/. ./.git/ +COPY .editorconfig /source + +# Build project +WORKDIR /source/src/Admin +RUN npm run build +RUN . /tmp/rid.txt && dotnet publish \ + --self-contained \ + /p:PublishSingleFile=true \ + /p:SourceRevisionId="$GIT_COMMIT" \ + -r $RID \ + -o out + +############################################### +# App stage # +############################################### +FROM mcr.microsoft.com/dotnet/aspnet:8.0 LABEL com.bitwarden.product="bitwarden" +EXPOSE 5000 + +ENV ASPNETCORE_URLS=http://+:5000 RUN apt-get update \ && apt-get install -y --no-install-recommends \ gosu \ curl \ - krb5-user \ && rm -rf /var/lib/apt/lists/* -ENV ASPNETCORE_URLS http://+:5000 -WORKDIR /app -EXPOSE 5000 -COPY obj/build-output/publish . -COPY entrypoint.sh / -RUN chmod +x /entrypoint.sh +ENV ASPNETCORE_URLS=http://+:5000 -HEALTHCHECK CMD curl -f http://localhost:5000 || exit 1 +# Copy app from the build stage +WORKDIR /app +COPY --from=build /source/src/Admin/out /app +COPY ./src/Admin/entrypoint.sh /entrypoint.sh +RUN chmod +x /entrypoint.sh +HEALTHCHECK CMD curl -f http://localhost:5000/alive || exit 1 ENTRYPOINT ["/entrypoint.sh"] diff --git a/src/Admin/entrypoint.sh b/src/Admin/entrypoint.sh index 2c564b1ce6..4d7d238d25 100644 --- a/src/Admin/entrypoint.sh +++ b/src/Admin/entrypoint.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # Setup @@ -19,31 +19,36 @@ then LGID=65534 fi -# Create user and group +if [ "$(id -u)" = "0" ] +then + # Create user and group -groupadd -o -g $LGID $GROUPNAME >/dev/null 2>&1 || -groupmod -o -g $LGID $GROUPNAME >/dev/null 2>&1 -useradd -o -u $LUID -g $GROUPNAME -s /bin/false $USERNAME >/dev/null 2>&1 || -usermod -o -u $LUID -g $GROUPNAME -s /bin/false $USERNAME >/dev/null 2>&1 -mkhomedir_helper $USERNAME + groupadd -o -g $LGID $GROUPNAME >/dev/null 2>&1 || + groupmod -o -g $LGID $GROUPNAME >/dev/null 2>&1 + useradd -o -u $LUID -g $GROUPNAME -s /bin/false $USERNAME >/dev/null 2>&1 || + usermod -o -u $LUID -g $GROUPNAME -s /bin/false $USERNAME >/dev/null 2>&1 + mkhomedir_helper $USERNAME -# The rest... + # The rest... -chown -R $USERNAME:$GROUPNAME /app -mkdir -p /etc/bitwarden/core -mkdir -p /etc/bitwarden/logs -mkdir -p /etc/bitwarden/ca-certificates -chown -R $USERNAME:$GROUPNAME /etc/bitwarden + chown -R $USERNAME:$GROUPNAME /app + mkdir -p /etc/bitwarden/core + mkdir -p /etc/bitwarden/logs + mkdir -p /etc/bitwarden/ca-certificates + chown -R $USERNAME:$GROUPNAME /etc/bitwarden -if [[ $globalSettings__selfHosted == "true" ]]; then - cp /etc/bitwarden/ca-certificates/*.crt /usr/local/share/ca-certificates/ >/dev/null 2>&1 \ - && update-ca-certificates + if [[ -f "/etc/bitwarden/kerberos/bitwarden.keytab" && -f "/etc/bitwarden/kerberos/krb5.conf" ]]; then + chown -R $USERNAME:$GROUPNAME /etc/bitwarden/kerberos + fi + + gosu_cmd="gosu $USERNAME:$GROUPNAME" +else + gosu_cmd="" fi if [[ -f "/etc/bitwarden/kerberos/bitwarden.keytab" && -f "/etc/bitwarden/kerberos/krb5.conf" ]]; then - chown -R $USERNAME:$GROUPNAME /etc/bitwarden/kerberos - cp -f /etc/bitwarden/kerberos/krb5.conf /etc/krb5.conf - gosu $USERNAME:$GROUPNAME kinit $globalSettings__kerberosUser -k -t /etc/bitwarden/kerberos/bitwarden.keytab + cp -f /etc/bitwarden/kerberos/krb5.conf /etc/krb5.conf + $gosu_cmd kinit $globalSettings__kerberosUser -k -t /etc/bitwarden/kerberos/bitwarden.keytab fi -exec gosu $USERNAME:$GROUPNAME dotnet /app/Admin.dll +exec $gosu_cmd /app/Admin diff --git a/src/Api/.dockerignore b/src/Api/.dockerignore deleted file mode 100644 index fc12f25146..0000000000 --- a/src/Api/.dockerignore +++ /dev/null @@ -1,4 +0,0 @@ -* -!obj/build-output/publish/* -!obj/Docker/empty/ -!entrypoint.sh diff --git a/src/Api/Dockerfile b/src/Api/Dockerfile index 6970dfa7bb..6e3ab0e444 100644 --- a/src/Api/Dockerfile +++ b/src/Api/Dockerfile @@ -1,6 +1,71 @@ +############################################### +# Build stage # +############################################### +FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:8.0 AS build +ARG GIT_COMMIT + +# Docker buildx supplies the value for this arg +ARG TARGETPLATFORM + +# Determine proper runtime value for .NET +# We put the value in a file to be read by later layers. +RUN if [ "$TARGETPLATFORM" = "linux/amd64" ]; then \ + RID=linux-x64 ; \ + elif [ "$TARGETPLATFORM" = "linux/arm64" ]; then \ + RID=linux-arm64 ; \ + elif [ "$TARGETPLATFORM" = "linux/arm/v7" ]; then \ + RID=linux-arm ; \ + fi \ + && echo "RID=$RID" > /tmp/rid.txt + +# Copy csproj files as distinct layers +WORKDIR /source +COPY src/Api/*.csproj ./src/Api/ +COPY src/Core/*.csproj ./src/Core/ +COPY src/Infrastructure.Dapper/*.csproj ./src/Infrastructure.Dapper/ +COPY src/Infrastructure.EntityFramework/*.csproj ./src/Infrastructure.EntityFramework/ +COPY src/SharedWeb/*.csproj ./src/SharedWeb/ +COPY bitwarden_license/src/Commercial.Core/*.csproj ./bitwarden_license/src/Commercial.Core/ +COPY bitwarden_license/src/Commercial.Infrastructure.EntityFramework/*.csproj ./bitwarden_license/src/Commercial.Infrastructure.EntityFramework/ +COPY Directory.Build.props . + +# Restore project dependencies and tools +WORKDIR /source/src/Api +RUN . /tmp/rid.txt && dotnet restore -r $RID + +# Copy required project files +WORKDIR /source +COPY src/Api/. ./src/Api/ +COPY src/Core/. ./src/Core/ +COPY src/Infrastructure.Dapper/. ./src/Infrastructure.Dapper/ +COPY src/Infrastructure.EntityFramework/. ./src/Infrastructure.EntityFramework/ +COPY src/SharedWeb/. ./src/SharedWeb/ +COPY bitwarden_license/src/Commercial.Core/. ./bitwarden_license/src/Commercial.Core/ +COPY bitwarden_license/src/Commercial.Infrastructure.EntityFramework/. ./bitwarden_license/src/Commercial.Infrastructure.EntityFramework/ +COPY .git/. ./.git/ +COPY .editorconfig /source + +# Build project +WORKDIR /source/src/Api +RUN . /tmp/rid.txt && dotnet publish \ + --self-contained \ + /p:PublishSingleFile=true \ + /p:SourceRevisionId="$GIT_COMMIT" \ + -r $RID \ + -o out + +WORKDIR /app + +############################################### +# App stage # +############################################### FROM mcr.microsoft.com/dotnet/aspnet:8.0 +ARG TARGETPLATFORM LABEL com.bitwarden.product="bitwarden" +ENV ASPNETCORE_ENVIRONMENT=Production +ENV ASPNETCORE_URLS=http://+:5000 +EXPOSE 5000 RUN apt-get update \ && apt-get install -y --no-install-recommends \ @@ -9,13 +74,11 @@ RUN apt-get update \ krb5-user \ && rm -rf /var/lib/apt/lists/* -ENV ASPNETCORE_URLS http://+:5000 +# Copy app from the build stage WORKDIR /app -EXPOSE 5000 -COPY obj/build-output/publish . -COPY entrypoint.sh / +COPY --from=build /source/src/Api/out /app +COPY ./src/Api/entrypoint.sh /entrypoint.sh RUN chmod +x /entrypoint.sh - HEALTHCHECK CMD curl -f http://localhost:5000/alive || exit 1 ENTRYPOINT ["/entrypoint.sh"] diff --git a/src/Api/entrypoint.sh b/src/Api/entrypoint.sh index 37d117215c..d89a4648ec 100644 --- a/src/Api/entrypoint.sh +++ b/src/Api/entrypoint.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # Setup @@ -19,31 +19,36 @@ then LGID=65534 fi -# Create user and group +if [ "$(id -u)" = "0" ] +then + # Create user and group -groupadd -o -g $LGID $GROUPNAME >/dev/null 2>&1 || -groupmod -o -g $LGID $GROUPNAME >/dev/null 2>&1 -useradd -o -u $LUID -g $GROUPNAME -s /bin/false $USERNAME >/dev/null 2>&1 || -usermod -o -u $LUID -g $GROUPNAME -s /bin/false $USERNAME >/dev/null 2>&1 -mkhomedir_helper $USERNAME + groupadd -o -g $LGID $GROUPNAME >/dev/null 2>&1 || + groupmod -o -g $LGID $GROUPNAME >/dev/null 2>&1 + useradd -o -u $LUID -g $GROUPNAME -s /bin/false $USERNAME >/dev/null 2>&1 || + usermod -o -u $LUID -g $GROUPNAME -s /bin/false $USERNAME >/dev/null 2>&1 + mkhomedir_helper $USERNAME -# The rest... + # The rest... -chown -R $USERNAME:$GROUPNAME /app -mkdir -p /etc/bitwarden/core -mkdir -p /etc/bitwarden/logs -mkdir -p /etc/bitwarden/ca-certificates -chown -R $USERNAME:$GROUPNAME /etc/bitwarden + chown -R $USERNAME:$GROUPNAME /app + mkdir -p /etc/bitwarden/core + mkdir -p /etc/bitwarden/logs + mkdir -p /etc/bitwarden/ca-certificates + chown -R $USERNAME:$GROUPNAME /etc/bitwarden -if [[ $globalSettings__selfHosted == "true" ]]; then - cp /etc/bitwarden/ca-certificates/*.crt /usr/local/share/ca-certificates/ >/dev/null 2>&1 \ - && update-ca-certificates + if [[ -f "/etc/bitwarden/kerberos/bitwarden.keytab" && -f "/etc/bitwarden/kerberos/krb5.conf" ]]; then + chown -R $USERNAME:$GROUPNAME /etc/bitwarden/kerberos + fi + + gosu_cmd="gosu $USERNAME:$GROUPNAME" +else + gosu_cmd="" fi if [[ -f "/etc/bitwarden/kerberos/bitwarden.keytab" && -f "/etc/bitwarden/kerberos/krb5.conf" ]]; then - chown -R $USERNAME:$GROUPNAME /etc/bitwarden/kerberos - cp -f /etc/bitwarden/kerberos/krb5.conf /etc/krb5.conf - gosu $USERNAME:$GROUPNAME kinit $globalSettings__kerberosUser -k -t /etc/bitwarden/kerberos/bitwarden.keytab + cp -f /etc/bitwarden/kerberos/krb5.conf /etc/krb5.conf + $gosu_cmd kinit $globalSettings__kerberosUser -k -t /etc/bitwarden/kerberos/bitwarden.keytab fi -exec gosu $USERNAME:$GROUPNAME dotnet /app/Api.dll +exec $gosu_cmd /app/Api diff --git a/src/Billing/.dockerignore b/src/Billing/.dockerignore deleted file mode 100644 index fc12f25146..0000000000 --- a/src/Billing/.dockerignore +++ /dev/null @@ -1,4 +0,0 @@ -* -!obj/build-output/publish/* -!obj/Docker/empty/ -!entrypoint.sh diff --git a/src/Billing/Dockerfile b/src/Billing/Dockerfile index 9abbe16477..d3e4939a44 100644 --- a/src/Billing/Dockerfile +++ b/src/Billing/Dockerfile @@ -1,6 +1,67 @@ +############################################### +# Build stage # +############################################### +FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:8.0 AS build +ARG GIT_COMMIT + +# Docker buildx supplies the value for this arg +ARG TARGETPLATFORM + +# Determine proper runtime value for .NET +# We put the value in a file to be read by later layers. +RUN if [ "$TARGETPLATFORM" = "linux/amd64" ]; then \ + RID=linux-x64 ; \ + elif [ "$TARGETPLATFORM" = "linux/arm64" ]; then \ + RID=linux-arm64 ; \ + elif [ "$TARGETPLATFORM" = "linux/arm/v7" ]; then \ + RID=linux-arm ; \ + fi \ + && echo "RID=$RID" > /tmp/rid.txt + +# Copy csproj files as distinct layers +WORKDIR /source +COPY src/Billing/*.csproj ./src/Billing/ +COPY src/Core/*.csproj ./src/Core/ +COPY src/Infrastructure.Dapper/*.csproj ./src/Infrastructure.Dapper/ +COPY src/Infrastructure.EntityFramework/*.csproj ./src/Infrastructure.EntityFramework/ +COPY src/SharedWeb/*.csproj ./src/SharedWeb/ +COPY Directory.Build.props . + +# Restore project dependencies and tools +WORKDIR /source/src/Billing +RUN . /tmp/rid.txt && dotnet restore -r $RID + +# Copy required project files +WORKDIR /source +COPY src/Billing/. ./src/Billing/ +COPY src/Core/. ./src/Core/ +COPY src/Infrastructure.Dapper/. ./src/Infrastructure.Dapper/ +COPY src/Infrastructure.EntityFramework/. ./src/Infrastructure.EntityFramework/ +COPY src/SharedWeb/. ./src/SharedWeb/ +COPY .git/. ./.git/ +COPY .editorconfig . + +# Build project +WORKDIR /source/src/Billing +RUN . /tmp/rid.txt && dotnet publish \ + --self-contained \ + /p:PublishSingleFile=true \ + /p:SourceRevisionId="$GIT_COMMIT" \ + -r $RID \ + -o out + +WORKDIR /app + +############################################### +# App stage # +############################################### FROM mcr.microsoft.com/dotnet/aspnet:8.0 +ARG TARGETPLATFORM LABEL com.bitwarden.product="bitwarden" +ENV ASPNETCORE_ENVIRONMENT=Production +ENV ASPNETCORE_URLS=http://+:5000 +EXPOSE 5000 RUN apt-get update \ && apt-get install -y --no-install-recommends \ @@ -8,14 +69,11 @@ RUN apt-get update \ curl \ && rm -rf /var/lib/apt/lists/* -ENV ASPNETCORE_URLS http://+:5000 +# Copy app from the build stage WORKDIR /app -EXPOSE 5000 -COPY entrypoint.sh / +COPY --from=build /source/src/Billing/out /app +COPY ./src/Billing/entrypoint.sh /entrypoint.sh RUN chmod +x /entrypoint.sh - -COPY obj/build-output/publish . - HEALTHCHECK CMD curl -f http://localhost:5000/alive || exit 1 ENTRYPOINT ["/entrypoint.sh"] diff --git a/src/Billing/entrypoint.sh b/src/Billing/entrypoint.sh index 6d98cfa6f6..66540416f5 100644 --- a/src/Billing/entrypoint.sh +++ b/src/Billing/entrypoint.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # Setup @@ -19,25 +19,27 @@ then LGID=65534 fi -# Create user and group +if [ "$(id -u)" = "0" ] +then + # Create user and group -groupadd -o -g $LGID $GROUPNAME >/dev/null 2>&1 || -groupmod -o -g $LGID $GROUPNAME >/dev/null 2>&1 -useradd -o -u $LUID -g $GROUPNAME -s /bin/false $USERNAME >/dev/null 2>&1 || -usermod -o -u $LUID -g $GROUPNAME -s /bin/false $USERNAME >/dev/null 2>&1 -mkhomedir_helper $USERNAME + groupadd -o -g $LGID $GROUPNAME >/dev/null 2>&1 || + groupmod -o -g $LGID $GROUPNAME >/dev/null 2>&1 + useradd -o -u $LUID -g $GROUPNAME -s /bin/false $USERNAME >/dev/null 2>&1 || + usermod -o -u $LUID -g $GROUPNAME -s /bin/false $USERNAME >/dev/null 2>&1 + mkhomedir_helper $USERNAME -# The rest... + # The rest... -chown -R $USERNAME:$GROUPNAME /app -mkdir -p /etc/bitwarden/core -mkdir -p /etc/bitwarden/logs -mkdir -p /etc/bitwarden/ca-certificates -chown -R $USERNAME:$GROUPNAME /etc/bitwarden + chown -R $USERNAME:$GROUPNAME /app + mkdir -p /etc/bitwarden/core + mkdir -p /etc/bitwarden/logs + mkdir -p /etc/bitwarden/ca-certificates + chown -R $USERNAME:$GROUPNAME /etc/bitwarden -if [[ $globalSettings__selfHosted == "true" ]]; then - cp /etc/bitwarden/ca-certificates/*.crt /usr/local/share/ca-certificates/ >/dev/null 2>&1 \ - && update-ca-certificates + gosu_cmd="gosu $USERNAME:$GROUPNAME" +else + gosu_cmd="" fi -exec gosu $USERNAME:$GROUPNAME dotnet /app/Billing.dll +exec $gosu_cmd /app/Billing diff --git a/src/Core/Settings/GlobalSettings.cs b/src/Core/Settings/GlobalSettings.cs index 2b658c65b3..d5b3a13c62 100644 --- a/src/Core/Settings/GlobalSettings.cs +++ b/src/Core/Settings/GlobalSettings.cs @@ -423,6 +423,7 @@ public class GlobalSettings : IGlobalSettings public class IdentityServerSettings { + public string CertificateLocation { get; set; } = "identity.pfx"; public string CertificateThumbprint { get; set; } public string CertificatePassword { get; set; } public string RedisConnectionString { get; set; } diff --git a/src/Core/Utilities/CoreHelpers.cs b/src/Core/Utilities/CoreHelpers.cs index eebcb00738..623c0efca6 100644 --- a/src/Core/Utilities/CoreHelpers.cs +++ b/src/Core/Utilities/CoreHelpers.cs @@ -660,9 +660,9 @@ public static class CoreHelpers { if (globalSettings.SelfHosted && SettingHasValue(globalSettings.IdentityServer.CertificatePassword) - && File.Exists("identity.pfx")) + && File.Exists(globalSettings.IdentityServer.CertificateLocation)) { - return GetCertificate("identity.pfx", + return GetCertificate(globalSettings.IdentityServer.CertificateLocation, globalSettings.IdentityServer.CertificatePassword); } else if (SettingHasValue(globalSettings.IdentityServer.CertificateThumbprint)) diff --git a/src/Events/.dockerignore b/src/Events/.dockerignore deleted file mode 100644 index fc12f25146..0000000000 --- a/src/Events/.dockerignore +++ /dev/null @@ -1,4 +0,0 @@ -* -!obj/build-output/publish/* -!obj/Docker/empty/ -!entrypoint.sh diff --git a/src/Events/Dockerfile b/src/Events/Dockerfile index 6970dfa7bb..7fd406eeae 100644 --- a/src/Events/Dockerfile +++ b/src/Events/Dockerfile @@ -1,21 +1,79 @@ +############################################### +# Build stage # +############################################### +FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:8.0 AS build +ARG GIT_COMMIT + +# Docker buildx supplies the value for this arg +ARG TARGETPLATFORM + +# Determine proper runtime value for .NET +# We put the value in a file to be read by later layers. +RUN if [ "$TARGETPLATFORM" = "linux/amd64" ]; then \ + RID=linux-x64 ; \ + elif [ "$TARGETPLATFORM" = "linux/arm64" ]; then \ + RID=linux-arm64 ; \ + elif [ "$TARGETPLATFORM" = "linux/arm/v7" ]; then \ + RID=linux-arm ; \ + fi \ + && echo "RID=$RID" > /tmp/rid.txt + +# Copy csproj files as distinct layers +WORKDIR /source +COPY src/Events/*.csproj ./src/Events/ +COPY src/Core/*.csproj ./src/Core/ +COPY src/Infrastructure.Dapper/*.csproj ./src/Infrastructure.Dapper/ +COPY src/Infrastructure.EntityFramework/*.csproj ./src/Infrastructure.EntityFramework/ +COPY src/SharedWeb/*.csproj ./src/SharedWeb/ +COPY Directory.Build.props . + +# Restore project dependencies and tools +WORKDIR /source/src/Events +RUN . /tmp/rid.txt && dotnet restore -r $RID + +# Copy required project files +WORKDIR /source +COPY src/Events/. ./src/Events/ +COPY src/Core/. ./src/Core/ +COPY src/Infrastructure.Dapper/. ./src/Infrastructure.Dapper/ +COPY src/Infrastructure.EntityFramework/. ./src/Infrastructure.EntityFramework/ +COPY src/SharedWeb/. ./src/SharedWeb/ +COPY .git/. ./.git/ +COPY .editorconfig /source + +# Build project +WORKDIR /source/src/Events +RUN . /tmp/rid.txt && dotnet publish \ + --self-contained \ + /p:PublishSingleFile=true \ + /p:SourceRevisionId="$GIT_COMMIT" \ + -r $RID \ + -o out + +WORKDIR /app + +############################################### +# App stage # +############################################### FROM mcr.microsoft.com/dotnet/aspnet:8.0 +ARG TARGETPLATFORM LABEL com.bitwarden.product="bitwarden" +ENV ASPNETCORE_ENVIRONMENT=Production +ENV ASPNETCORE_URLS=http://+:5000 +EXPOSE 5000 RUN apt-get update \ && apt-get install -y --no-install-recommends \ gosu \ curl \ - krb5-user \ && rm -rf /var/lib/apt/lists/* -ENV ASPNETCORE_URLS http://+:5000 +# Copy app from the build stage WORKDIR /app -EXPOSE 5000 -COPY obj/build-output/publish . -COPY entrypoint.sh / +COPY --from=build /source/src/Events/out /app +COPY ./src/Events/entrypoint.sh /entrypoint.sh RUN chmod +x /entrypoint.sh - HEALTHCHECK CMD curl -f http://localhost:5000/alive || exit 1 ENTRYPOINT ["/entrypoint.sh"] diff --git a/src/Events/entrypoint.sh b/src/Events/entrypoint.sh index f1bd48e1a3..92b19195ea 100644 --- a/src/Events/entrypoint.sh +++ b/src/Events/entrypoint.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # Setup @@ -19,31 +19,36 @@ then LGID=65534 fi -# Create user and group +if [ "$(id -u)" = "0" ] +then + # Create user and group -groupadd -o -g $LGID $GROUPNAME >/dev/null 2>&1 || -groupmod -o -g $LGID $GROUPNAME >/dev/null 2>&1 -useradd -o -u $LUID -g $GROUPNAME -s /bin/false $USERNAME >/dev/null 2>&1 || -usermod -o -u $LUID -g $GROUPNAME -s /bin/false $USERNAME >/dev/null 2>&1 -mkhomedir_helper $USERNAME + groupadd -o -g $LGID $GROUPNAME >/dev/null 2>&1 || + groupmod -o -g $LGID $GROUPNAME >/dev/null 2>&1 + useradd -o -u $LUID -g $GROUPNAME -s /bin/false $USERNAME >/dev/null 2>&1 || + usermod -o -u $LUID -g $GROUPNAME -s /bin/false $USERNAME >/dev/null 2>&1 + mkhomedir_helper $USERNAME -# The rest... + # The rest... -chown -R $USERNAME:$GROUPNAME /app -mkdir -p /etc/bitwarden/core -mkdir -p /etc/bitwarden/logs -mkdir -p /etc/bitwarden/ca-certificates -chown -R $USERNAME:$GROUPNAME /etc/bitwarden + chown -R $USERNAME:$GROUPNAME /app + mkdir -p /etc/bitwarden/core + mkdir -p /etc/bitwarden/logs + mkdir -p /etc/bitwarden/ca-certificates + chown -R $USERNAME:$GROUPNAME /etc/bitwarden -if [[ $globalSettings__selfHosted == "true" ]]; then - cp /etc/bitwarden/ca-certificates/*.crt /usr/local/share/ca-certificates/ >/dev/null 2>&1 \ - && update-ca-certificates + if [[ -f "/etc/bitwarden/kerberos/bitwarden.keytab" && -f "/etc/bitwarden/kerberos/krb5.conf" ]]; then + chown -R $USERNAME:$GROUPNAME /etc/bitwarden/kerberos + fi + + gosu_cmd="gosu $USERNAME:$GROUPNAME" +else + gosu_cmd="" fi if [[ -f "/etc/bitwarden/kerberos/bitwarden.keytab" && -f "/etc/bitwarden/kerberos/krb5.conf" ]]; then - chown -R $USERNAME:$GROUPNAME /etc/bitwarden/kerberos - cp -f /etc/bitwarden/kerberos/krb5.conf /etc/krb5.conf - gosu $USERNAME:$GROUPNAME kinit $globalSettings__kerberosUser -k -t /etc/bitwarden/kerberos/bitwarden.keytab + cp -f /etc/bitwarden/kerberos/krb5.conf /etc/krb5.conf + $gosu_cmd kinit $globalSettings__kerberosUser -k -t /etc/bitwarden/kerberos/bitwarden.keytab fi -exec gosu $USERNAME:$GROUPNAME dotnet /app/Events.dll +exec $gosu_cmd /app/Events diff --git a/src/EventsProcessor/Dockerfile b/src/EventsProcessor/Dockerfile index 4344452f65..4e9c23ac11 100644 --- a/src/EventsProcessor/Dockerfile +++ b/src/EventsProcessor/Dockerfile @@ -1,6 +1,68 @@ +############################################### +# Build stage # +############################################### +FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:8.0 AS build +ARG GIT_COMMIT + +# Docker buildx supplies the value for this arg +ARG TARGETPLATFORM + +# Determine proper runtime value for .NET +# We put the value in a file to be read by later layers. +RUN if [ "$TARGETPLATFORM" = "linux/amd64" ]; then \ + RID=linux-x64 ; \ + elif [ "$TARGETPLATFORM" = "linux/arm64" ]; then \ + RID=linux-arm64 ; \ + elif [ "$TARGETPLATFORM" = "linux/arm/v7" ]; then \ + RID=linux-arm ; \ + fi \ + && echo "RID=$RID" > /tmp/rid.txt + +# Copy csproj files as distinct layers +WORKDIR /source + +COPY src/EventsProcessor/*.csproj ./src/EventsProcessor/ +COPY src/Core/*.csproj ./src/Core/ +COPY src/Infrastructure.Dapper/*.csproj ./src/Infrastructure.Dapper/ +COPY src/Infrastructure.EntityFramework/*.csproj ./src/Infrastructure.EntityFramework/ +COPY src/SharedWeb/*.csproj ./src/SharedWeb/ +COPY Directory.Build.props . + +# Restore project dependencies and tools +WORKDIR /source/src/EventsProcessor +RUN . /tmp/rid.txt && dotnet restore -r $RID + +# Copy required project files +WORKDIR /source +COPY src/EventsProcessor/. ./src/EventsProcessor/ +COPY src/Core/. ./src/Core/ +COPY src/Infrastructure.Dapper/. ./src/Infrastructure.Dapper/ +COPY src/Infrastructure.EntityFramework/. ./src/Infrastructure.EntityFramework/ +COPY src/SharedWeb/. ./src/SharedWeb/ +COPY .git/. ./.git/ +COPY .editorconfig /source + +# Build project +WORKDIR /source/src/EventsProcessor +RUN . /tmp/rid.txt && dotnet publish \ + --self-contained \ + /p:PublishSingleFile=true \ + /p:SourceRevisionId="$GIT_COMMIT" \ + -r $RID \ + -o out + +WORKDIR /app + +############################################### +# App stage # +############################################### FROM mcr.microsoft.com/dotnet/aspnet:8.0 +ARG TARGETPLATFORM LABEL com.bitwarden.product="bitwarden" +ENV ASPNETCORE_ENVIRONMENT=Production +ENV ASPNETCORE_URLS=http://+:5000 +EXPOSE 5000 RUN apt-get update \ && apt-get install -y --no-install-recommends \ @@ -8,13 +70,12 @@ RUN apt-get update \ curl \ && rm -rf /var/lib/apt/lists/* -ENV ASPNETCORE_URLS http://+:5000 +# Copy app from the build stage +# Copy app from the build stage WORKDIR /app -EXPOSE 5000 -COPY obj/build-output/publish . -COPY entrypoint.sh / +COPY --from=build /source/src/EventsProcessor/out /app +COPY ./src/EventsProcessor/entrypoint.sh /entrypoint.sh RUN chmod +x /entrypoint.sh - HEALTHCHECK CMD curl -f http://localhost:5000/alive || exit 1 -CMD ["./../entrypoint.sh"] +CMD ["/entrypoint.sh"] diff --git a/src/EventsProcessor/entrypoint.sh b/src/EventsProcessor/entrypoint.sh index 0ae7b82cb5..e0d2dc0230 100644 --- a/src/EventsProcessor/entrypoint.sh +++ b/src/EventsProcessor/entrypoint.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # Setup @@ -19,24 +19,26 @@ then LGID=65534 fi -# Create user and group +if [ "$(id -u)" = "0" ] +then + # Create user and group -groupadd -o -g $LGID $GROUPNAME >/dev/null 2>&1 || -groupmod -o -g $LGID $GROUPNAME >/dev/null 2>&1 -useradd -o -u $LUID -g $GROUPNAME -s /bin/false $USERNAME >/dev/null 2>&1 || -usermod -o -u $LUID -g $GROUPNAME -s /bin/false $USERNAME >/dev/null 2>&1 -mkhomedir_helper $USERNAME + groupadd -o -g $LGID $GROUPNAME >/dev/null 2>&1 || + groupmod -o -g $LGID $GROUPNAME >/dev/null 2>&1 + useradd -o -u $LUID -g $GROUPNAME -s /bin/false $USERNAME >/dev/null 2>&1 || + usermod -o -u $LUID -g $GROUPNAME -s /bin/false $USERNAME >/dev/null 2>&1 + mkhomedir_helper $USERNAME -# The rest... + # The rest... -chown -R $USERNAME:$GROUPNAME /app -mkdir -p /etc/bitwarden/logs -#mkdir -p /etc/bitwarden/ca-certificates -chown -R $USERNAME:$GROUPNAME /etc/bitwarden + chown -R $USERNAME:$GROUPNAME /app + mkdir -p /etc/bitwarden/logs + mkdir -p /etc/bitwarden/ca-certificates + chown -R $USERNAME:$GROUPNAME /etc/bitwarden -if [[ $globalSettings__selfHosted == "true" ]]; then - cp /etc/bitwarden/ca-certificates/*.crt /usr/local/share/ca-certificates/ >/dev/null 2>&1 \ - && update-ca-certificates + gosu_cmd="gosu $USERNAME:$GROUPNAME" +else + gosu_cmd="" fi -exec gosu $USERNAME:$GROUPNAME dotnet /app/EventsProcessor.dll +exec $gosu_cmd /app/EventsProcessor diff --git a/src/Icons/.dockerignore b/src/Icons/.dockerignore deleted file mode 100644 index fc12f25146..0000000000 --- a/src/Icons/.dockerignore +++ /dev/null @@ -1,4 +0,0 @@ -* -!obj/build-output/publish/* -!obj/Docker/empty/ -!entrypoint.sh diff --git a/src/Icons/Dockerfile b/src/Icons/Dockerfile index edc1e0905b..8b78b8d1f6 100644 --- a/src/Icons/Dockerfile +++ b/src/Icons/Dockerfile @@ -1,6 +1,66 @@ +############################################### +# Build stage # +############################################### +FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:8.0 AS build +ARG GIT_COMMIT + +# Docker buildx supplies the value for this arg +ARG TARGETPLATFORM + +# Determine proper runtime value for .NET +RUN if [ "$TARGETPLATFORM" = "linux/amd64" ]; then \ + RID=linux-x64 ; \ + elif [ "$TARGETPLATFORM" = "linux/arm64" ]; then \ + RID=linux-arm64 ; \ + elif [ "$TARGETPLATFORM" = "linux/arm/v7" ]; then \ + RID=linux-arm ; \ + fi \ + && echo "RID=$RID" > /tmp/rid.txt + +# Copy csproj files as distinct layers +WORKDIR /source +COPY src/Icons/*.csproj ./src/Icons/ +COPY src/Core/*.csproj ./src/Core/ +COPY src/Infrastructure.Dapper/*.csproj ./src/Infrastructure.Dapper/ +COPY src/Infrastructure.EntityFramework/*.csproj ./src/Infrastructure.EntityFramework/ +COPY src/SharedWeb/*.csproj ./src/SharedWeb/ +COPY Directory.Build.props . + +# Restore project dependencies and tools +WORKDIR /source/src/Icons +RUN . /tmp/rid.txt && dotnet restore -r $RID + +# Copy required project files +WORKDIR /source +COPY src/Icons/. ./src/Icons/ +COPY src/Core/. ./src/Core/ +COPY src/Infrastructure.Dapper/. ./src/Infrastructure.Dapper/ +COPY src/Infrastructure.EntityFramework/. ./src/Infrastructure.EntityFramework/ +COPY src/SharedWeb/. ./src/SharedWeb/ +COPY .git/. ./.git/ +COPY .editorconfig /source + +# Build project +WORKDIR /source/src/Icons +RUN . /tmp/rid.txt && dotnet publish \ + --self-contained \ + /p:PublishSingleFile=true \ + /p:SourceRevisionId="$GIT_COMMIT" \ + -r $RID \ + -o out + +WORKDIR /app + +############################################### +# App stage # +############################################### FROM mcr.microsoft.com/dotnet/aspnet:8.0 +ARG TARGETPLATFORM LABEL com.bitwarden.product="bitwarden" +ENV ASPNETCORE_ENVIRONMENT=Production +ENV ASPNETCORE_URLS=http://+:5000 +EXPOSE 5000 RUN apt-get update \ && apt-get install -y --no-install-recommends \ @@ -8,13 +68,11 @@ RUN apt-get update \ curl \ && rm -rf /var/lib/apt/lists/* -ENV ASPNETCORE_URLS http://+:5000 +# Copy app from the build stage WORKDIR /app -EXPOSE 5000 -COPY obj/build-output/publish . -COPY entrypoint.sh / +COPY --from=build /source/src/Icons/out /app +COPY ./src/Icons/entrypoint.sh /entrypoint.sh RUN chmod +x /entrypoint.sh - HEALTHCHECK CMD curl -f http://localhost:5000/google.com/icon.png || exit 1 ENTRYPOINT ["/entrypoint.sh"] diff --git a/src/Icons/entrypoint.sh b/src/Icons/entrypoint.sh index 9ed16fba23..c65d3b308d 100644 --- a/src/Icons/entrypoint.sh +++ b/src/Icons/entrypoint.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # Setup @@ -19,24 +19,36 @@ then LGID=65534 fi -# Create user and group +if [ "$(id -u)" = "0" ] +then + # Create user and group -groupadd -o -g $LGID $GROUPNAME >/dev/null 2>&1 || -groupmod -o -g $LGID $GROUPNAME >/dev/null 2>&1 -useradd -o -u $LUID -g $GROUPNAME -s /bin/false $USERNAME >/dev/null 2>&1 || -usermod -o -u $LUID -g $GROUPNAME -s /bin/false $USERNAME >/dev/null 2>&1 -mkhomedir_helper $USERNAME + groupadd -o -g $LGID $GROUPNAME >/dev/null 2>&1 || + groupmod -o -g $LGID $GROUPNAME >/dev/null 2>&1 + useradd -o -u $LUID -g $GROUPNAME -s /bin/false $USERNAME >/dev/null 2>&1 || + usermod -o -u $LUID -g $GROUPNAME -s /bin/false $USERNAME >/dev/null 2>&1 + mkhomedir_helper $USERNAME -# The rest... + # The rest... -chown -R $USERNAME:$GROUPNAME /app -mkdir -p /etc/bitwarden/logs -mkdir -p /etc/bitwarden/ca-certificates -chown -R $USERNAME:$GROUPNAME /etc/bitwarden + chown -R $USERNAME:$GROUPNAME /app + mkdir -p /etc/bitwarden/core + mkdir -p /etc/bitwarden/logs + mkdir -p /etc/bitwarden/ca-certificates + chown -R $USERNAME:$GROUPNAME /etc/bitwarden -if [[ $globalSettings__selfHosted == "true" ]]; then - cp /etc/bitwarden/ca-certificates/*.crt /usr/local/share/ca-certificates/ >/dev/null 2>&1 \ - && update-ca-certificates + if [[ -f "/etc/bitwarden/kerberos/bitwarden.keytab" && -f "/etc/bitwarden/kerberos/krb5.conf" ]]; then + chown -R $USERNAME:$GROUPNAME /etc/bitwarden/kerberos + fi + + gosu_cmd="gosu $USERNAME:$GROUPNAME" +else + gosu_cmd="" fi -exec gosu $USERNAME:$GROUPNAME dotnet /app/Icons.dll +if [[ -f "/etc/bitwarden/kerberos/bitwarden.keytab" && -f "/etc/bitwarden/kerberos/krb5.conf" ]]; then + cp -f /etc/bitwarden/kerberos/krb5.conf /etc/krb5.conf + $gosu_cmd kinit $globalSettings__kerberosUser -k -t /etc/bitwarden/kerberos/bitwarden.keytab +fi + +exec $gosu_cmd /app/Icons diff --git a/src/Identity/.dockerignore b/src/Identity/.dockerignore deleted file mode 100644 index fc12f25146..0000000000 --- a/src/Identity/.dockerignore +++ /dev/null @@ -1,4 +0,0 @@ -* -!obj/build-output/publish/* -!obj/Docker/empty/ -!entrypoint.sh diff --git a/src/Identity/Dockerfile b/src/Identity/Dockerfile index 050859a496..e15c55671a 100644 --- a/src/Identity/Dockerfile +++ b/src/Identity/Dockerfile @@ -1,6 +1,67 @@ +############################################### +# Build stage # +############################################### +FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:8.0 AS build +ARG GIT_COMMIT + +# Docker buildx supplies the value for this arg +ARG TARGETPLATFORM + +# Determine proper runtime value for .NET +# We put the value in a file to be read by later layers. +RUN if [ "$TARGETPLATFORM" = "linux/amd64" ]; then \ + RID=linux-x64 ; \ + elif [ "$TARGETPLATFORM" = "linux/arm64" ]; then \ + RID=linux-arm64 ; \ + elif [ "$TARGETPLATFORM" = "linux/arm/v7" ]; then \ + RID=linux-arm ; \ + fi \ + && echo "RID=$RID" > /tmp/rid.txt + +# Copy csproj files as distinct layers +WORKDIR /source +COPY src/Identity/*.csproj ./src/Identity/ +COPY src/Core/*.csproj ./src/Core/ +COPY src/Infrastructure.Dapper/*.csproj ./src/Infrastructure.Dapper/ +COPY src/Infrastructure.EntityFramework/*.csproj ./src/Infrastructure.EntityFramework/ +COPY src/SharedWeb/*.csproj ./src/SharedWeb/ +COPY Directory.Build.props . + +# Restore project dependencies and tools +WORKDIR /source/src/Identity +RUN . /tmp/rid.txt && dotnet restore -r $RID + +# Copy required project files +WORKDIR /source +COPY src/Identity/. ./src/Identity/ +COPY src/Core/. ./src/Core/ +COPY src/Infrastructure.Dapper/. ./src/Infrastructure.Dapper/ +COPY src/Infrastructure.EntityFramework/. ./src/Infrastructure.EntityFramework/ +COPY src/SharedWeb/. ./src/SharedWeb/ +COPY .git/. ./.git/ +COPY .editorconfig /source + +# Build project +WORKDIR /source/src/Identity +RUN . /tmp/rid.txt && dotnet publish \ + --self-contained \ + /p:PublishSingleFile=true \ + /p:SourceRevisionId="$GIT_COMMIT" \ + -r $RID \ + -o out + +WORKDIR /app + +############################################### +# App stage # +############################################### FROM mcr.microsoft.com/dotnet/aspnet:8.0 +ARG TARGETPLATFORM LABEL com.bitwarden.product="bitwarden" +ENV ASPNETCORE_ENVIRONMENT=Production +ENV ASPNETCORE_URLS=http://+:5000 +EXPOSE 5000 RUN apt-get update \ && apt-get install -y --no-install-recommends \ @@ -9,11 +70,10 @@ RUN apt-get update \ krb5-user \ && rm -rf /var/lib/apt/lists/* -ENV ASPNETCORE_URLS http://+:5000 +# Copy app from the build stage WORKDIR /app -EXPOSE 5000 -COPY obj/build-output/publish . -COPY entrypoint.sh / +COPY --from=build /source/src/Identity/out /app +COPY ./src/Identity/entrypoint.sh /entrypoint.sh RUN chmod +x /entrypoint.sh HEALTHCHECK CMD curl -f http://localhost:5000/.well-known/openid-configuration || exit 1 diff --git a/src/Identity/entrypoint.sh b/src/Identity/entrypoint.sh index cf59bee472..f5f84cc220 100644 --- a/src/Identity/entrypoint.sh +++ b/src/Identity/entrypoint.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # Setup @@ -19,37 +19,42 @@ then LGID=65534 fi -# Create user and group +if [ "$(id -u)" = "0" ] +then + # Create user and group -groupadd -o -g $LGID $GROUPNAME >/dev/null 2>&1 || -groupmod -o -g $LGID $GROUPNAME >/dev/null 2>&1 -useradd -o -u $LUID -g $GROUPNAME -s /bin/false $USERNAME >/dev/null 2>&1 || -usermod -o -u $LUID -g $GROUPNAME -s /bin/false $USERNAME >/dev/null 2>&1 -mkhomedir_helper $USERNAME + groupadd -o -g $LGID $GROUPNAME >/dev/null 2>&1 || + groupmod -o -g $LGID $GROUPNAME >/dev/null 2>&1 + useradd -o -u $LUID -g $GROUPNAME -s /bin/false $USERNAME >/dev/null 2>&1 || + usermod -o -u $LUID -g $GROUPNAME -s /bin/false $USERNAME >/dev/null 2>&1 + mkhomedir_helper $USERNAME -# The rest... + # The rest... -mkdir -p /etc/bitwarden/identity -mkdir -p /etc/bitwarden/core -mkdir -p /etc/bitwarden/logs -mkdir -p /etc/bitwarden/ca-certificates -chown -R $USERNAME:$GROUPNAME /etc/bitwarden + chown -R $USERNAME:$GROUPNAME /app + mkdir -p /etc/bitwarden/core + mkdir -p /etc/bitwarden/logs + mkdir -p /etc/bitwarden/ca-certificates + chown -R $USERNAME:$GROUPNAME /etc/bitwarden -if [[ $globalSettings__selfHosted == "true" ]]; then - cp /etc/bitwarden/identity/identity.pfx /app/identity.pfx -fi + if [[ -f "/etc/bitwarden/kerberos/bitwarden.keytab" && -f "/etc/bitwarden/kerberos/krb5.conf" ]]; then + chown -R $USERNAME:$GROUPNAME /etc/bitwarden/kerberos + fi -chown -R $USERNAME:$GROUPNAME /app - -if [[ $globalSettings__selfHosted == "true" ]]; then - cp /etc/bitwarden/ca-certificates/*.crt /usr/local/share/ca-certificates/ >/dev/null 2>&1 \ - && update-ca-certificates + gosu_cmd="gosu $USERNAME:$GROUPNAME" +else + gosu_cmd="" fi if [[ -f "/etc/bitwarden/kerberos/bitwarden.keytab" && -f "/etc/bitwarden/kerberos/krb5.conf" ]]; then - chown -R $USERNAME:$GROUPNAME /etc/bitwarden/kerberos - cp -f /etc/bitwarden/kerberos/krb5.conf /etc/krb5.conf - gosu $USERNAME:$GROUPNAME kinit $globalSettings__kerberosUser -k -t /etc/bitwarden/kerberos/bitwarden.keytab + cp -f /etc/bitwarden/kerberos/krb5.conf /etc/krb5.conf + $gosu_cmd kinit $globalSettings__kerberosUser -k -t /etc/bitwarden/kerberos/bitwarden.keytab fi -exec gosu $USERNAME:$GROUPNAME dotnet /app/Identity.dll +if [[ $globalSettings__selfHosted == "true" ]]; then + if [[ -z $globalSettings__identityServer__certificateLocation ]]; then + export globalSettings__identityServer__certificateLocation=/etc/bitwarden/identity/identity.pfx + fi +fi + +exec $gosu_cmd /app/Identity diff --git a/src/Notifications/.dockerignore b/src/Notifications/.dockerignore deleted file mode 100644 index fc12f25146..0000000000 --- a/src/Notifications/.dockerignore +++ /dev/null @@ -1,4 +0,0 @@ -* -!obj/build-output/publish/* -!obj/Docker/empty/ -!entrypoint.sh diff --git a/src/Notifications/Dockerfile b/src/Notifications/Dockerfile index ae9e693c2a..e3d0327cee 100644 --- a/src/Notifications/Dockerfile +++ b/src/Notifications/Dockerfile @@ -1,6 +1,67 @@ +############################################### +# Build stage # +############################################### +FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:8.0 AS build +ARG GIT_COMMIT + +# Docker buildx supplies the value for this arg +ARG TARGETPLATFORM + +# Determine proper runtime value for .NET +# We put the value in a file to be read by later layers. +RUN if [ "$TARGETPLATFORM" = "linux/amd64" ]; then \ + RID=linux-x64 ; \ + elif [ "$TARGETPLATFORM" = "linux/arm64" ]; then \ + RID=linux-arm64 ; \ + elif [ "$TARGETPLATFORM" = "linux/arm/v7" ]; then \ + RID=linux-arm ; \ + fi \ + && echo "RID=$RID" > /tmp/rid.txt + +# Copy csproj files as distinct layers +WORKDIR /source +COPY src/Notifications/*.csproj ./src/Notifications/ +COPY src/Core/*.csproj ./src/Core/ +COPY src/Infrastructure.Dapper/*.csproj ./src/Infrastructure.Dapper/ +COPY src/Infrastructure.EntityFramework/*.csproj ./src/Infrastructure.EntityFramework/ +COPY src/SharedWeb/*.csproj ./src/SharedWeb/ +COPY Directory.Build.props . + +# Restore project dependencies and tools +WORKDIR /source/src/Notifications +RUN . /tmp/rid.txt && dotnet restore -r $RID + +# Copy required project files +WORKDIR /source +COPY src/Notifications/. ./src/Notifications/ +COPY src/Core/. ./src/Core/ +COPY src/Infrastructure.Dapper/. ./src/Infrastructure.Dapper/ +COPY src/Infrastructure.EntityFramework/. ./src/Infrastructure.EntityFramework/ +COPY src/SharedWeb/. ./src/SharedWeb/ +COPY .git/. ./.git/ +COPY .editorconfig /source + +# Build project +WORKDIR /source/src/Notifications +RUN . /tmp/rid.txt && dotnet publish \ + --self-contained \ + /p:PublishSingleFile=true \ + /p:SourceRevisionId="$GIT_COMMIT" \ + -r $RID \ + -o out + +WORKDIR /app + +############################################### +# App stage # +############################################### FROM mcr.microsoft.com/dotnet/aspnet:8.0 +ARG TARGETPLATFORM LABEL com.bitwarden.product="bitwarden" +ENV ASPNETCORE_ENVIRONMENT=Production +ENV ASPNETCORE_URLS=http://+:5000 +EXPOSE 5000 RUN apt-get update \ && apt-get install -y --no-install-recommends \ @@ -8,13 +69,11 @@ RUN apt-get update \ curl \ && rm -rf /var/lib/apt/lists/* -ENV ASPNETCORE_URLS http://+:5000 +# Copy app from the build stage WORKDIR /app -EXPOSE 5000 -COPY obj/build-output/publish . -COPY entrypoint.sh / +COPY --from=build /source/src/Notifications/out /app +COPY ./src/Notifications/entrypoint.sh /entrypoint.sh RUN chmod +x /entrypoint.sh - HEALTHCHECK CMD curl -f http://localhost:5000/alive || exit 1 ENTRYPOINT ["/entrypoint.sh"] diff --git a/src/Notifications/entrypoint.sh b/src/Notifications/entrypoint.sh index e1555b6c50..d95324de2f 100644 --- a/src/Notifications/entrypoint.sh +++ b/src/Notifications/entrypoint.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # Setup @@ -19,24 +19,27 @@ then LGID=65534 fi -# Create user and group +if [ "$(id -u)" = "0" ] +then + # Create user and group -groupadd -o -g $LGID $GROUPNAME >/dev/null 2>&1 || -groupmod -o -g $LGID $GROUPNAME >/dev/null 2>&1 -useradd -o -u $LUID -g $GROUPNAME -s /bin/false $USERNAME >/dev/null 2>&1 || -usermod -o -u $LUID -g $GROUPNAME -s /bin/false $USERNAME >/dev/null 2>&1 -mkhomedir_helper $USERNAME + groupadd -o -g $LGID $GROUPNAME >/dev/null 2>&1 || + groupmod -o -g $LGID $GROUPNAME >/dev/null 2>&1 + useradd -o -u $LUID -g $GROUPNAME -s /bin/false $USERNAME >/dev/null 2>&1 || + usermod -o -u $LUID -g $GROUPNAME -s /bin/false $USERNAME >/dev/null 2>&1 + mkhomedir_helper $USERNAME -# The rest... + # The rest... -chown -R $USERNAME:$GROUPNAME /app -mkdir -p /etc/bitwarden/logs -mkdir -p /etc/bitwarden/ca-certificates -chown -R $USERNAME:$GROUPNAME /etc/bitwarden + chown -R $USERNAME:$GROUPNAME /app + mkdir -p /etc/bitwarden/core + mkdir -p /etc/bitwarden/logs + mkdir -p /etc/bitwarden/ca-certificates + chown -R $USERNAME:$GROUPNAME /etc/bitwarden -if [[ $globalSettings__selfHosted == "true" ]]; then - cp /etc/bitwarden/ca-certificates/*.crt /usr/local/share/ca-certificates/ >/dev/null 2>&1 \ - && update-ca-certificates + gosu_cmd="gosu $USERNAME:$GROUPNAME" +else + gosu_cmd="" fi -exec gosu $USERNAME:$GROUPNAME dotnet /app/Notifications.dll +exec $gosu_cmd /app/Notifications diff --git a/util/Attachments/Dockerfile b/util/Attachments/Dockerfile index 37b23a1b95..89a33e80af 100644 --- a/util/Attachments/Dockerfile +++ b/util/Attachments/Dockerfile @@ -1,16 +1,68 @@ -FROM ghcr.io/bitwarden/server +############################################### +# Build stage # +############################################### +FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:8.0 AS build +# Docker buildx supplies the value for this arg +ARG TARGETPLATFORM + +# Determine proper runtime value for .NET +# We put the value in a file to be read by later layers. +RUN if [ "$TARGETPLATFORM" = "linux/amd64" ]; then \ + RID=linux-x64 ; \ + elif [ "$TARGETPLATFORM" = "linux/arm64" ]; then \ + RID=linux-arm64 ; \ + elif [ "$TARGETPLATFORM" = "linux/arm/v7" ]; then \ + RID=linux-arm ; \ + fi \ + && echo "RID=$RID" > /tmp/rid.txt + +# Copy csproj files as distinct layers +WORKDIR /source +COPY util/Server/*.csproj ./util/Server/ +COPY Directory.Build.props . +COPY .editorconfig . + +# Restore project dependencies and tools +WORKDIR /source/util/Server +RUN . /tmp/rid.txt && dotnet restore -r $RID + +# Copy required project files +WORKDIR /source +COPY util/Server/. ./util/Server/ + +# Build project +WORKDIR /source/util/Server +RUN . /tmp/rid.txt && dotnet publish \ + --self-contained \ + /p:PublishSingleFile=true \ + /p:SourceRevisionId="$GIT_COMMIT" \ + -r $RID \ + -o out + +WORKDIR /app + +############################################### +# App stage # +############################################### +FROM mcr.microsoft.com/dotnet/aspnet:8.0 + +ARG TARGETPLATFORM LABEL com.bitwarden.product="bitwarden" +ENV ASPNETCORE_ENVIRONMENT=Production +ENV ASPNETCORE_URLS=http://+:5000 +EXPOSE 5000 RUN apt-get update \ && apt-get install -y --no-install-recommends \ - gosu \ - curl \ + gosu \ + curl \ && rm -rf /var/lib/apt/lists/* -ENV ASPNETCORE_URLS http://+:5000 -EXPOSE 5000 -COPY entrypoint.sh / +# Copy app from the build stage +WORKDIR /bitwarden_server +COPY --from=build /source/util/Server/out /bitwarden_server +COPY util/Attachments/entrypoint.sh /entrypoint.sh RUN chmod +x /entrypoint.sh HEALTHCHECK CMD curl -f http://localhost:5000/alive || exit 1 diff --git a/util/Attachments/entrypoint.sh b/util/Attachments/entrypoint.sh index 3b50472930..1de574dc43 100644 --- a/util/Attachments/entrypoint.sh +++ b/util/Attachments/entrypoint.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # Setup @@ -19,19 +19,27 @@ then LGID=65534 fi -# Create user and group +if [ "$(id -u)" = "0" ] +then + # Create user and group -groupadd -o -g $LGID $GROUPNAME >/dev/null 2>&1 || -groupmod -o -g $LGID $GROUPNAME >/dev/null 2>&1 -useradd -o -u $LUID -g $GROUPNAME -s /bin/false $USERNAME >/dev/null 2>&1 || -usermod -o -u $LUID -g $GROUPNAME -s /bin/false $USERNAME >/dev/null 2>&1 -mkhomedir_helper $USERNAME + groupadd -o -g $LGID $GROUPNAME >/dev/null 2>&1 || + groupmod -o -g $LGID $GROUPNAME >/dev/null 2>&1 + useradd -o -u $LUID -g $GROUPNAME -s /bin/false $USERNAME >/dev/null 2>&1 || + usermod -o -u $LUID -g $GROUPNAME -s /bin/false $USERNAME >/dev/null 2>&1 + mkhomedir_helper $USERNAME -# The rest... + # The rest... -chown -R $USERNAME:$GROUPNAME /bitwarden_server -mkdir -p /etc/bitwarden/core/attachments -chown -R $USERNAME:$GROUPNAME /etc/bitwarden + chown -R $USERNAME:$GROUPNAME /bitwarden_server + mkdir -p /etc/bitwarden/core/attachments + chown -R $USERNAME:$GROUPNAME /etc/bitwarden + gosu_cmd="gosu $USERNAME:$GROUPNAME" +else + gosu_cmd="" +fi -exec gosu $USERNAME:$GROUPNAME dotnet /bitwarden_server/Server.dll \ - /contentRoot=/etc/bitwarden/core/attachments /webRoot=. /serveUnknown=true +exec $gosu_cmd /bitwarden_server/Server \ + /contentRoot=/etc/bitwarden/core/attachments \ + /webRoot=. \ + /serveUnknown=true diff --git a/util/MsSql/Dockerfile b/util/MsSql/Dockerfile index ab439095f6..3ce7ce33d1 100644 --- a/util/MsSql/Dockerfile +++ b/util/MsSql/Dockerfile @@ -10,9 +10,9 @@ RUN apt-get update \ tzdata \ && rm -rf /var/lib/apt/lists/* -COPY backup-db.sql / -COPY backup-db.sh / -COPY entrypoint.sh / +COPY util/MsSql/backup-db.sql / +COPY util/MsSql/backup-db.sh / +COPY util/MsSql/entrypoint.sh / RUN chmod +x /entrypoint.sh \ && chmod +x /backup-db.sh diff --git a/util/MsSqlMigratorUtility/Dockerfile b/util/MsSqlMigratorUtility/Dockerfile index b3da6a53f0..edc202bc93 100644 --- a/util/MsSqlMigratorUtility/Dockerfile +++ b/util/MsSqlMigratorUtility/Dockerfile @@ -1,8 +1,67 @@ -FROM mcr.microsoft.com/dotnet/aspnet:8.0 +############################################### +# Build stage # +############################################### +FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:8.0 AS build +ARG GIT_COMMIT -LABEL com.bitwarden.product="bitwarden" +# Docker buildx supplies the value for this arg +ARG TARGETPLATFORM + +# Determine proper runtime value for .NET +# We put the value in a file to be read by later layers. +RUN if [ "$TARGETPLATFORM" = "linux/amd64" ]; then \ + RID=linux-x64 ; \ + elif [ "$TARGETPLATFORM" = "linux/arm64" ]; then \ + RID=linux-arm64 ; \ + elif [ "$TARGETPLATFORM" = "linux/arm/v7" ]; then \ + RID=linux-arm ; \ + fi \ + && echo "RID=$RID" > /tmp/rid.txt + +# Copy csproj files as distinct layers +WORKDIR /source +COPY util/MsSqlMigratorUtility/*.csproj ./util/MsSqlMigratorUtility/ +COPY src/Core/*.csproj ./src/Core/ +COPY util/Migrator/*.csproj ./util/Migrator/ +COPY util/Server/*.csproj ./util/Server/ +COPY util/Server/Properties/*.csproj ./util/Server/Properties/ +COPY util/Server/Properties/launchSettings.json ./util/Server/Properties/ +COPY Directory.Build.props . + +# Restore project dependencies and tools +WORKDIR /source/util/MsSqlMigratorUtility +RUN . /tmp/rid.txt && dotnet restore -r $RID + +# Copy required project files +WORKDIR /source +COPY util/MsSqlMigratorUtility/. ./util/MsSqlMigratorUtility/ +COPY src/Core/. ./src/Core/ +COPY util/Migrator/. ./util/Migrator/ +COPY util/Server/. ./util/Server/ +COPY .git/. ./.git/ +COPY .editorconfig /source + +# Build project +WORKDIR /source/util/MsSqlMigratorUtility +RUN . /tmp/rid.txt && dotnet publish \ + --self-contained \ + /p:PublishSingleFile=true \ + /p:SourceRevisionId="$GIT_COMMIT" \ + -r $RID \ + -o out WORKDIR /app -COPY obj/build-output/publish . -ENTRYPOINT ["sh", "-c", "dotnet /app/MsSqlMigratorUtility.dll \"${MSSQL_CONN_STRING}\" ${@}", "--" ] +############################################### +# App stage # +############################################### +FROM mcr.microsoft.com/dotnet/aspnet:8.0 + +ARG TARGETPLATFORM +LABEL com.bitwarden.product="bitwarden" + +# Copy app from the build stage +WORKDIR /app +COPY --from=build /source/util/MsSqlMigratorUtility/out /app + +ENTRYPOINT ["sh", "-c", "/app/MsSqlMigratorUtility \"${MSSQL_CONN_STRING}\" ${@}", "--" ] diff --git a/util/Nginx/Dockerfile b/util/Nginx/Dockerfile index e868e9b81f..acdcfae96a 100644 --- a/util/Nginx/Dockerfile +++ b/util/Nginx/Dockerfile @@ -1,20 +1,21 @@ -FROM nginx:stable +FROM --platform=$BUILDPLATFORM nginx:stable +ARG TARGETPLATFORM LABEL com.bitwarden.product="bitwarden" RUN apt-get update \ && apt-get install -y --no-install-recommends \ - gosu \ - curl \ + gosu \ + curl \ && rm -rf /var/lib/apt/lists/* -COPY nginx.conf /etc/nginx -COPY proxy.conf /etc/nginx -COPY mime.types /etc/nginx -COPY security-headers.conf /etc/nginx -COPY security-headers-ssl.conf /etc/nginx -COPY logrotate.sh / -COPY entrypoint.sh / +COPY util/Nginx/nginx.conf /etc/nginx +COPY util/Nginx/proxy.conf /etc/nginx +COPY util/Nginx/mime.types /etc/nginx +COPY util/Nginx/security-headers.conf /etc/nginx +COPY util/Nginx/security-headers-ssl.conf /etc/nginx +COPY util/Nginx/logrotate.sh / +COPY util/Nginx/entrypoint.sh / EXPOSE 8080 EXPOSE 8443 diff --git a/util/Server/Dockerfile b/util/Server/Dockerfile deleted file mode 100644 index 6755a85284..0000000000 --- a/util/Server/Dockerfile +++ /dev/null @@ -1,5 +0,0 @@ -FROM mcr.microsoft.com/dotnet/aspnet:8.0 - -LABEL com.bitwarden.product="bitwarden" - -COPY obj/build-output/publish /bitwarden_server diff --git a/util/Setup/Dockerfile b/util/Setup/Dockerfile index 0d0b0d7648..7769f52eef 100644 --- a/util/Setup/Dockerfile +++ b/util/Setup/Dockerfile @@ -1,5 +1,58 @@ +############################################### +# Build stage # +############################################### +FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:8.0 AS build +ARG GIT_COMMIT + +# Docker buildx supplies the value for this arg +ARG TARGETPLATFORM + +# Determine proper runtime value for .NET +# We put the value in a file to be read by later layers. +RUN if [ "$TARGETPLATFORM" = "linux/amd64" ]; then \ + RID=linux-x64 ; \ + elif [ "$TARGETPLATFORM" = "linux/arm64" ]; then \ + RID=linux-arm64 ; \ + elif [ "$TARGETPLATFORM" = "linux/arm/v7" ]; then \ + RID=linux-arm ; \ + fi \ + && echo "RID=$RID" > /tmp/rid.txt + +# Copy csproj files as distinct layers +WORKDIR /source +COPY util/Setup/*.csproj ./util/Setup/ +COPY src/Core/*.csproj ./src/Core/ +COPY util/Migrator/*.csproj ./util/Migrator/ +COPY Directory.Build.props . + +# Restore project dependencies and tools +WORKDIR /source/util/Setup +RUN . /tmp/rid.txt && dotnet restore -r $RID + +# Copy required project files +WORKDIR /source +COPY util/Setup/. ./util/Setup/ +COPY src/Core/. ./src/Core/ +COPY util/Migrator/. ./util/Migrator/ +COPY .editorconfig /source + +# Build project +WORKDIR /source/util/Setup +RUN . /tmp/rid.txt && dotnet publish \ + --self-contained \ + /p:PublishSingleFile=true \ + /p:SourceRevisionId="$GIT_COMMIT" \ + -r $RID \ + -o out + +WORKDIR /app + +############################################### +# App stage # +############################################### FROM mcr.microsoft.com/dotnet/aspnet:8.0 +ARG TARGETPLATFORM LABEL com.bitwarden.product="bitwarden" com.bitwarden.project="setup" RUN apt-get update \ @@ -8,9 +61,10 @@ RUN apt-get update \ gosu \ && rm -rf /var/lib/apt/lists/* +# Copy app from the build stage WORKDIR /app -COPY obj/build-output/publish . -COPY entrypoint.sh / +COPY --from=build /source/util/Setup/out . +COPY util/Setup/entrypoint.sh /entrypoint.sh RUN chmod +x /entrypoint.sh ENTRYPOINT ["/entrypoint.sh"]