Refactor lite dockerfile to pull from existing compiled sources (#480)

* Refactor BW lite dockerfile to copy from already compiled sources

* Consolidate RUN steps & add caching to GHA

* Update supervisord configs

* Improve web tag sanitization
Found while testing branches:
- 264-UI
- AC-217-Migrate-Cards-To-Banners
- Ac-1410/update_planresponsemodel_on_client

We need to lowercase and replace "/".

* Tune cache

* Update bitwarden-lite/Dockerfile

Alphabetical ordering

Co-authored-by: Vince Grassia <593223+vgrassia@users.noreply.github.com>

* Update bitwarden-lite/Dockerfile

Alphabetical ordering

Co-authored-by: Vince Grassia <593223+vgrassia@users.noreply.github.com>

---------

Co-authored-by: Vince Grassia <593223+vgrassia@users.noreply.github.com>
This commit is contained in:
MtnBurrit0
2026-04-01 00:58:12 -06:00
committed by GitHub
parent 36730f4e40
commit 08922d41f4
10 changed files with 74 additions and 259 deletions

View File

@@ -5,6 +5,8 @@ on:
paths:
- "bitwarden-lite/**"
- ".github/workflows/build-bitwarden-lite.yml"
branches:
- main
workflow_dispatch:
inputs:
self_host_repo_ref:
@@ -165,66 +167,31 @@ jobs:
echo "Using $IMAGE_TAG for build"
echo "image_tag=${IMAGE_TAG}" >> "$GITHUB_OUTPUT"
- name: Log in to Azure
uses: bitwarden/gh-actions/azure-login@main
with:
subscription_id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
tenant_id: ${{ secrets.AZURE_TENANT_ID }}
client_id: ${{ secrets.AZURE_CLIENT_ID }}
- name: Get Azure Key Vault secrets
id: get-kv-secrets
uses: bitwarden/gh-actions/get-keyvault-secrets@main
with:
keyvault: gh-org-bitwarden
secrets: "BW-GHAPP-ID,BW-GHAPP-KEY"
- name: Log out from Azure
uses: bitwarden/gh-actions/azure-logout@main
- name: Generate GH App token
uses: actions/create-github-app-token@0f859bf9e69e887678d5bbfbee594437cb440ffe # v2.1.0
id: app-token
with:
app-id: ${{ steps.get-kv-secrets.outputs.BW-GHAPP-ID }}
private-key: ${{ steps.get-kv-secrets.outputs.BW-GHAPP-KEY }}
permission-actions: read # for downloading workflow run artifacts
permission-contents: read # for checking out repos
- name: Checkout server repo
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
repository: bitwarden/server
token: ${{ steps.app-token.outputs.token }}
ref: ${{ needs.setup.outputs.server_ref }}
path: "server"
persist-credentials: false
- name: Download web client branch artifacts for dev builds
if: ${{ !inputs.use_latest_web_version }}
uses: bitwarden/gh-actions/download-artifacts@main
with:
github_token: ${{ steps.app-token.outputs.token }}
workflow: build-web.yml
workflow_conclusion: success
branch: ${{ needs.setup.outputs.web_ref }}
repo: bitwarden/clients
artifacts: "web-*-selfhosted-DEV.zip"
if_no_artifact_found: fail
- name: Set web artifact path for dev builds
if: ${{ !inputs.use_latest_web_version }}
id: set-web-artifact-path
run: echo "path=$(find . -name "web-*-selfhosted-DEV.zip" | head -1)" >> "$GITHUB_OUTPUT"
- name: Generate web image tag
id: web-tag
env:
WEB_REF: ${{ needs.setup.outputs.web_ref }}
run: |
if [[ $WEB_REF =~ ^refs/tags/web-v(.+)$ ]]; then
WEB_TAG="${BASH_REMATCH[1]}"
else
WEB_TAG=$(echo "${WEB_REF#refs/heads/}" | \
tr '[:upper:]' '[:lower:]' | \
sed -E 's/[^a-z0-9._-]+/-/g; s/-+/-/g; s/^-+|-+$//g' | \
cut -c1-128 | \
sed -E 's/[.-]$//')
[[ "$WEB_TAG" == "main" ]] && WEB_TAG=dev
fi
echo "web_tag=${WEB_TAG}" >> "$GITHUB_OUTPUT"
- name: Log build configuration
env:
SERVER_REF: ${{ needs.setup.outputs.server_ref }}
WEB_REF: ${{ needs.setup.outputs.web_ref }}
SERVER_TAG: ${{ steps.tag.outputs.image_tag }}
WEB_TAG: ${{ steps.web-tag.outputs.web_tag }}
run: |
echo "### Build Configuration" >> $GITHUB_STEP_SUMMARY
echo "- Server: ${SERVER_REF}" >> $GITHUB_STEP_SUMMARY
echo "- Web: ${WEB_REF}" >> $GITHUB_STEP_SUMMARY
echo "- Server: ghcr.io/bitwarden/\*:${SERVER_TAG}" >> $GITHUB_STEP_SUMMARY
echo "- Web: ghcr.io/bitwarden/web:${WEB_TAG}" >> $GITHUB_STEP_SUMMARY
- name: Build and push Docker image
id: build-docker
@@ -239,7 +206,10 @@ jobs:
push: true
tags: ghcr.io/bitwarden/lite:${{ steps.tag.outputs.image_tag }}
build-args: |
WEB_ARTIFACT_PATH=${{ steps.set-web-artifact-path.outputs.path }}
SERVER_TAG=${{ steps.tag.outputs.image_tag }}
WEB_TAG=${{ steps.web-tag.outputs.web_tag }}
cache-from: type=gha
cache-to: type=gha,mode=min
- name: Install Cosign
uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4.0.0

View File

@@ -1,186 +1,23 @@
# syntax = docker/dockerfile:1.21
###############################################
# Build stage #
###############################################
FROM --platform=$BUILDPLATFORM alpine:3.23 AS web-setup
ARG WEB_ARTIFACT_PATH
# Add packages
RUN apk add --no-cache \
curl \
jq \
unzip \
git
WORKDIR /tmp
# Grab last tag/release of the 'web' client
RUN if [ -z "${WEB_ARTIFACT_PATH}" ]; then \
git ls-remote --tags https://github.com/bitwarden/clients.git \
| grep -E 'refs/tags/web-v[0-9]{4}\.([1-9]|1[0-2])\.[0-9]+' \
| cut -d/ -f3 | sort -Vr | head -1 > tag.txt; \
fi
# Extract the version of the 'web' client
RUN if [ -z "${WEB_ARTIFACT_PATH}" ]; then \
cat tag.txt | grep -o -E '[0-9]{4}\.([1-9]|1[0-2])\.[0-9]+' > version.txt; \
fi
# Download the built release artifact for the 'web' client
RUN if [ -z "${WEB_ARTIFACT_PATH}" ]; then \
TAG=$(cat tag.txt) \
&& VERSION=$(cat version.txt) \
&& curl --proto "=https" -L https://github.com/bitwarden/clients/releases/download/$TAG/web-$VERSION-selfhosted-COMMERCIAL.zip -O; \
fi
# Copy provided web artifact if available
COPY ${WEB_ARTIFACT_PATH}* /tmp/
# Unzip the 'web' client to /tmp/build
RUN if [ -z "${WEB_ARTIFACT_PATH}" ]; then \
VERSION=$(cat version.txt) \
&& unzip web-$VERSION-selfhosted-COMMERCIAL.zip; \
else \
unzip ${WEB_ARTIFACT_PATH} -d /tmp/; \
fi
ARG SERVER_TAG=dev
ARG WEB_TAG=dev
###############################################
# Build stage #
# Web app stage #
###############################################
FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:8.0-alpine3.21 AS dotnet-build
FROM ghcr.io/bitwarden/web:${WEB_TAG} AS web-app
# 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-musl-x64 ; \
elif [ "$TARGETPLATFORM" = "linux/arm64" ]; then \
RID=linux-musl-arm64 ; \
elif [ "$TARGETPLATFORM" = "linux/arm/v7" ]; then \
RID=linux-musl-arm ; \
fi \
&& echo "RID=$RID" > /tmp/rid.txt
# Add packages
RUN apk add --no-cache \
npm
# Copy csproj files as distinct layers
WORKDIR /source
COPY server/src/Admin/*.csproj ./src/Admin/
COPY server/src/Api/*.csproj ./src/Api/
COPY server/src/Events/*.csproj ./src/Events/
COPY server/src/Icons/*.csproj ./src/Icons/
COPY server/src/Identity/*.csproj ./src/Identity/
COPY server/src/Notifications/*.csproj ./src/Notifications/
COPY server/bitwarden_license/src/Sso/*.csproj ./bitwarden_license/src/Sso/
COPY server/bitwarden_license/src/Scim/*.csproj ./bitwarden_license/src/Scim/
COPY server/src/Core/*.csproj ./src/Core/
COPY server/src/Infrastructure.Dapper/*.csproj ./src/Infrastructure.Dapper/
COPY server/src/Infrastructure.EntityFramework/*.csproj ./src/Infrastructure.EntityFramework/
COPY server/src/SharedWeb/*.csproj ./src/SharedWeb/
COPY server/util/Migrator/*.csproj ./util/Migrator/
COPY server/util/MySqlMigrations/*.csproj ./util/MySqlMigrations/
COPY server/util/PostgresMigrations/*.csproj ./util/PostgresMigrations/
COPY server/util/SqliteMigrations/*.csproj ./util/SqliteMigrations/
COPY server/bitwarden_license/src/Commercial.Core/*.csproj ./bitwarden_license/src/Commercial.Core/
COPY server/bitwarden_license/src/Commercial.Infrastructure.EntityFramework/*.csproj ./bitwarden_license/src/Commercial.Infrastructure.EntityFramework/
COPY server/Directory.Build.props .
COPY server/.editorconfig .
COPY server/global.json .
# Restore Admin project dependencies and tools
WORKDIR /source/src/Admin
RUN . /tmp/rid.txt && dotnet restore -r $RID
# Restore Api project dependencies and tools
WORKDIR /source/src/Api
RUN . /tmp/rid.txt && dotnet restore -r $RID
# Restore Events project dependencies and tools
WORKDIR /source/src/Events
RUN . /tmp/rid.txt && dotnet restore -r $RID
# Restore Icons project dependencies and tools
WORKDIR /source/src/Icons
RUN . /tmp/rid.txt && dotnet restore -r $RID
# Restore Identity project dependencies and tools
WORKDIR /source/src/Identity
RUN . /tmp/rid.txt && dotnet restore -r $RID
# Restore Notifications project dependencies and tools
WORKDIR /source/src/Notifications
RUN . /tmp/rid.txt && dotnet restore -r $RID
# Restore Sso project dependencies and tools
WORKDIR /source/bitwarden_license/src/Sso
RUN . /tmp/rid.txt && dotnet restore -r $RID
# Restore Scim project dependencies and tools
WORKDIR /source/bitwarden_license/src/Scim
RUN . /tmp/rid.txt && dotnet restore -r $RID
# Copy required project files
WORKDIR /source
COPY server/src/Admin/. ./src/Admin/
COPY server/src/Api/. ./src/Api/
COPY server/src/Events/. ./src/Events/
COPY server/src/Icons/. ./src/Icons/
COPY server/src/Identity/. ./src/Identity/
COPY server/src/Notifications/. ./src/Notifications/
COPY server/bitwarden_license/src/Sso/. ./bitwarden_license/src/Sso/
COPY server/bitwarden_license/src/Scim/. ./bitwarden_license/src/Scim/
COPY server/src/Core/. ./src/Core/
COPY server/src/Infrastructure.Dapper/. ./src/Infrastructure.Dapper/
COPY server/src/Infrastructure.EntityFramework/. ./src/Infrastructure.EntityFramework/
COPY server/src/SharedWeb/. ./src/SharedWeb/
COPY server/util/Migrator/. ./util/Migrator/
COPY server/util/MySqlMigrations/. ./util/MySqlMigrations/
COPY server/util/PostgresMigrations/. ./util/PostgresMigrations/
COPY server/util/SqliteMigrations/. ./util/SqliteMigrations/
COPY server/util/EfShared/. ./util/EfShared/
COPY server/bitwarden_license/src/Commercial.Core/. ./bitwarden_license/src/Commercial.Core/
COPY server/bitwarden_license/src/Commercial.Infrastructure.EntityFramework/. ./bitwarden_license/src/Commercial.Infrastructure.EntityFramework/
COPY server/.git/. ./.git/
# Build Admin app
WORKDIR /source/src/Admin
RUN npm install
RUN npm run build
RUN . /tmp/rid.txt && dotnet publish -c release -o /app/Admin --no-restore --no-self-contained -r $RID
# Build Api app
WORKDIR /source/src/Api
RUN . /tmp/rid.txt && dotnet publish -c release -o /app/Api --no-restore --no-self-contained -r $RID
# Build Events app
WORKDIR /source/src/Events
RUN . /tmp/rid.txt && dotnet publish -c release -o /app/Events --no-restore --no-self-contained -r $RID
# Build Icons app
WORKDIR /source/src/Icons
RUN . /tmp/rid.txt && dotnet publish -c release -o /app/Icons --no-restore --no-self-contained -r $RID
# Build Identity app
WORKDIR /source/src/Identity
RUN . /tmp/rid.txt && dotnet publish -c release -o /app/Identity --no-restore --no-self-contained -r $RID
# Build Notifications app
WORKDIR /source/src/Notifications
RUN . /tmp/rid.txt && dotnet publish -c release -o /app/Notifications --no-restore --no-self-contained -r $RID
# Build Sso app
WORKDIR /source/bitwarden_license/src/Sso
RUN npm install
RUN npm run build
RUN . /tmp/rid.txt && dotnet publish -c release -o /app/Sso --no-restore --no-self-contained -r $RID
# Build Scim app
WORKDIR /source/bitwarden_license/src/Scim
RUN . /tmp/rid.txt && dotnet publish -c release -o /app/Scim --no-restore --no-self-contained -r $RID
###############################################
# Server app stages #
###############################################
FROM ghcr.io/bitwarden/admin:${SERVER_TAG} AS admin-app
FROM ghcr.io/bitwarden/api:${SERVER_TAG} AS api-app
FROM ghcr.io/bitwarden/events:${SERVER_TAG} AS events-app
FROM ghcr.io/bitwarden/icons:${SERVER_TAG} AS icons-app
FROM ghcr.io/bitwarden/identity:${SERVER_TAG} AS identity-app
FROM ghcr.io/bitwarden/notifications:${SERVER_TAG} AS notifications-app
FROM ghcr.io/bitwarden/scim:${SERVER_TAG} AS scim-app
FROM ghcr.io/bitwarden/sso:${SERVER_TAG} AS sso-app
###############################################
# App stage #
@@ -235,26 +72,34 @@ RUN apk add --no-cache \
gcompat
# Create required directories
RUN mkdir -p /etc/bitwarden/attachments/send
RUN mkdir -p /etc/bitwarden/data-protection
RUN mkdir -p /etc/bitwarden/licenses
RUN mkdir -p /etc/bitwarden/logs
RUN mkdir -p /etc/supervisor
RUN mkdir -p /etc/supervisor.d
RUN mkdir -p /var/log/bitwarden
RUN mkdir -p /var/log/nginx/logs
RUN mkdir -p /etc/nginx/http.d
RUN mkdir -p /var/run/nginx
RUN mkdir -p /var/lib/nginx/tmp
RUN touch /var/run/nginx/nginx.pid
RUN mkdir -p /app
RUN mkdir -p \
/etc/bitwarden/attachments/send \
/etc/bitwarden/data-protection \
/etc/bitwarden/licenses \
/etc/bitwarden/logs \
/etc/supervisor \
/etc/supervisor.d \
/var/log/bitwarden \
/var/log/nginx/logs \
/etc/nginx/http.d \
/var/run/nginx \
/var/lib/nginx/tmp \
/app \
&& touch /var/run/nginx/nginx.pid
# Copy all apps from dotnet-build stage
# Copy compiled apps from server images
WORKDIR /app
COPY --from=dotnet-build /app ./
COPY --from=admin-app /app /app/Admin
COPY --from=api-app /app /app/Api
COPY --from=events-app /app /app/Events
COPY --from=icons-app /app /app/Icons
COPY --from=identity-app /app /app/Identity
COPY --from=notifications-app /app /app/Notifications
COPY --from=scim-app /app /app/Scim
COPY --from=sso-app /app /app/Sso
# Copy Web files from web-setup stage
COPY --from=web-setup /tmp/build /app/Web
# Copy Web files from web-app stage
COPY --from=web-app /app /app/Web
# Set up supervisord
COPY bitwarden-lite/supervisord/*.ini /etc/supervisor.d/

View File

@@ -1,7 +1,7 @@
[program:admin]
autostart=true
autorestart=true
command=/usr/bin/dotnet "Admin.dll"
command=/app/Admin/Admin
directory=/app/Admin
environment=ASPNETCORE_URLS="http://+:5000"
priority=3

View File

@@ -1,7 +1,7 @@
[program:api]
autostart=true
autorestart=true
command=/usr/bin/dotnet "Api.dll"
command=/app/Api/Api
directory=/app/Api
environment=ASPNETCORE_URLS="http://+:5001"
priority=2

View File

@@ -1,7 +1,7 @@
[program:events]
autostart=true
autorestart=true
command=/usr/bin/dotnet "Events.dll"
command=/app/Events/Events
directory=/app/Events
environment=ASPNETCORE_URLS="http://+:5003"
priority=3

View File

@@ -1,7 +1,7 @@
[program:icons]
autostart=true
autorestart=true
command=/usr/bin/dotnet "Icons.dll"
command=/app/Icons/Icons
directory=/app/Icons
environment=ASPNETCORE_URLS="http://+:5004"
priority=3

View File

@@ -1,7 +1,7 @@
[program:identity]
autostart=true
autorestart=true
command=/usr/bin/dotnet "Identity.dll"
command=/app/Identity/Identity
directory=/app/Identity
environment=ASPNETCORE_URLS="http://+:5005"
priority=1

View File

@@ -1,7 +1,7 @@
[program:notifications]
autostart=true
autorestart=true
command=/usr/bin/dotnet "Notifications.dll"
command=/app/Notifications/Notifications
directory=/app/Notifications
environment=ASPNETCORE_URLS="http://+:5006"
priority=3

View File

@@ -1,7 +1,7 @@
[program:scim]
autostart=true
autorestart=true
command=/usr/bin/dotnet "Scim.dll"
command=/app/Scim/Scim
directory=/app/Scim
environment=ASPNETCORE_URLS="http://+:5002"
priority=4

View File

@@ -1,7 +1,7 @@
[program:sso]
autostart=true
autorestart=true
command=/usr/bin/dotnet "Sso.dll"
command=/app/Sso/Sso
directory=/app/Sso
environment=ASPNETCORE_URLS="http://+:5007"
priority=4