From c93be6d52b12599040d3c3d8a7b3bc854c6c6802 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Wed, 23 Apr 2025 11:25:43 -0700 Subject: [PATCH 01/41] Use IHttpMessageHandlerFactory For HTTP Communication Co-authored-by: Justin Baur <19896123+justindbaur@users.noreply.github.com> --- bitwarden_license/src/Scim/Startup.cs | 3 +++ bitwarden_license/src/Sso/Startup.cs | 3 +++ .../DynamicAuthenticationSchemeProvider.cs | 1 + src/Admin/Startup.cs | 3 +++ src/Api/Startup.cs | 3 +++ src/Billing/Startup.cs | 3 +++ src/Events/Startup.cs | 3 +++ src/EventsProcessor/Startup.cs | 3 +++ src/Icons/Startup.cs | 3 +++ src/Identity/Startup.cs | 3 +++ src/Notifications/Startup.cs | 3 +++ .../Utilities/ServiceCollectionExtensions.cs | 23 ++++++++++++++++++- 12 files changed, 53 insertions(+), 1 deletion(-) diff --git a/bitwarden_license/src/Scim/Startup.cs b/bitwarden_license/src/Scim/Startup.cs index 3fac669eda8e..a28aa6dd2377 100644 --- a/bitwarden_license/src/Scim/Startup.cs +++ b/bitwarden_license/src/Scim/Startup.cs @@ -89,6 +89,9 @@ public void ConfigureServices(IServiceCollection services) services.AddScimGroupQueries(); services.AddScimUserQueries(); services.AddScimUserCommands(); + + // This should be registered last because it customizes the primary http message handler and we want it to win. + services.AddX509ChainCustomization(); } public void Configure( diff --git a/bitwarden_license/src/Sso/Startup.cs b/bitwarden_license/src/Sso/Startup.cs index 3aeb9c6beb57..a8f8109cb474 100644 --- a/bitwarden_license/src/Sso/Startup.cs +++ b/bitwarden_license/src/Sso/Startup.cs @@ -86,6 +86,9 @@ public void ConfigureServices(IServiceCollection services) // TODO: Remove when OrganizationUser methods are moved out of OrganizationService, this noop dependency should // TODO: no longer be required - see PM-1880 services.AddScoped(); + + // This should be registered last because it customizes the primary http message handler and we want it to win. + services.AddX509ChainCustomization(); } public void Configure( diff --git a/bitwarden_license/src/Sso/Utilities/DynamicAuthenticationSchemeProvider.cs b/bitwarden_license/src/Sso/Utilities/DynamicAuthenticationSchemeProvider.cs index 8bde8f84a1f3..7ded57188de7 100644 --- a/bitwarden_license/src/Sso/Utilities/DynamicAuthenticationSchemeProvider.cs +++ b/bitwarden_license/src/Sso/Utilities/DynamicAuthenticationSchemeProvider.cs @@ -35,6 +35,7 @@ public class DynamicAuthenticationSchemeProvider : AuthenticationSchemeProvider private readonly Dictionary _cachedHandlerSchemes; private readonly SemaphoreSlim _semaphore; private readonly IServiceProvider _serviceProvider; + private readonly IHttpMessageHandlerFactory _httpMessageHandlerFactory; private DateTime? _lastSchemeLoad; private IEnumerable _schemesCopy = Array.Empty(); diff --git a/src/Admin/Startup.cs b/src/Admin/Startup.cs index 11f9e7ce6846..b4ed9c545734 100644 --- a/src/Admin/Startup.cs +++ b/src/Admin/Startup.cs @@ -129,6 +129,9 @@ public void ConfigureServices(IServiceCollection services) services.AddHostedService(); } } + + // This should be registered last because it customizes the primary http message handler and we want it to win. + services.AddX509ChainCustomization(); } public void Configure( diff --git a/src/Api/Startup.cs b/src/Api/Startup.cs index 2872a5b88b94..8b7613f126b4 100644 --- a/src/Api/Startup.cs +++ b/src/Api/Startup.cs @@ -230,6 +230,9 @@ public void ConfigureServices(IServiceCollection services) { services.AddSingleton(); } + + // This should be registered last because it customizes the primary http message handler and we want it to win. + services.AddX509ChainCustomization(); } public void Configure( diff --git a/src/Billing/Startup.cs b/src/Billing/Startup.cs index afb01f4801c3..89ac840b14c7 100644 --- a/src/Billing/Startup.cs +++ b/src/Billing/Startup.cs @@ -121,6 +121,9 @@ public void ConfigureServices(IServiceCollection services) // Swagger services.AddEndpointsApiExplorer(); services.AddSwaggerGen(); + + // This should be registered last because it customizes the primary http message handler and we want it to win. + services.AddX509ChainCustomization(); } public void Configure( diff --git a/src/Events/Startup.cs b/src/Events/Startup.cs index 34ffed4ee698..83e6a9f46133 100644 --- a/src/Events/Startup.cs +++ b/src/Events/Startup.cs @@ -146,6 +146,9 @@ public void ConfigureServices(IServiceCollection services) globalSettings, globalSettings.EventLogging.RabbitMq.WebhookQueueName)); } + + // This should be registered last because it customizes the primary http message handler and we want it to win. + services.AddX509ChainCustomization(); } public void Configure( diff --git a/src/EventsProcessor/Startup.cs b/src/EventsProcessor/Startup.cs index e397bd326bb6..a3b748a2ad56 100644 --- a/src/EventsProcessor/Startup.cs +++ b/src/EventsProcessor/Startup.cs @@ -82,6 +82,9 @@ public void ConfigureServices(IServiceCollection services) globalSettings.EventLogging.AzureServiceBus.WebhookSubscriptionName)); } services.AddHostedService(); + + // This should be registered last because it customizes the primary http message handler and we want it to win. + services.AddX509ChainCustomization(); } public void Configure( diff --git a/src/Icons/Startup.cs b/src/Icons/Startup.cs index 4695c320e939..a3ed0ddb67e2 100644 --- a/src/Icons/Startup.cs +++ b/src/Icons/Startup.cs @@ -47,6 +47,9 @@ public void ConfigureServices(IServiceCollection services) // Mvc services.AddMvc(); + + // This should be registered last because it customizes the primary http message handler and we want it to win. + services.AddX509ChainCustomization(); } public void Configure( diff --git a/src/Identity/Startup.cs b/src/Identity/Startup.cs index 320c91b24833..8b959deac0d4 100644 --- a/src/Identity/Startup.cs +++ b/src/Identity/Startup.cs @@ -163,6 +163,9 @@ public void ConfigureServices(IServiceCollection services) { client.BaseAddress = new Uri(globalSettings.BaseServiceUri.InternalSso); }); + + // This should be registered last because it customizes the primary http message handler and we want it to win. + services.AddX509ChainCustomization(); } public void Configure( diff --git a/src/Notifications/Startup.cs b/src/Notifications/Startup.cs index 440808b78b35..01856b8ae93f 100644 --- a/src/Notifications/Startup.cs +++ b/src/Notifications/Startup.cs @@ -76,6 +76,9 @@ public void ConfigureServices(IServiceCollection services) services.AddHostedService(); } } + + // This should be registered last because it customizes the primary http message handler and we want it to win. + services.AddX509ChainCustomization(); } public void Configure( diff --git a/src/SharedWeb/Utilities/ServiceCollectionExtensions.cs b/src/SharedWeb/Utilities/ServiceCollectionExtensions.cs index 8d48fc86ef11..e56f125eca0d 100644 --- a/src/SharedWeb/Utilities/ServiceCollectionExtensions.cs +++ b/src/SharedWeb/Utilities/ServiceCollectionExtensions.cs @@ -1,4 +1,5 @@ -using System.Net; +using System.Diagnostics; +using System.Net; using System.Reflection; using System.Security.Claims; using System.Security.Cryptography.X509Certificates; @@ -486,6 +487,8 @@ public static void AddIdentityAuthenticationServices( Action addAuthorization) { services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) + // If we ever use the overload here with a different authentication scheme name then + // we need to change the AddOptions call below. .AddJwtBearer(options => { options.MapInboundClaims = false; @@ -505,6 +508,24 @@ public static void AddIdentityAuthenticationServices( }; }); + // This is done through a Configure method instead of above so that we can avoid + // an early creation of services but still use a service that should centrally control how HttpMessageHandlers + // are created. + services.AddOptions(JwtBearerDefaults.AuthenticationScheme) + .Configure((options, httpMessageHandlerFactory) => + { + // Since we don't manually set the Backchannel and the Post stage configuration shouldn't have + // ran yet we don't expect this option to be set. If it is set, it was likely set with a + // handler already and won't respect the BackchannelHttpHandler we are about to set. + Debug.Assert(options.Backchannel is null); + + // Do a few debug checks to make sure we are customizing the expected options configured above. + Debug.Assert(!options.TokenValidationParameters.ValidateAudience); + Debug.Assert(options.TokenValidationParameters.ValidTypes.Single() == "at+jwt"); + Debug.Assert(options.TokenValidationParameters.NameClaimType == ClaimTypes.Email); + options.BackchannelHttpHandler = httpMessageHandlerFactory.CreateHandler(); + }); + if (addAuthorization != null) { services.AddAuthorization(config => From 3e48c6318d0077ead555d3048537c4c4bf349b16 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Wed, 23 Apr 2025 11:28:23 -0700 Subject: [PATCH 02/41] feat: allow custom app-id.json location for rootless Co-authored-by: Justin Baur <19896123+justindbaur@users.noreply.github.com> --- util/Server/Startup.cs | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/util/Server/Startup.cs b/util/Server/Startup.cs index 7b195beb5347..4eb84d2ad7e8 100644 --- a/util/Server/Startup.cs +++ b/util/Server/Startup.cs @@ -26,7 +26,8 @@ public void ConfigureServices(IServiceCollection services) public void Configure( IApplicationBuilder app, - IConfiguration configuration) + IConfiguration configuration, + ILogger logger) { if (configuration.GetValue("serveUnknown") ?? false) { @@ -44,6 +45,22 @@ public void Configure( } else if (configuration.GetValue("webVault") ?? false) { + var appIdLocation = configuration.GetValue("appIdLocation"); + + if (!string.IsNullOrEmpty(appIdLocation)) + { + app.UseRouting(); + app.UseEndpoints(endpoints => + { + endpoints.MapGet("/app-id.json", async context => + { + var appId = await File.ReadAllTextAsync(appIdLocation); + context.Response.ContentType = "application/json"; + await context.Response.WriteAsync(appId); + }); + }); + } + // TODO: This should be removed when asp.net natively support avif var provider = new FileExtensionContentTypeProvider { Mappings = { [".avif"] = "image/avif" } }; From 5d7025dd99e6d0d09c96bc36e281bb05ce5e8e6c Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Wed, 23 Apr 2025 11:37:42 -0700 Subject: [PATCH 03/41] fix: new build context wont allow copying git context --- Directory.Build.props | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index 16d8d83ae0c5..a9696a532459 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -52,22 +52,4 @@ 4.18.1 - - - - - - - - - - <_Parameter1>GitHash - <_Parameter2>$(SourceRevisionId) - - - - - \ No newline at end of file + 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 04/41] 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 | 97 ++++++++++++++++++++++-- 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 | 40 ++++++---- util/MsSql/Dockerfile | 6 +- util/MsSqlMigratorUtility/Dockerfile | 63 ++++++++++++++- 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 fc12f251469d..000000000000 --- 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 6970dfa7bb05..87cfe9cca554 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 edc3bbe14ae9..41930504d3ba 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 + +if [[ $globalSettings__selfHosted == "true" ]]; then + if [[ -z $globalSettings__identityServer__certificateLocation ]]; then + export globalSettings__identityServer__certificateLocation=/etc/bitwarden/identity/identity.pfx + fi fi -exec gosu $USERNAME:$GROUPNAME dotnet /app/Scim.dll +exec $gosu_cmd /app/Scim diff --git a/bitwarden_license/src/Sso/Dockerfile b/bitwarden_license/src/Sso/Dockerfile index 6970dfa7bb05..b5ff0dfab176 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 2c7bd18b8435..c762659fb384 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 - -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 +if [ "$(id -u)" = "0" ] +then + # Create user and group -# The rest... + 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 -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 + # The rest... -if [[ $globalSettings__selfHosted == "true" ]]; then - cp /etc/bitwarden/identity/identity.pfx /app/identity.pfx -fi + 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 + if [[ -f "/etc/bitwarden/kerberos/bitwarden.keytab" && -f "/etc/bitwarden/kerberos/krb5.conf" ]]; then + chown -R $USERNAME:$GROUPNAME /etc/bitwarden/kerberos + fi -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 + +if [[ $globalSettings__selfHosted == "true" ]]; then + if [[ -z $globalSettings__identityServer__certificateLocation ]]; then + export globalSettings__identityServer__certificateLocation=/etc/bitwarden/identity/identity.pfx + fi fi -exec gosu $USERNAME:$GROUPNAME dotnet /app/Sso.dll +exec $gosu_cmd /app/Sso diff --git a/src/Admin/.dockerignore b/src/Admin/.dockerignore deleted file mode 100644 index fc12f251469d..000000000000 --- 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 79d117681c46..f2810c6c8151 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 +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/Admin/out /app +COPY ./src/Admin/entrypoint.sh /entrypoint.sh RUN chmod +x /entrypoint.sh - -HEALTHCHECK CMD curl -f http://localhost:5000 || exit 1 +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 2c564b1ce675..4d7d238d2520 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 [[ -f "/etc/bitwarden/kerberos/bitwarden.keytab" && -f "/etc/bitwarden/kerberos/krb5.conf" ]]; then + chown -R $USERNAME:$GROUPNAME /etc/bitwarden/kerberos + fi -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/Admin.dll +exec $gosu_cmd /app/Admin diff --git a/src/Api/.dockerignore b/src/Api/.dockerignore deleted file mode 100644 index fc12f251469d..000000000000 --- 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 6970dfa7bb05..6e3ab0e444d0 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 37d117215c44..d89a4648ec99 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 [[ -f "/etc/bitwarden/kerberos/bitwarden.keytab" && -f "/etc/bitwarden/kerberos/krb5.conf" ]]; then + chown -R $USERNAME:$GROUPNAME /etc/bitwarden/kerberos + fi -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/Api.dll +exec $gosu_cmd /app/Api diff --git a/src/Billing/.dockerignore b/src/Billing/.dockerignore deleted file mode 100644 index fc12f251469d..000000000000 --- 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 9abbe164776f..d3e4939a44c2 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 6d98cfa6f6b6..66540416f519 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 2b658c65b3c8..d5b3a13c6251 100644 --- a/src/Core/Settings/GlobalSettings.cs +++ b/src/Core/Settings/GlobalSettings.cs @@ -423,6 +423,7 @@ public class SmtpSettings 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 eebcb0073816..623c0efca6a5 100644 --- a/src/Core/Utilities/CoreHelpers.cs +++ b/src/Core/Utilities/CoreHelpers.cs @@ -660,9 +660,9 @@ public static bool IsCorsOriginAllowed(string origin, GlobalSettings globalSetti { 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 fc12f251469d..000000000000 --- 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 6970dfa7bb05..7fd406eeae87 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 f1bd48e1a38b..92b19195ea4b 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 [[ -f "/etc/bitwarden/kerberos/bitwarden.keytab" && -f "/etc/bitwarden/kerberos/krb5.conf" ]]; then + chown -R $USERNAME:$GROUPNAME /etc/bitwarden/kerberos + fi -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/Events.dll +exec $gosu_cmd /app/Events diff --git a/src/EventsProcessor/Dockerfile b/src/EventsProcessor/Dockerfile index 4344452f652b..4e9c23ac11b0 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 0ae7b82cb576..e0d2dc023050 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 fc12f251469d..000000000000 --- 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 edc1e0905b9a..8b78b8d1f6db 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 9ed16fba2388..c65d3b308d68 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/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/logs -mkdir -p /etc/bitwarden/ca-certificates -chown -R $USERNAME:$GROUPNAME /etc/bitwarden + 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 [[ $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 + 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/Icons.dll +exec $gosu_cmd /app/Icons diff --git a/src/Identity/.dockerignore b/src/Identity/.dockerignore deleted file mode 100644 index fc12f251469d..000000000000 --- 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 050859a496b2..e15c55671ada 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 cf59bee472e2..f5f84cc22073 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 - -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 +if [ "$(id -u)" = "0" ] +then + # Create user and group -# The rest... + 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 -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 + # The rest... -if [[ $globalSettings__selfHosted == "true" ]]; then - cp /etc/bitwarden/identity/identity.pfx /app/identity.pfx -fi + 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 + if [[ -f "/etc/bitwarden/kerberos/bitwarden.keytab" && -f "/etc/bitwarden/kerberos/krb5.conf" ]]; then + chown -R $USERNAME:$GROUPNAME /etc/bitwarden/kerberos + fi -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 + +if [[ $globalSettings__selfHosted == "true" ]]; then + if [[ -z $globalSettings__identityServer__certificateLocation ]]; then + export globalSettings__identityServer__certificateLocation=/etc/bitwarden/identity/identity.pfx + fi fi -exec gosu $USERNAME:$GROUPNAME dotnet /app/Identity.dll +exec $gosu_cmd /app/Identity diff --git a/src/Notifications/.dockerignore b/src/Notifications/.dockerignore deleted file mode 100644 index fc12f251469d..000000000000 --- 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 ae9e693c2a5f..e3d0327cee0b 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 e1555b6c5018..d95324de2f8c 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 37b23a1b9589..89a33e80af85 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 3b5047293083..1de574dc43c5 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 - -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... - -chown -R $USERNAME:$GROUPNAME /bitwarden_server -mkdir -p /etc/bitwarden/core/attachments -chown -R $USERNAME:$GROUPNAME /etc/bitwarden +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 + + # The rest... + + 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 ab439095f6ce..3ce7ce33d1f3 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 b3da6a53f064..edc202bc937e 100644 --- a/util/MsSqlMigratorUtility/Dockerfile +++ b/util/MsSqlMigratorUtility/Dockerfile @@ -1,8 +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 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 + +############################################### +# 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 obj/build-output/publish . +COPY --from=build /source/util/MsSqlMigratorUtility/out /app -ENTRYPOINT ["sh", "-c", "dotnet /app/MsSqlMigratorUtility.dll \"${MSSQL_CONN_STRING}\" ${@}", "--" ] +ENTRYPOINT ["sh", "-c", "/app/MsSqlMigratorUtility \"${MSSQL_CONN_STRING}\" ${@}", "--" ] diff --git a/util/Nginx/Dockerfile b/util/Nginx/Dockerfile index e868e9b81f30..acdcfae96a80 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 6755a8528494..000000000000 --- 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 0d0b0d764876..7769f52eef62 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"] From 3e4639489b6b6c06b5a977a069002fe0c0eb2057 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Wed, 30 Apr 2025 13:27:14 -0700 Subject: [PATCH 05/41] fix: build failures caused by bad merge --- .../Sso/Utilities/DynamicAuthenticationSchemeProvider.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/bitwarden_license/src/Sso/Utilities/DynamicAuthenticationSchemeProvider.cs b/bitwarden_license/src/Sso/Utilities/DynamicAuthenticationSchemeProvider.cs index 7ded57188de7..1dea98531eb9 100644 --- a/bitwarden_license/src/Sso/Utilities/DynamicAuthenticationSchemeProvider.cs +++ b/bitwarden_license/src/Sso/Utilities/DynamicAuthenticationSchemeProvider.cs @@ -36,7 +36,6 @@ public class DynamicAuthenticationSchemeProvider : AuthenticationSchemeProvider private readonly SemaphoreSlim _semaphore; private readonly IServiceProvider _serviceProvider; private readonly IHttpMessageHandlerFactory _httpMessageHandlerFactory; - private DateTime? _lastSchemeLoad; private IEnumerable _schemesCopy = Array.Empty(); private IEnumerable _handlerSchemesCopy = Array.Empty(); @@ -51,7 +50,8 @@ public DynamicAuthenticationSchemeProvider( ILogger logger, GlobalSettings globalSettings, SamlEnvironment samlEnvironment, - IServiceProvider serviceProvider) + IServiceProvider serviceProvider, + IHttpMessageHandlerFactory httpMessageHandlerFactory) : base(options) { _oidcPostConfigureOptions = oidcPostConfigureOptions; @@ -79,6 +79,7 @@ public DynamicAuthenticationSchemeProvider( _cachedHandlerSchemes = new Dictionary(); _semaphore = new SemaphoreSlim(1); _serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider)); + _httpMessageHandlerFactory = httpMessageHandlerFactory; } private bool CacheIsValid @@ -311,6 +312,8 @@ private DynamicAuthenticationScheme GetOidcAuthenticationScheme(string name, Sso // Prevents URLs that go beyond 1024 characters which may break for some servers AuthenticationMethod = config.RedirectBehavior, GetClaimsFromUserInfoEndpoint = config.GetClaimsFromUserInfoEndpoint, + // Make sure all communication goes through the Platform supplied HttpMessageHandler + BackchannelHttpHandler = _httpMessageHandlerFactory.CreateHandler(), }; oidcOptions.Scope .AddIfNotExists(OpenIdConnectScopes.OpenId) From 32c2f6236a894534de09ffe847ffff064a7174bd Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Wed, 30 Apr 2025 13:28:09 -0700 Subject: [PATCH 06/41] build: we don't need to copy the `.git` dir --- bitwarden_license/src/Scim/Dockerfile | 9 +++------ bitwarden_license/src/Sso/Dockerfile | 3 --- src/Admin/Dockerfile | 1 - src/Api/Dockerfile | 1 - src/Billing/Dockerfile | 1 - src/Events/Dockerfile | 1 - src/EventsProcessor/Dockerfile | 1 - src/Icons/Dockerfile | 1 - src/Identity/Dockerfile | 1 - src/Notifications/Dockerfile | 1 - util/MsSqlMigratorUtility/Dockerfile | 1 - 11 files changed, 3 insertions(+), 18 deletions(-) diff --git a/bitwarden_license/src/Scim/Dockerfile b/bitwarden_license/src/Scim/Dockerfile index 87cfe9cca554..b31336b25b7b 100644 --- a/bitwarden_license/src/Scim/Dockerfile +++ b/bitwarden_license/src/Scim/Dockerfile @@ -9,11 +9,11 @@ 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 ; \ + RID=linux-x64 ; \ elif [ "$TARGETPLATFORM" = "linux/arm64" ]; then \ - RID=linux-arm64 ; \ + RID=linux-arm64 ; \ elif [ "$TARGETPLATFORM" = "linux/arm/v7" ]; then \ - RID=linux-arm ; \ + RID=linux-arm ; \ fi \ && echo "RID=$RID" > /tmp/rid.txt @@ -31,8 +31,6 @@ COPY Directory.Build.props . 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 @@ -41,7 +39,6 @@ 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 diff --git a/bitwarden_license/src/Sso/Dockerfile b/bitwarden_license/src/Sso/Dockerfile index b5ff0dfab176..568c8ccbe100 100644 --- a/bitwarden_license/src/Sso/Dockerfile +++ b/bitwarden_license/src/Sso/Dockerfile @@ -31,8 +31,6 @@ COPY Directory.Build.props . 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 @@ -41,7 +39,6 @@ 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 diff --git a/src/Admin/Dockerfile b/src/Admin/Dockerfile index f2810c6c8151..0919f7bb1f19 100644 --- a/src/Admin/Dockerfile +++ b/src/Admin/Dockerfile @@ -62,7 +62,6 @@ 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 diff --git a/src/Api/Dockerfile b/src/Api/Dockerfile index 6e3ab0e444d0..0c6959c7cecc 100644 --- a/src/Api/Dockerfile +++ b/src/Api/Dockerfile @@ -42,7 +42,6 @@ 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 diff --git a/src/Billing/Dockerfile b/src/Billing/Dockerfile index d3e4939a44c2..5b5ac396c54a 100644 --- a/src/Billing/Dockerfile +++ b/src/Billing/Dockerfile @@ -38,7 +38,6 @@ 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 diff --git a/src/Events/Dockerfile b/src/Events/Dockerfile index 7fd406eeae87..a745673e2bfe 100644 --- a/src/Events/Dockerfile +++ b/src/Events/Dockerfile @@ -38,7 +38,6 @@ 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 diff --git a/src/EventsProcessor/Dockerfile b/src/EventsProcessor/Dockerfile index 4e9c23ac11b0..d66c1bf99929 100644 --- a/src/EventsProcessor/Dockerfile +++ b/src/EventsProcessor/Dockerfile @@ -39,7 +39,6 @@ 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 diff --git a/src/Icons/Dockerfile b/src/Icons/Dockerfile index 8b78b8d1f6db..d387d34ee1b1 100644 --- a/src/Icons/Dockerfile +++ b/src/Icons/Dockerfile @@ -37,7 +37,6 @@ 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 diff --git a/src/Identity/Dockerfile b/src/Identity/Dockerfile index e15c55671ada..f4f76df75277 100644 --- a/src/Identity/Dockerfile +++ b/src/Identity/Dockerfile @@ -38,7 +38,6 @@ 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 diff --git a/src/Notifications/Dockerfile b/src/Notifications/Dockerfile index e3d0327cee0b..a588d81a4c08 100644 --- a/src/Notifications/Dockerfile +++ b/src/Notifications/Dockerfile @@ -38,7 +38,6 @@ 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 diff --git a/util/MsSqlMigratorUtility/Dockerfile b/util/MsSqlMigratorUtility/Dockerfile index edc202bc937e..213364b6c40f 100644 --- a/util/MsSqlMigratorUtility/Dockerfile +++ b/util/MsSqlMigratorUtility/Dockerfile @@ -38,7 +38,6 @@ 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 From 7a99f5dc5d84c8bfae4d7449c795545c98c5366d Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Wed, 30 Apr 2025 13:35:38 -0700 Subject: [PATCH 07/41] Revert "build: we don't need to copy the `.git` dir" This reverts commit 32c2f6236a894534de09ffe847ffff064a7174bd. --- bitwarden_license/src/Scim/Dockerfile | 9 ++++++--- bitwarden_license/src/Sso/Dockerfile | 3 +++ src/Admin/Dockerfile | 1 + src/Api/Dockerfile | 1 + src/Billing/Dockerfile | 1 + src/Events/Dockerfile | 1 + src/EventsProcessor/Dockerfile | 1 + src/Icons/Dockerfile | 1 + src/Identity/Dockerfile | 1 + src/Notifications/Dockerfile | 1 + util/MsSqlMigratorUtility/Dockerfile | 1 + 11 files changed, 18 insertions(+), 3 deletions(-) diff --git a/bitwarden_license/src/Scim/Dockerfile b/bitwarden_license/src/Scim/Dockerfile index b31336b25b7b..87cfe9cca554 100644 --- a/bitwarden_license/src/Scim/Dockerfile +++ b/bitwarden_license/src/Scim/Dockerfile @@ -9,11 +9,11 @@ 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 ; \ + RID=linux-x64 ; \ elif [ "$TARGETPLATFORM" = "linux/arm64" ]; then \ - RID=linux-arm64 ; \ + RID=linux-arm64 ; \ elif [ "$TARGETPLATFORM" = "linux/arm/v7" ]; then \ - RID=linux-arm ; \ + RID=linux-arm ; \ fi \ && echo "RID=$RID" > /tmp/rid.txt @@ -31,6 +31,8 @@ COPY Directory.Build.props . 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 @@ -39,6 +41,7 @@ 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 diff --git a/bitwarden_license/src/Sso/Dockerfile b/bitwarden_license/src/Sso/Dockerfile index 568c8ccbe100..b5ff0dfab176 100644 --- a/bitwarden_license/src/Sso/Dockerfile +++ b/bitwarden_license/src/Sso/Dockerfile @@ -31,6 +31,8 @@ COPY Directory.Build.props . 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 @@ -39,6 +41,7 @@ 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 diff --git a/src/Admin/Dockerfile b/src/Admin/Dockerfile index 0919f7bb1f19..f2810c6c8151 100644 --- a/src/Admin/Dockerfile +++ b/src/Admin/Dockerfile @@ -62,6 +62,7 @@ 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 diff --git a/src/Api/Dockerfile b/src/Api/Dockerfile index 0c6959c7cecc..6e3ab0e444d0 100644 --- a/src/Api/Dockerfile +++ b/src/Api/Dockerfile @@ -42,6 +42,7 @@ 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 diff --git a/src/Billing/Dockerfile b/src/Billing/Dockerfile index 5b5ac396c54a..d3e4939a44c2 100644 --- a/src/Billing/Dockerfile +++ b/src/Billing/Dockerfile @@ -38,6 +38,7 @@ 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 diff --git a/src/Events/Dockerfile b/src/Events/Dockerfile index a745673e2bfe..7fd406eeae87 100644 --- a/src/Events/Dockerfile +++ b/src/Events/Dockerfile @@ -38,6 +38,7 @@ 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 diff --git a/src/EventsProcessor/Dockerfile b/src/EventsProcessor/Dockerfile index d66c1bf99929..4e9c23ac11b0 100644 --- a/src/EventsProcessor/Dockerfile +++ b/src/EventsProcessor/Dockerfile @@ -39,6 +39,7 @@ 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 diff --git a/src/Icons/Dockerfile b/src/Icons/Dockerfile index d387d34ee1b1..8b78b8d1f6db 100644 --- a/src/Icons/Dockerfile +++ b/src/Icons/Dockerfile @@ -37,6 +37,7 @@ 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 diff --git a/src/Identity/Dockerfile b/src/Identity/Dockerfile index f4f76df75277..e15c55671ada 100644 --- a/src/Identity/Dockerfile +++ b/src/Identity/Dockerfile @@ -38,6 +38,7 @@ 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 diff --git a/src/Notifications/Dockerfile b/src/Notifications/Dockerfile index a588d81a4c08..e3d0327cee0b 100644 --- a/src/Notifications/Dockerfile +++ b/src/Notifications/Dockerfile @@ -38,6 +38,7 @@ 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 diff --git a/util/MsSqlMigratorUtility/Dockerfile b/util/MsSqlMigratorUtility/Dockerfile index 213364b6c40f..edc202bc937e 100644 --- a/util/MsSqlMigratorUtility/Dockerfile +++ b/util/MsSqlMigratorUtility/Dockerfile @@ -38,6 +38,7 @@ 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 From 284501a4932b819b093406e0bcdf76def22b6eea Mon Sep 17 00:00:00 2001 From: Justin Baur <19896123+justindbaur@users.noreply.github.com> Date: Thu, 1 May 2025 08:59:15 -0400 Subject: [PATCH 08/41] Use `IHttpClientFactory` in more places --- src/Admin/Controllers/HomeController.cs | 8 ++++++-- src/Admin/Jobs/AliveJob.cs | 6 ++++-- src/Api/Tools/Controllers/HibpController.cs | 11 ++++------- src/Billing/Controllers/FreshsalesController.cs | 16 ++++------------ src/Billing/Startup.cs | 10 ++++++++++ .../Controllers/FreshsalesControllerTests.cs | 8 +++++++- util/Setup/Program.cs | 10 +++++++++- 7 files changed, 44 insertions(+), 25 deletions(-) diff --git a/src/Admin/Controllers/HomeController.cs b/src/Admin/Controllers/HomeController.cs index 20c1be70d006..9497be03aa62 100644 --- a/src/Admin/Controllers/HomeController.cs +++ b/src/Admin/Controllers/HomeController.cs @@ -11,13 +11,17 @@ namespace Bit.Admin.Controllers; public class HomeController : Controller { private readonly GlobalSettings _globalSettings; - private readonly HttpClient _httpClient = new HttpClient(); + private readonly HttpClient _httpClient; private readonly ILogger _logger; - public HomeController(GlobalSettings globalSettings, ILogger logger) + public HomeController( + GlobalSettings globalSettings, + ILogger logger, + IHttpClientFactory httpClientFactory) { _globalSettings = globalSettings; _logger = logger; + _httpClient = httpClientFactory.CreateClient(); } [Authorize] diff --git a/src/Admin/Jobs/AliveJob.cs b/src/Admin/Jobs/AliveJob.cs index b97d597e58ca..2e8de4327587 100644 --- a/src/Admin/Jobs/AliveJob.cs +++ b/src/Admin/Jobs/AliveJob.cs @@ -8,14 +8,16 @@ namespace Bit.Admin.Jobs; public class AliveJob : BaseJob { private readonly GlobalSettings _globalSettings; - private HttpClient _httpClient = new HttpClient(); + private readonly HttpClient _httpClient; public AliveJob( GlobalSettings globalSettings, - ILogger logger) + ILogger logger, + IHttpClientFactory httpClientFactory) : base(logger) { _globalSettings = globalSettings; + _httpClient = httpClientFactory.CreateClient(); } protected async override Task ExecuteJobAsync(IJobExecutionContext context) diff --git a/src/Api/Tools/Controllers/HibpController.cs b/src/Api/Tools/Controllers/HibpController.cs index f12027cb312a..0d05b94e7ed8 100644 --- a/src/Api/Tools/Controllers/HibpController.cs +++ b/src/Api/Tools/Controllers/HibpController.cs @@ -16,27 +16,24 @@ public class HibpController : Controller { private const string HibpBreachApi = "https://haveibeenpwned.com/api/v3/breachedaccount/{0}" + "?truncateResponse=false&includeUnverified=false"; - private static HttpClient _httpClient; + private readonly HttpClient _httpClient; private readonly IUserService _userService; private readonly ICurrentContext _currentContext; private readonly GlobalSettings _globalSettings; private readonly string _userAgent; - static HibpController() - { - _httpClient = new HttpClient(); - } - public HibpController( IUserService userService, ICurrentContext currentContext, - GlobalSettings globalSettings) + GlobalSettings globalSettings, + IHttpClientFactory httpClientFactory) { _userService = userService; _currentContext = currentContext; _globalSettings = globalSettings; _userAgent = _globalSettings.SelfHosted ? "Bitwarden Self-Hosted" : "Bitwarden"; + _httpClient = httpClientFactory.CreateClient(); } [HttpGet("breach")] diff --git a/src/Billing/Controllers/FreshsalesController.cs b/src/Billing/Controllers/FreshsalesController.cs index 0182011d7a3c..d825a2d07132 100644 --- a/src/Billing/Controllers/FreshsalesController.cs +++ b/src/Billing/Controllers/FreshsalesController.cs @@ -1,5 +1,4 @@ -using System.Net.Http.Headers; -using System.Text.Json.Serialization; +using System.Text.Json.Serialization; using Bit.Core.Billing.Enums; using Bit.Core.Repositories; using Bit.Core.Settings; @@ -25,23 +24,16 @@ public FreshsalesController(IUserRepository userRepository, IOrganizationRepository organizationRepository, IOptions billingSettings, ILogger logger, - GlobalSettings globalSettings) + GlobalSettings globalSettings, + IHttpClientFactory httpClientFactory) { _userRepository = userRepository; _organizationRepository = organizationRepository; _logger = logger; _globalSettings = globalSettings; - - _httpClient = new HttpClient - { - BaseAddress = new Uri("https://bitwarden.freshsales.io/api/") - }; + _httpClient = httpClientFactory.CreateClient("Freshsales"); _freshsalesApiKey = billingSettings.Value.FreshsalesApiKey; - - _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue( - "Token", - $"token={_freshsalesApiKey}"); } diff --git a/src/Billing/Startup.cs b/src/Billing/Startup.cs index 89ac840b14c7..e6b2ac03e9bf 100644 --- a/src/Billing/Startup.cs +++ b/src/Billing/Startup.cs @@ -10,6 +10,7 @@ using Bit.Core.Utilities; using Bit.SharedWeb.Utilities; using Microsoft.Extensions.DependencyInjection.Extensions; +using Microsoft.Extensions.Options; using Quartz; using Stripe; @@ -102,6 +103,15 @@ public void ConfigureServices(IServiceCollection services) { client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", billingSettings.Onyx.ApiKey); }); + services.AddHttpClient("Freshsales", (sp, client) => + { + var billingSettings = sp.GetRequiredService>().Value; + client.BaseAddress = new Uri("https://bitwarden.freshsales.io/api/"); + client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue( + "Token", + $"token={billingSettings.FreshsalesApiKey}" + ); + }); services.AddScoped(); services.AddScoped(); diff --git a/test/Billing.Test/Controllers/FreshsalesControllerTests.cs b/test/Billing.Test/Controllers/FreshsalesControllerTests.cs index c9ae6efb1a1b..c9eb8c8e40c7 100644 --- a/test/Billing.Test/Controllers/FreshsalesControllerTests.cs +++ b/test/Billing.Test/Controllers/FreshsalesControllerTests.cs @@ -31,12 +31,18 @@ private static (FreshsalesController, IUserRepository, IOrganizationRepository) var globalSettings = new GlobalSettings(); globalSettings.BaseServiceUri.Admin = "https://test.com"; + var httpClientFactory = Substitute.For(); + httpClientFactory + .CreateClient("Freshsales") + .Returns(new HttpClient()); + var sut = new FreshsalesController( userRepository, organizationRepository, billingSettings, Substitute.For>(), - globalSettings + globalSettings, + httpClientFactory ); return (sut, userRepository, organizationRepository); diff --git a/util/Setup/Program.cs b/util/Setup/Program.cs index 50f3046d6d7c..bb857a327618 100644 --- a/util/Setup/Program.cs +++ b/util/Setup/Program.cs @@ -2,6 +2,7 @@ using System.Net.Http.Json; using Bit.Migrator; using Bit.Setup.Enums; +using Microsoft.Extensions.DependencyInjection; namespace Bit.Setup; @@ -285,7 +286,14 @@ private static bool ValidateInstallation() url = $"{installationUrl}/installations/"; } - var response = new HttpClient().GetAsync(url + _context.Install.InstallationId).GetAwaiter().GetResult(); + // We need to get an HttpClient that has been configured with custom trust certificates. + var httpClient = new ServiceCollection() + .AddX509ChainCustomization() + .BuildServiceProvider() + .GetRequiredService() + .CreateClient(); + + var response = httpClient.GetAsync(url + _context.Install.InstallationId).GetAwaiter().GetResult(); if (!response.IsSuccessStatusCode) { From 192b058f743f4ac7d0bdeb7bb3e7833fc5ce71dc Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Thu, 1 May 2025 07:55:39 -0700 Subject: [PATCH 09/41] update build workflow --- .github/workflows/build.yml | 298 ++++++++++++++---------------------- 1 file changed, 116 insertions(+), 182 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 33edd075a00e..d67ba7ce08f5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -18,7 +18,7 @@ env: jobs: lint: name: Lint - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - name: Check out repo uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 @@ -31,11 +31,12 @@ jobs: - name: Verify format run: dotnet format --verify-no-changes - build-artifacts: - name: Build artifacts - runs-on: ubuntu-22.04 - needs: - - lint + build-container: + name: Build container images + runs-on: ubuntu-24.04 + permissions: + id-token: write + security-events: write outputs: has_secrets: ${{ steps.check-secrets.outputs.has_secrets }} strategy: @@ -44,9 +45,10 @@ jobs: include: - project_name: Admin base_path: ./src - node: true - project_name: Api base_path: ./src + - project_name: Attachments + base_path: ./util - project_name: Billing base_path: ./src - project_name: Events @@ -57,21 +59,20 @@ jobs: base_path: ./src - project_name: Identity base_path: ./src + - project_name: MsSql + base_path: ./util - project_name: MsSqlMigratorUtility base_path: ./util - dotnet: true + - project_name: Nginx + base_path: ./util - project_name: Notifications base_path: ./src - project_name: Scim base_path: ./bitwarden_license/src - dotnet: true - - project_name: Server - base_path: ./util - project_name: Setup base_path: ./util - project_name: Sso base_path: ./bitwarden_license/src - node: true steps: - name: Check secrets id: check-secrets @@ -86,116 +87,6 @@ jobs: with: ref: ${{ github.event.pull_request.head.sha }} - - name: Set up .NET - uses: actions/setup-dotnet@87b7050bc53ea08284295505d98d2aa94301e852 # v4.2.0 - - - name: Set up Node - uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 - with: - cache: "npm" - cache-dependency-path: "**/package-lock.json" - node-version: "16" - - - name: Print environment - run: | - whoami - dotnet --info - node --version - npm --version - echo "GitHub ref: $GITHUB_REF" - echo "GitHub event: $GITHUB_EVENT" - - - name: Build node - if: ${{ matrix.node }} - working-directory: ${{ matrix.base_path }}/${{ matrix.project_name }} - run: | - npm ci - npm run build - - - name: Publish project - working-directory: ${{ matrix.base_path }}/${{ matrix.project_name }} - run: | - echo "Publish" - dotnet publish -c "Release" -o obj/build-output/publish - - cd obj/build-output/publish - zip -r ${{ matrix.project_name }}.zip . - mv ${{ matrix.project_name }}.zip ../../../ - - pwd - ls -atlh ../../../ - - - name: Upload project artifact - uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 - with: - name: ${{ matrix.project_name }}.zip - path: ${{ matrix.base_path }}/${{ matrix.project_name }}/${{ matrix.project_name }}.zip - if-no-files-found: error - - build-docker: - name: Build Docker images - runs-on: ubuntu-22.04 - permissions: - security-events: write - id-token: write - needs: - - build-artifacts - if: ${{ needs.build-artifacts.outputs.has_secrets == 'true' }} - strategy: - fail-fast: false - matrix: - include: - - project_name: Admin - base_path: ./src - dotnet: true - - project_name: Api - base_path: ./src - dotnet: true - - project_name: Attachments - base_path: ./util - - project_name: Billing - base_path: ./src - dotnet: true - - project_name: Events - base_path: ./src - dotnet: true - - project_name: EventsProcessor - base_path: ./src - dotnet: true - - project_name: Icons - base_path: ./src - dotnet: true - - project_name: Identity - base_path: ./src - dotnet: true - - project_name: MsSql - base_path: ./util - - project_name: MsSqlMigratorUtility - base_path: ./util - dotnet: true - - project_name: Nginx - base_path: ./util - - project_name: Notifications - base_path: ./src - dotnet: true - - project_name: Scim - base_path: ./bitwarden_license/src - dotnet: true - - project_name: Server - base_path: ./util - dotnet: true - - project_name: Setup - base_path: ./util - dotnet: true - - project_name: Sso - base_path: ./bitwarden_license/src - dotnet: true - steps: - - name: Check out repo - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - ref: ${{ github.event.pull_request.head.sha }} - - name: Check branch to publish env: PUBLISH_BRANCHES: "main,rc,hotfix-rc" @@ -209,6 +100,20 @@ jobs: echo "is_publish_branch=false" >> $GITHUB_ENV fi + ########## Set up Docker ########## + - name: Set up QEMU emulators + uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v3.0.0 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0 + + ########## Set up Docker ########## + - name: Set up QEMU emulators + uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v3.0.0 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0 + ########## ACRs ########## - name: Log in to Azure - production subscription uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 @@ -218,20 +123,8 @@ jobs: - name: Log in to ACR - production subscription run: az acr login -n bitwardenprod - - name: Log in to Azure - CI subscription - uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 - with: - creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} - - - name: Retrieve GitHub PAT secrets - id: retrieve-secret-pat - uses: bitwarden/gh-actions/get-keyvault-secrets@main - with: - keyvault: "bitwarden-ci" - secrets: "github-pat-bitwarden-devops-bot-repo-scope" - - ########## Generate image tag and build Docker image ########## - - name: Generate Docker image tag + ########## Generate image tag and build container image ########## + - name: Generate container image tag id: tag run: | if [[ "${GITHUB_EVENT_NAME}" == "pull_request" ]]; then @@ -245,7 +138,7 @@ jobs: fi echo "image_tag=$IMAGE_TAG" >> $GITHUB_OUTPUT - echo "### :mega: Docker Image Tag: $IMAGE_TAG" >> $GITHUB_STEP_SUMMARY + echo "### :mega: Container Image Tag: $IMAGE_TAG" >> $GITHUB_STEP_SUMMARY - name: Set up project name id: setup @@ -270,30 +163,26 @@ jobs: fi echo "tags=$TAGS" >> $GITHUB_OUTPUT - - name: Get build artifact - if: ${{ matrix.dotnet }} - uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 - with: - name: ${{ matrix.project_name }}.zip - - - name: Set up build artifact - if: ${{ matrix.dotnet }} - run: | - mkdir -p ${{ matrix.base_path}}/${{ matrix.project_name }}/obj/build-output/publish - unzip ${{ matrix.project_name }}.zip \ - -d ${{ matrix.base_path }}/${{ matrix.project_name }}/obj/build-output/publish + - name: Generate image full name + id: cache-name + env: + PROJECT_NAME: ${{ steps.setup.outputs.project_name }} + run: echo "name=${_AZ_REGISTRY}/${PROJECT_NAME}:buildcache" >> $GITHUB_OUTPUT - - name: Build Docker image - id: build-docker + - name: Build Container image + id: build-container uses: docker/build-push-action@67a2d409c0a876cbe6b11854e3e25193efe4e62d # v6.12.0 with: - context: ${{ matrix.base_path }}/${{ matrix.project_name }} + cache-from: type=registry,ref=${{ steps.cache-name.outputs.name }} + cache-to: type=registry,ref=${{ steps.cache-name.outputs.name}},mode=max + context: . file: ${{ matrix.base_path }}/${{ matrix.project_name }}/Dockerfile - platforms: linux/amd64 + platforms: | + linux/amd64, + linux/arm/v7, + linux/arm64 push: true tags: ${{ steps.image-tags.outputs.tags }} - secrets: | - "GH_PAT=${{ steps.retrieve-secret-pat.outputs.github-pat-bitwarden-devops-bot-repo-scope }}" - name: Install Cosign if: github.event_name != 'pull_request' && github.ref == 'refs/heads/main' @@ -302,7 +191,7 @@ jobs: - name: Sign image with Cosign if: github.event_name != 'pull_request' && github.ref == 'refs/heads/main' env: - DIGEST: ${{ steps.build-docker.outputs.digest }} + DIGEST: ${{ steps.build-container.outputs.digest }} TAGS: ${{ steps.image-tags.outputs.tags }} run: | IFS="," read -a tags <<< "${TAGS}" @@ -312,7 +201,7 @@ jobs: done cosign sign --yes ${images} - - name: Scan Docker image + - name: Scan container image id: container-scan uses: anchore/scan-action@abae793926ec39a78ab18002bc7fc45bbbd94342 # v6.0.0 with: @@ -327,10 +216,10 @@ jobs: sha: ${{ contains(github.event_name, 'pull_request') && github.event.pull_request.head.sha || github.sha }} ref: ${{ contains(github.event_name, 'pull_request') && format('refs/pull/{0}/head', github.event.pull_request.number) || github.ref }} - upload: - name: Upload - runs-on: ubuntu-22.04 - needs: build-docker + build-stub-swagger: + name: Build Docker-Stub/Swagger + runs-on: ubuntu-24.04 + needs: build-container steps: - name: Check out repo uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 @@ -345,8 +234,11 @@ jobs: with: creds: ${{ secrets.AZURE_PROD_KV_CREDENTIALS }} - - name: Log in to ACR - production subscription - run: az acr login -n $_AZ_REGISTRY --only-show-errors + - name: Login to PROD ACR + run: az acr login -n ${_AZ_REGISTRY%.azurecr.io} + + - name: Restore + run: dotnet tool restore - name: Make Docker stubs if: | @@ -441,8 +333,10 @@ jobs: - name: Build Public API Swagger run: | cd ./src/Api - echo "Restore tools" - dotnet tool restore + echo "Restore" + dotnet restore --locked-mode + echo "Clean" + dotnet clean -c "Release" -o obj/build-output/publish echo "Publish" dotnet publish -c "Release" -o obj/build-output/publish @@ -505,9 +399,7 @@ jobs: build-mssqlmigratorutility: name: Build MSSQL migrator utility - runs-on: ubuntu-22.04 - needs: - - lint + runs-on: ubuntu-24.04 defaults: run: shell: bash @@ -535,6 +427,11 @@ jobs: echo "GitHub ref: $GITHUB_REF" echo "GitHub event: $GITHUB_EVENT" + - name: Restore project + run: | + echo "Restore" + dotnet restore --locked-mode + - name: Publish project run: | dotnet publish -c "Release" -o obj/build-output/publish -r ${{ matrix.target }} -p:PublishSingleFile=true \ @@ -561,9 +458,8 @@ jobs: if: | github.event_name != 'pull_request' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/rc' || github.ref == 'refs/heads/hotfix-rc') - runs-on: ubuntu-22.04 - needs: - - build-docker + runs-on: ubuntu-24.04 + needs: build-container steps: - name: Log in to Azure - CI subscription uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 @@ -595,9 +491,8 @@ jobs: trigger-k8s-deploy: name: Trigger k8s deploy if: github.event_name != 'pull_request' && github.ref == 'refs/heads/main' - runs-on: ubuntu-22.04 - needs: - - build-docker + runs-on: ubuntu-24.04 + needs: build-container steps: - name: Log in to Azure - CI subscription uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 @@ -627,11 +522,49 @@ jobs: } }) - setup-ephemeral-environment: - name: Setup Ephemeral Environment - needs: build-docker + trigger-ee-updates: + name: Trigger Ephemeral Environment updates + if: | + needs.build-container.outputs.has_secrets == 'true' + && github.event_name == 'pull_request' + && contains(github.event.pull_request.labels.*.name, 'ephemeral-environment') + runs-on: ubuntu-24.04 + needs: build-container + steps: + - name: Log in to Azure - CI subscription + uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 + with: + creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} + + - name: Retrieve GitHub PAT secrets + id: retrieve-secret-pat + uses: bitwarden/gh-actions/get-keyvault-secrets@main + with: + keyvault: "bitwarden-ci" + secrets: "github-pat-bitwarden-devops-bot-repo-scope" + + - name: Trigger Ephemeral Environment update + uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 + with: + github-token: ${{ steps.retrieve-secret-pat.outputs.github-pat-bitwarden-devops-bot-repo-scope }} + script: | + await github.rest.actions.createWorkflowDispatch({ + owner: 'bitwarden', + repo: 'devops', + workflow_id: '_update_ephemeral_tags.yml', + ref: 'main', + inputs: { + ephemeral_env_branch: process.env.GITHUB_HEAD_REF + } + }) + + trigger-ephemeral-environment-sync: + name: Trigger Ephemeral Environment Sync + needs: + - build-container + - trigger-ee-updates if: | - needs.build-artifacts.outputs.has_secrets == 'true' + needs.build-container.outputs.has_secrets == 'true' && github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'ephemeral-environment') uses: bitwarden/gh-actions/.github/workflows/_ephemeral_environment_manager.yml@main @@ -643,15 +576,16 @@ jobs: check-failures: name: Check for failures if: always() - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 needs: - lint - - build-artifacts - - build-docker - - upload + - build-container + - build-stub-swagger - build-mssqlmigratorutility - self-host-build - trigger-k8s-deploy + - trigger-ee-updates + - trigger-ephemeral-environment-sync steps: - name: Check if any job failed if: | From 948a79952f06b75e939c87aeece0942b6d47ae05 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Fri, 2 May 2025 08:39:22 -0700 Subject: [PATCH 10/41] fix: compatibility with the existin run.sh script --- util/Setup/Dockerfile | 1 - 1 file changed, 1 deletion(-) diff --git a/util/Setup/Dockerfile b/util/Setup/Dockerfile index 7769f52eef62..6266405d9de9 100644 --- a/util/Setup/Dockerfile +++ b/util/Setup/Dockerfile @@ -40,7 +40,6 @@ COPY .editorconfig /source WORKDIR /source/util/Setup RUN . /tmp/rid.txt && dotnet publish \ --self-contained \ - /p:PublishSingleFile=true \ /p:SourceRevisionId="$GIT_COMMIT" \ -r $RID \ -o out From b30edc541660bb0b1af797cb9724e9697f14bc3e Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Fri, 2 May 2025 08:39:43 -0700 Subject: [PATCH 11/41] fix: compatibility with existing run.sh script --- util/Setup/entrypoint.sh | 50 +++++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/util/Setup/entrypoint.sh b/util/Setup/entrypoint.sh index c034894e716c..0d81192f3c00 100644 --- a/util/Setup/entrypoint.sh +++ b/util/Setup/entrypoint.sh @@ -19,27 +19,29 @@ then LGID=65534 fi -# 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 - -# The rest... - -chown -R $USERNAME:$GROUPNAME /app -mkdir -p /bitwarden/env -mkdir -p /bitwarden/docker -mkdir -p /bitwarden/ssl -mkdir -p /bitwarden/letsencrypt -mkdir -p /bitwarden/identity -mkdir -p /bitwarden/nginx -mkdir -p /bitwarden/ca-certificates -chown -R $USERNAME:$GROUPNAME /bitwarden - -cp /bitwarden/ca-certificates/*.crt /usr/local/share/ca-certificates/ >/dev/null 2>&1 \ - && update-ca-certificates - -exec gosu $USERNAME:$GROUPNAME "$@" +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 + + # The rest... + + chown -R $USERNAME:$GROUPNAME /app + mkdir -p /bitwarden/env + mkdir -p /bitwarden/docker + mkdir -p /bitwarden/ssl + mkdir -p /bitwarden/letsencrypt + mkdir -p /bitwarden/identity + mkdir -p /bitwarden/nginx + mkdir -p /bitwarden/ca-certificates + chown -R $USERNAME:$GROUPNAME /bitwarden +else + gosu_cmd="" +fi + +exec $gosu_cmd "$@" From 69082bab8aa106a1d895e8e9ba1a652acd851556 Mon Sep 17 00:00:00 2001 From: Justin Baur <19896123+justindbaur@users.noreply.github.com> Date: Fri, 2 May 2025 16:18:58 -0400 Subject: [PATCH 12/41] Add SelfHosted GlobalSettings for Setup --- util/Setup/Program.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/util/Setup/Program.cs b/util/Setup/Program.cs index bb857a327618..5bf335fd4acd 100644 --- a/util/Setup/Program.cs +++ b/util/Setup/Program.cs @@ -289,6 +289,8 @@ private static bool ValidateInstallation() // We need to get an HttpClient that has been configured with custom trust certificates. var httpClient = new ServiceCollection() .AddX509ChainCustomization() + // Setup is always ran for self hosted, so it's fine to hard code this to true and allow chain customization + .AddSingleton(new GlobalSettings { SelfHosted = true }) .BuildServiceProvider() .GetRequiredService() .CreateClient(); From 49ad409999cee2ea741f230a238c3aa4ed52df7f Mon Sep 17 00:00:00 2001 From: Justin Baur <19896123+justindbaur@users.noreply.github.com> Date: Fri, 2 May 2025 16:50:41 -0400 Subject: [PATCH 13/41] Fix my build error --- util/Setup/Program.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/util/Setup/Program.cs b/util/Setup/Program.cs index 5bf335fd4acd..2249774a1d7e 100644 --- a/util/Setup/Program.cs +++ b/util/Setup/Program.cs @@ -1,5 +1,6 @@ using System.Globalization; using System.Net.Http.Json; +using Bit.Core.Settings; using Bit.Migrator; using Bit.Setup.Enums; using Microsoft.Extensions.DependencyInjection; From acae59429bfa4df0841a1cbdaebcf6df46c52b20 Mon Sep 17 00:00:00 2001 From: Justin Baur <19896123+justindbaur@users.noreply.github.com> Date: Sat, 3 May 2025 14:10:28 -0400 Subject: [PATCH 14/41] Add other services --- util/Setup/Program.cs | 10 ++++++++-- util/Setup/SetupHostEnvironment.cs | 12 ++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 util/Setup/SetupHostEnvironment.cs diff --git a/util/Setup/Program.cs b/util/Setup/Program.cs index 2249774a1d7e..25062e6bbeef 100644 --- a/util/Setup/Program.cs +++ b/util/Setup/Program.cs @@ -4,6 +4,7 @@ using Bit.Migrator; using Bit.Setup.Enums; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; namespace Bit.Setup; @@ -292,6 +293,8 @@ private static bool ValidateInstallation() .AddX509ChainCustomization() // Setup is always ran for self hosted, so it's fine to hard code this to true and allow chain customization .AddSingleton(new GlobalSettings { SelfHosted = true }) + .AddLogging() + .AddSingleton(new SetupHostEnvironment()) .BuildServiceProvider() .GetRequiredService() .CreateClient(); @@ -321,9 +324,12 @@ private static bool ValidateInstallation() return true; } - catch + catch (Exception ex) { - Console.WriteLine($"Unable to validate installation id. Problem contacting Bitwarden {cloudRegion.ToString()} server."); + // TODO: Remove exception message before main merge?? + Console.WriteLine( + $"Unable to validate installation id. Problem contacting Bitwarden {cloudRegion.ToString()} server.\nError: {ex.Message}" + ); return false; } } diff --git a/util/Setup/SetupHostEnvironment.cs b/util/Setup/SetupHostEnvironment.cs new file mode 100644 index 000000000000..97e088741afb --- /dev/null +++ b/util/Setup/SetupHostEnvironment.cs @@ -0,0 +1,12 @@ +using Microsoft.Extensions.FileProviders; +using Microsoft.Extensions.Hosting; + +namespace Bit.Setup; + +internal class SetupHostEnvironment : IHostEnvironment +{ + public string ApplicationName { get; set; } = "Setup"; + public IFileProvider ContentRootFileProvider { get; set; } = new NullFileProvider(); + public string ContentRootPath { get; set; } = string.Empty; + public string EnvironmentName { get; set; } = "Production"; +} From 2ec431557cf74e0c049f2238508f0d4524e60080 Mon Sep 17 00:00:00 2001 From: Justin Baur <19896123+justindbaur@users.noreply.github.com> Date: Mon, 5 May 2025 15:54:07 -0400 Subject: [PATCH 15/41] Add IConfiguration --- util/Setup/Program.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/util/Setup/Program.cs b/util/Setup/Program.cs index 25062e6bbeef..d3fca08a9eb8 100644 --- a/util/Setup/Program.cs +++ b/util/Setup/Program.cs @@ -3,6 +3,7 @@ using Bit.Core.Settings; using Bit.Migrator; using Bit.Setup.Enums; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; @@ -288,9 +289,20 @@ private static bool ValidateInstallation() url = $"{installationUrl}/installations/"; } + var config = new ConfigurationBuilder() + .AddInMemoryCollection(new Dictionary + { + // Setup uses a different default location for the location of the CA certificates. + ["X509ChainOptions:AdditionalCustomTrustCertificatesDirectory"] = "/bitwarden/ca-certificates", + }) + // Still allow customization through environment variables though + .AddEnvironmentVariables() + .Build(); + // We need to get an HttpClient that has been configured with custom trust certificates. var httpClient = new ServiceCollection() .AddX509ChainCustomization() + .AddSingleton(config) // Setup is always ran for self hosted, so it's fine to hard code this to true and allow chain customization .AddSingleton(new GlobalSettings { SelfHosted = true }) .AddLogging() From 0ad1f2f5fbdcab8d1e6352a21aae77514e1dcb26 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Mon, 5 May 2025 13:25:45 -0700 Subject: [PATCH 16/41] fix: missing gosu command for rootful mode --- util/Setup/entrypoint.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/util/Setup/entrypoint.sh b/util/Setup/entrypoint.sh index 0d81192f3c00..b981d760a9f8 100644 --- a/util/Setup/entrypoint.sh +++ b/util/Setup/entrypoint.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # Setup @@ -40,6 +40,8 @@ then mkdir -p /bitwarden/nginx mkdir -p /bitwarden/ca-certificates chown -R $USERNAME:$GROUPNAME /bitwarden + + gosu_cmd="gosu $USERNAME:$GROUPNAME" else gosu_cmd="" fi From b6322dd764c409426e5889208b8c0d1c8f4aec8f Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Tue, 6 May 2025 10:12:23 -0700 Subject: [PATCH 17/41] fix: try using .net core certificate handling --- bitwarden_license/src/Scim/Dockerfile | 1 + bitwarden_license/src/Sso/Dockerfile | 1 + src/Admin/Dockerfile | 3 +-- src/Api/Dockerfile | 1 + src/Billing/Dockerfile | 1 + src/Events/Dockerfile | 1 + src/EventsProcessor/Dockerfile | 1 + src/Icons/Dockerfile | 1 + src/Identity/Dockerfile | 1 + src/Notifications/Dockerfile | 1 + util/Attachments/Dockerfile | 1 + 11 files changed, 11 insertions(+), 2 deletions(-) diff --git a/bitwarden_license/src/Scim/Dockerfile b/bitwarden_license/src/Scim/Dockerfile index 87cfe9cca554..356003559658 100644 --- a/bitwarden_license/src/Scim/Dockerfile +++ b/bitwarden_license/src/Scim/Dockerfile @@ -65,6 +65,7 @@ ARG TARGETPLATFORM LABEL com.bitwarden.product="bitwarden" ENV ASPNETCORE_ENVIRONMENT=Production ENV ASPNETCORE_URLS=http://+:5000 +ENV SSL_CERT_DIR=/etc/bitwarden/ca-certificates EXPOSE 5000 RUN apt-get update \ diff --git a/bitwarden_license/src/Sso/Dockerfile b/bitwarden_license/src/Sso/Dockerfile index b5ff0dfab176..d75d1ca50369 100644 --- a/bitwarden_license/src/Sso/Dockerfile +++ b/bitwarden_license/src/Sso/Dockerfile @@ -65,6 +65,7 @@ ARG TARGETPLATFORM LABEL com.bitwarden.product="bitwarden" ENV ASPNETCORE_ENVIRONMENT=Production ENV ASPNETCORE_URLS=http://+:5000 +ENV SSL_CERT_DIR=/etc/bitwarden/ca-certificates EXPOSE 5000 RUN apt-get update \ diff --git a/src/Admin/Dockerfile b/src/Admin/Dockerfile index f2810c6c8151..8c74c1928961 100644 --- a/src/Admin/Dockerfile +++ b/src/Admin/Dockerfile @@ -83,6 +83,7 @@ LABEL com.bitwarden.product="bitwarden" EXPOSE 5000 ENV ASPNETCORE_URLS=http://+:5000 +ENV SSL_CERT_DIR=/etc/bitwarden/ca-certificates RUN apt-get update \ && apt-get install -y --no-install-recommends \ @@ -90,8 +91,6 @@ RUN apt-get update \ curl \ && rm -rf /var/lib/apt/lists/* -ENV ASPNETCORE_URLS=http://+:5000 - # Copy app from the build stage WORKDIR /app COPY --from=build /source/src/Admin/out /app diff --git a/src/Api/Dockerfile b/src/Api/Dockerfile index 6e3ab0e444d0..3a3aafbfcd48 100644 --- a/src/Api/Dockerfile +++ b/src/Api/Dockerfile @@ -65,6 +65,7 @@ ARG TARGETPLATFORM LABEL com.bitwarden.product="bitwarden" ENV ASPNETCORE_ENVIRONMENT=Production ENV ASPNETCORE_URLS=http://+:5000 +ENV SSL_CERT_DIR=/etc/bitwarden/ca-certificates EXPOSE 5000 RUN apt-get update \ diff --git a/src/Billing/Dockerfile b/src/Billing/Dockerfile index d3e4939a44c2..1eef72733fc6 100644 --- a/src/Billing/Dockerfile +++ b/src/Billing/Dockerfile @@ -61,6 +61,7 @@ ARG TARGETPLATFORM LABEL com.bitwarden.product="bitwarden" ENV ASPNETCORE_ENVIRONMENT=Production ENV ASPNETCORE_URLS=http://+:5000 +ENV SSL_CERT_DIR=/etc/bitwarden/ca-certificates EXPOSE 5000 RUN apt-get update \ diff --git a/src/Events/Dockerfile b/src/Events/Dockerfile index 7fd406eeae87..72d8e0a83390 100644 --- a/src/Events/Dockerfile +++ b/src/Events/Dockerfile @@ -61,6 +61,7 @@ ARG TARGETPLATFORM LABEL com.bitwarden.product="bitwarden" ENV ASPNETCORE_ENVIRONMENT=Production ENV ASPNETCORE_URLS=http://+:5000 +ENV SSL_CERT_DIR=/etc/bitwarden/ca-certificates EXPOSE 5000 RUN apt-get update \ diff --git a/src/EventsProcessor/Dockerfile b/src/EventsProcessor/Dockerfile index 4e9c23ac11b0..5bb4fd34a230 100644 --- a/src/EventsProcessor/Dockerfile +++ b/src/EventsProcessor/Dockerfile @@ -62,6 +62,7 @@ ARG TARGETPLATFORM LABEL com.bitwarden.product="bitwarden" ENV ASPNETCORE_ENVIRONMENT=Production ENV ASPNETCORE_URLS=http://+:5000 +ENV SSL_CERT_DIR=/etc/bitwarden/ca-certificates EXPOSE 5000 RUN apt-get update \ diff --git a/src/Icons/Dockerfile b/src/Icons/Dockerfile index 8b78b8d1f6db..eb844c646458 100644 --- a/src/Icons/Dockerfile +++ b/src/Icons/Dockerfile @@ -60,6 +60,7 @@ ARG TARGETPLATFORM LABEL com.bitwarden.product="bitwarden" ENV ASPNETCORE_ENVIRONMENT=Production ENV ASPNETCORE_URLS=http://+:5000 +ENV SSL_CERT_DIR=/etc/bitwarden/ca-certificates EXPOSE 5000 RUN apt-get update \ diff --git a/src/Identity/Dockerfile b/src/Identity/Dockerfile index e15c55671ada..62439c82071e 100644 --- a/src/Identity/Dockerfile +++ b/src/Identity/Dockerfile @@ -61,6 +61,7 @@ ARG TARGETPLATFORM LABEL com.bitwarden.product="bitwarden" ENV ASPNETCORE_ENVIRONMENT=Production ENV ASPNETCORE_URLS=http://+:5000 +ENV SSL_CERT_DIR=/etc/bitwarden/ca-certificates EXPOSE 5000 RUN apt-get update \ diff --git a/src/Notifications/Dockerfile b/src/Notifications/Dockerfile index e3d0327cee0b..8179e6be0414 100644 --- a/src/Notifications/Dockerfile +++ b/src/Notifications/Dockerfile @@ -61,6 +61,7 @@ ARG TARGETPLATFORM LABEL com.bitwarden.product="bitwarden" ENV ASPNETCORE_ENVIRONMENT=Production ENV ASPNETCORE_URLS=http://+:5000 +ENV SSL_CERT_DIR=/etc/bitwarden/ca-certificates EXPOSE 5000 RUN apt-get update \ diff --git a/util/Attachments/Dockerfile b/util/Attachments/Dockerfile index 89a33e80af85..4bdfc43e76ab 100644 --- a/util/Attachments/Dockerfile +++ b/util/Attachments/Dockerfile @@ -51,6 +51,7 @@ ARG TARGETPLATFORM LABEL com.bitwarden.product="bitwarden" ENV ASPNETCORE_ENVIRONMENT=Production ENV ASPNETCORE_URLS=http://+:5000 +ENV SSL_CERT_DIR=/etc/bitwarden/ca-certificates EXPOSE 5000 RUN apt-get update \ From 05e58cb9e45a6723b8e6931ddfa516f37b8f6829 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Tue, 6 May 2025 10:22:32 -0700 Subject: [PATCH 18/41] fix: add `SSL_CERT_DIR` to remaining images --- util/MsSqlMigratorUtility/Dockerfile | 2 ++ util/Nginx/Dockerfile | 2 ++ util/Setup/Dockerfile | 2 ++ 3 files changed, 6 insertions(+) diff --git a/util/MsSqlMigratorUtility/Dockerfile b/util/MsSqlMigratorUtility/Dockerfile index edc202bc937e..eab9bf8b65c7 100644 --- a/util/MsSqlMigratorUtility/Dockerfile +++ b/util/MsSqlMigratorUtility/Dockerfile @@ -60,6 +60,8 @@ FROM mcr.microsoft.com/dotnet/aspnet:8.0 ARG TARGETPLATFORM LABEL com.bitwarden.product="bitwarden" +ENV SSL_CERT_DIR=/etc/bitwarden/ca-certificates + # Copy app from the build stage WORKDIR /app COPY --from=build /source/util/MsSqlMigratorUtility/out /app diff --git a/util/Nginx/Dockerfile b/util/Nginx/Dockerfile index acdcfae96a80..d0d05b0bf7ac 100644 --- a/util/Nginx/Dockerfile +++ b/util/Nginx/Dockerfile @@ -3,6 +3,8 @@ FROM --platform=$BUILDPLATFORM nginx:stable ARG TARGETPLATFORM LABEL com.bitwarden.product="bitwarden" +ENV SSL_CERT_DIR=/etc/bitwarden/ca-certificates + RUN apt-get update \ && apt-get install -y --no-install-recommends \ gosu \ diff --git a/util/Setup/Dockerfile b/util/Setup/Dockerfile index 6266405d9de9..d43ecac38f6b 100644 --- a/util/Setup/Dockerfile +++ b/util/Setup/Dockerfile @@ -54,6 +54,8 @@ FROM mcr.microsoft.com/dotnet/aspnet:8.0 ARG TARGETPLATFORM LABEL com.bitwarden.product="bitwarden" com.bitwarden.project="setup" +ENV SSL_CERT_DIR=/etc/bitwarden/ca-certificates + RUN apt-get update \ && apt-get install -y --no-install-recommends \ openssl \ From b1efa88c6dfe56f969e008fe6dc6407aed0c1d42 Mon Sep 17 00:00:00 2001 From: Justin Baur <19896123+justindbaur@users.noreply.github.com> Date: Tue, 6 May 2025 13:39:10 -0400 Subject: [PATCH 19/41] Remove X509ChainCustomization activation code --- bitwarden_license/src/Scim/Startup.cs | 3 --- bitwarden_license/src/Sso/Startup.cs | 3 --- src/Admin/Startup.cs | 3 --- src/Api/Startup.cs | 3 --- src/Billing/Startup.cs | 3 --- src/Events/Startup.cs | 3 --- src/EventsProcessor/Startup.cs | 3 --- src/Icons/Startup.cs | 3 --- src/Identity/Startup.cs | 3 --- src/Notifications/Startup.cs | 3 --- util/Setup/Program.cs | 29 ++------------------------- 11 files changed, 2 insertions(+), 57 deletions(-) diff --git a/bitwarden_license/src/Scim/Startup.cs b/bitwarden_license/src/Scim/Startup.cs index a28aa6dd2377..3fac669eda8e 100644 --- a/bitwarden_license/src/Scim/Startup.cs +++ b/bitwarden_license/src/Scim/Startup.cs @@ -89,9 +89,6 @@ public void ConfigureServices(IServiceCollection services) services.AddScimGroupQueries(); services.AddScimUserQueries(); services.AddScimUserCommands(); - - // This should be registered last because it customizes the primary http message handler and we want it to win. - services.AddX509ChainCustomization(); } public void Configure( diff --git a/bitwarden_license/src/Sso/Startup.cs b/bitwarden_license/src/Sso/Startup.cs index a8f8109cb474..3aeb9c6beb57 100644 --- a/bitwarden_license/src/Sso/Startup.cs +++ b/bitwarden_license/src/Sso/Startup.cs @@ -86,9 +86,6 @@ public void ConfigureServices(IServiceCollection services) // TODO: Remove when OrganizationUser methods are moved out of OrganizationService, this noop dependency should // TODO: no longer be required - see PM-1880 services.AddScoped(); - - // This should be registered last because it customizes the primary http message handler and we want it to win. - services.AddX509ChainCustomization(); } public void Configure( diff --git a/src/Admin/Startup.cs b/src/Admin/Startup.cs index b4ed9c545734..11f9e7ce6846 100644 --- a/src/Admin/Startup.cs +++ b/src/Admin/Startup.cs @@ -129,9 +129,6 @@ public void ConfigureServices(IServiceCollection services) services.AddHostedService(); } } - - // This should be registered last because it customizes the primary http message handler and we want it to win. - services.AddX509ChainCustomization(); } public void Configure( diff --git a/src/Api/Startup.cs b/src/Api/Startup.cs index 1a46eef01596..1cc371ae1b54 100644 --- a/src/Api/Startup.cs +++ b/src/Api/Startup.cs @@ -234,9 +234,6 @@ public void ConfigureServices(IServiceCollection services) { services.AddSingleton(); } - - // This should be registered last because it customizes the primary http message handler and we want it to win. - services.AddX509ChainCustomization(); } public void Configure( diff --git a/src/Billing/Startup.cs b/src/Billing/Startup.cs index e6b2ac03e9bf..63ed23c3d25f 100644 --- a/src/Billing/Startup.cs +++ b/src/Billing/Startup.cs @@ -131,9 +131,6 @@ public void ConfigureServices(IServiceCollection services) // Swagger services.AddEndpointsApiExplorer(); services.AddSwaggerGen(); - - // This should be registered last because it customizes the primary http message handler and we want it to win. - services.AddX509ChainCustomization(); } public void Configure( diff --git a/src/Events/Startup.cs b/src/Events/Startup.cs index 7c93ffc98741..366b56248571 100644 --- a/src/Events/Startup.cs +++ b/src/Events/Startup.cs @@ -152,9 +152,6 @@ public void ConfigureServices(IServiceCollection services) globalSettings, globalSettings.EventLogging.RabbitMq.WebhookQueueName)); } - - // This should be registered last because it customizes the primary http message handler and we want it to win. - services.AddX509ChainCustomization(); } public void Configure( diff --git a/src/EventsProcessor/Startup.cs b/src/EventsProcessor/Startup.cs index a3b748a2ad56..e397bd326bb6 100644 --- a/src/EventsProcessor/Startup.cs +++ b/src/EventsProcessor/Startup.cs @@ -82,9 +82,6 @@ public void ConfigureServices(IServiceCollection services) globalSettings.EventLogging.AzureServiceBus.WebhookSubscriptionName)); } services.AddHostedService(); - - // This should be registered last because it customizes the primary http message handler and we want it to win. - services.AddX509ChainCustomization(); } public void Configure( diff --git a/src/Icons/Startup.cs b/src/Icons/Startup.cs index a3ed0ddb67e2..4695c320e939 100644 --- a/src/Icons/Startup.cs +++ b/src/Icons/Startup.cs @@ -47,9 +47,6 @@ public void ConfigureServices(IServiceCollection services) // Mvc services.AddMvc(); - - // This should be registered last because it customizes the primary http message handler and we want it to win. - services.AddX509ChainCustomization(); } public void Configure( diff --git a/src/Identity/Startup.cs b/src/Identity/Startup.cs index 8b959deac0d4..320c91b24833 100644 --- a/src/Identity/Startup.cs +++ b/src/Identity/Startup.cs @@ -163,9 +163,6 @@ public void ConfigureServices(IServiceCollection services) { client.BaseAddress = new Uri(globalSettings.BaseServiceUri.InternalSso); }); - - // This should be registered last because it customizes the primary http message handler and we want it to win. - services.AddX509ChainCustomization(); } public void Configure( diff --git a/src/Notifications/Startup.cs b/src/Notifications/Startup.cs index 01856b8ae93f..440808b78b35 100644 --- a/src/Notifications/Startup.cs +++ b/src/Notifications/Startup.cs @@ -76,9 +76,6 @@ public void ConfigureServices(IServiceCollection services) services.AddHostedService(); } } - - // This should be registered last because it customizes the primary http message handler and we want it to win. - services.AddX509ChainCustomization(); } public void Configure( diff --git a/util/Setup/Program.cs b/util/Setup/Program.cs index d3fca08a9eb8..68f5447c5f59 100644 --- a/util/Setup/Program.cs +++ b/util/Setup/Program.cs @@ -1,11 +1,7 @@ using System.Globalization; using System.Net.Http.Json; -using Bit.Core.Settings; using Bit.Migrator; using Bit.Setup.Enums; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; namespace Bit.Setup; @@ -289,29 +285,8 @@ private static bool ValidateInstallation() url = $"{installationUrl}/installations/"; } - var config = new ConfigurationBuilder() - .AddInMemoryCollection(new Dictionary - { - // Setup uses a different default location for the location of the CA certificates. - ["X509ChainOptions:AdditionalCustomTrustCertificatesDirectory"] = "/bitwarden/ca-certificates", - }) - // Still allow customization through environment variables though - .AddEnvironmentVariables() - .Build(); - - // We need to get an HttpClient that has been configured with custom trust certificates. - var httpClient = new ServiceCollection() - .AddX509ChainCustomization() - .AddSingleton(config) - // Setup is always ran for self hosted, so it's fine to hard code this to true and allow chain customization - .AddSingleton(new GlobalSettings { SelfHosted = true }) - .AddLogging() - .AddSingleton(new SetupHostEnvironment()) - .BuildServiceProvider() - .GetRequiredService() - .CreateClient(); - - var response = httpClient.GetAsync(url + _context.Install.InstallationId).GetAwaiter().GetResult(); + + var response = new HttpClient().GetAsync(url + _context.Install.InstallationId).GetAwaiter().GetResult(); if (!response.IsSuccessStatusCode) { From 5909f6ef8e20f6cf2b37eef54591108800df1527 Mon Sep 17 00:00:00 2001 From: Justin Baur <19896123+justindbaur@users.noreply.github.com> Date: Wed, 7 May 2025 16:51:51 -0400 Subject: [PATCH 20/41] Revert "Use IHttpMessageHandlerFactory For HTTP Communication" This reverts commit c93be6d52b12599040d3c3d8a7b3bc854c6c6802. --- .../DynamicAuthenticationSchemeProvider.cs | 1 - .../Utilities/ServiceCollectionExtensions.cs | 23 +------------------ 2 files changed, 1 insertion(+), 23 deletions(-) diff --git a/bitwarden_license/src/Sso/Utilities/DynamicAuthenticationSchemeProvider.cs b/bitwarden_license/src/Sso/Utilities/DynamicAuthenticationSchemeProvider.cs index 1dea98531eb9..424f91f9b7a4 100644 --- a/bitwarden_license/src/Sso/Utilities/DynamicAuthenticationSchemeProvider.cs +++ b/bitwarden_license/src/Sso/Utilities/DynamicAuthenticationSchemeProvider.cs @@ -35,7 +35,6 @@ public class DynamicAuthenticationSchemeProvider : AuthenticationSchemeProvider private readonly Dictionary _cachedHandlerSchemes; private readonly SemaphoreSlim _semaphore; private readonly IServiceProvider _serviceProvider; - private readonly IHttpMessageHandlerFactory _httpMessageHandlerFactory; private DateTime? _lastSchemeLoad; private IEnumerable _schemesCopy = Array.Empty(); private IEnumerable _handlerSchemesCopy = Array.Empty(); diff --git a/src/SharedWeb/Utilities/ServiceCollectionExtensions.cs b/src/SharedWeb/Utilities/ServiceCollectionExtensions.cs index 0fa37e96e59c..26e5c7abaf72 100644 --- a/src/SharedWeb/Utilities/ServiceCollectionExtensions.cs +++ b/src/SharedWeb/Utilities/ServiceCollectionExtensions.cs @@ -1,5 +1,4 @@ -using System.Diagnostics; -using System.Net; +using System.Net; using System.Reflection; using System.Security.Claims; using System.Security.Cryptography.X509Certificates; @@ -493,8 +492,6 @@ public static void AddIdentityAuthenticationServices( Action addAuthorization) { services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) - // If we ever use the overload here with a different authentication scheme name then - // we need to change the AddOptions call below. .AddJwtBearer(options => { options.MapInboundClaims = false; @@ -514,24 +511,6 @@ public static void AddIdentityAuthenticationServices( }; }); - // This is done through a Configure method instead of above so that we can avoid - // an early creation of services but still use a service that should centrally control how HttpMessageHandlers - // are created. - services.AddOptions(JwtBearerDefaults.AuthenticationScheme) - .Configure((options, httpMessageHandlerFactory) => - { - // Since we don't manually set the Backchannel and the Post stage configuration shouldn't have - // ran yet we don't expect this option to be set. If it is set, it was likely set with a - // handler already and won't respect the BackchannelHttpHandler we are about to set. - Debug.Assert(options.Backchannel is null); - - // Do a few debug checks to make sure we are customizing the expected options configured above. - Debug.Assert(!options.TokenValidationParameters.ValidateAudience); - Debug.Assert(options.TokenValidationParameters.ValidTypes.Single() == "at+jwt"); - Debug.Assert(options.TokenValidationParameters.NameClaimType == ClaimTypes.Email); - options.BackchannelHttpHandler = httpMessageHandlerFactory.CreateHandler(); - }); - if (addAuthorization != null) { services.AddAuthorization(config => From 4fe99ab6baaa9c8b6f26d49b41fad2a8ed878cab Mon Sep 17 00:00:00 2001 From: Justin Baur <19896123+justindbaur@users.noreply.github.com> Date: Wed, 7 May 2025 16:52:18 -0400 Subject: [PATCH 21/41] Revert "fix: build failures caused by bad merge" This reverts commit 3e4639489b6b6c06b5a977a069002fe0c0eb2057. --- .../Sso/Utilities/DynamicAuthenticationSchemeProvider.cs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/bitwarden_license/src/Sso/Utilities/DynamicAuthenticationSchemeProvider.cs b/bitwarden_license/src/Sso/Utilities/DynamicAuthenticationSchemeProvider.cs index 424f91f9b7a4..8bde8f84a1f3 100644 --- a/bitwarden_license/src/Sso/Utilities/DynamicAuthenticationSchemeProvider.cs +++ b/bitwarden_license/src/Sso/Utilities/DynamicAuthenticationSchemeProvider.cs @@ -35,6 +35,7 @@ public class DynamicAuthenticationSchemeProvider : AuthenticationSchemeProvider private readonly Dictionary _cachedHandlerSchemes; private readonly SemaphoreSlim _semaphore; private readonly IServiceProvider _serviceProvider; + private DateTime? _lastSchemeLoad; private IEnumerable _schemesCopy = Array.Empty(); private IEnumerable _handlerSchemesCopy = Array.Empty(); @@ -49,8 +50,7 @@ public DynamicAuthenticationSchemeProvider( ILogger logger, GlobalSettings globalSettings, SamlEnvironment samlEnvironment, - IServiceProvider serviceProvider, - IHttpMessageHandlerFactory httpMessageHandlerFactory) + IServiceProvider serviceProvider) : base(options) { _oidcPostConfigureOptions = oidcPostConfigureOptions; @@ -78,7 +78,6 @@ public DynamicAuthenticationSchemeProvider( _cachedHandlerSchemes = new Dictionary(); _semaphore = new SemaphoreSlim(1); _serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider)); - _httpMessageHandlerFactory = httpMessageHandlerFactory; } private bool CacheIsValid @@ -311,8 +310,6 @@ private DynamicAuthenticationScheme GetOidcAuthenticationScheme(string name, Sso // Prevents URLs that go beyond 1024 characters which may break for some servers AuthenticationMethod = config.RedirectBehavior, GetClaimsFromUserInfoEndpoint = config.GetClaimsFromUserInfoEndpoint, - // Make sure all communication goes through the Platform supplied HttpMessageHandler - BackchannelHttpHandler = _httpMessageHandlerFactory.CreateHandler(), }; oidcOptions.Scope .AddIfNotExists(OpenIdConnectScopes.OpenId) From 5fedad91a3c218e2e431abecc6c9e9972d202c51 Mon Sep 17 00:00:00 2001 From: Justin Baur <19896123+justindbaur@users.noreply.github.com> Date: Wed, 7 May 2025 16:53:31 -0400 Subject: [PATCH 22/41] Revert "Use `IHttpClientFactory` in more places" This reverts commit 284501a4932b819b093406e0bcdf76def22b6eea. --- src/Admin/Controllers/HomeController.cs | 8 ++------ src/Admin/Jobs/AliveJob.cs | 6 ++---- src/Api/Dirt/Controllers/HibpController.cs | 11 +++++++---- src/Billing/Controllers/FreshsalesController.cs | 16 ++++++++++++---- src/Billing/Startup.cs | 10 ---------- .../Controllers/FreshsalesControllerTests.cs | 8 +------- util/Setup/Program.cs | 1 - 7 files changed, 24 insertions(+), 36 deletions(-) diff --git a/src/Admin/Controllers/HomeController.cs b/src/Admin/Controllers/HomeController.cs index 9497be03aa62..20c1be70d006 100644 --- a/src/Admin/Controllers/HomeController.cs +++ b/src/Admin/Controllers/HomeController.cs @@ -11,17 +11,13 @@ namespace Bit.Admin.Controllers; public class HomeController : Controller { private readonly GlobalSettings _globalSettings; - private readonly HttpClient _httpClient; + private readonly HttpClient _httpClient = new HttpClient(); private readonly ILogger _logger; - public HomeController( - GlobalSettings globalSettings, - ILogger logger, - IHttpClientFactory httpClientFactory) + public HomeController(GlobalSettings globalSettings, ILogger logger) { _globalSettings = globalSettings; _logger = logger; - _httpClient = httpClientFactory.CreateClient(); } [Authorize] diff --git a/src/Admin/Jobs/AliveJob.cs b/src/Admin/Jobs/AliveJob.cs index 2e8de4327587..b97d597e58ca 100644 --- a/src/Admin/Jobs/AliveJob.cs +++ b/src/Admin/Jobs/AliveJob.cs @@ -8,16 +8,14 @@ namespace Bit.Admin.Jobs; public class AliveJob : BaseJob { private readonly GlobalSettings _globalSettings; - private readonly HttpClient _httpClient; + private HttpClient _httpClient = new HttpClient(); public AliveJob( GlobalSettings globalSettings, - ILogger logger, - IHttpClientFactory httpClientFactory) + ILogger logger) : base(logger) { _globalSettings = globalSettings; - _httpClient = httpClientFactory.CreateClient(); } protected async override Task ExecuteJobAsync(IJobExecutionContext context) diff --git a/src/Api/Dirt/Controllers/HibpController.cs b/src/Api/Dirt/Controllers/HibpController.cs index 0d05b94e7ed8..f12027cb312a 100644 --- a/src/Api/Dirt/Controllers/HibpController.cs +++ b/src/Api/Dirt/Controllers/HibpController.cs @@ -16,24 +16,27 @@ public class HibpController : Controller { private const string HibpBreachApi = "https://haveibeenpwned.com/api/v3/breachedaccount/{0}" + "?truncateResponse=false&includeUnverified=false"; - private readonly HttpClient _httpClient; + private static HttpClient _httpClient; private readonly IUserService _userService; private readonly ICurrentContext _currentContext; private readonly GlobalSettings _globalSettings; private readonly string _userAgent; + static HibpController() + { + _httpClient = new HttpClient(); + } + public HibpController( IUserService userService, ICurrentContext currentContext, - GlobalSettings globalSettings, - IHttpClientFactory httpClientFactory) + GlobalSettings globalSettings) { _userService = userService; _currentContext = currentContext; _globalSettings = globalSettings; _userAgent = _globalSettings.SelfHosted ? "Bitwarden Self-Hosted" : "Bitwarden"; - _httpClient = httpClientFactory.CreateClient(); } [HttpGet("breach")] diff --git a/src/Billing/Controllers/FreshsalesController.cs b/src/Billing/Controllers/FreshsalesController.cs index d825a2d07132..0182011d7a3c 100644 --- a/src/Billing/Controllers/FreshsalesController.cs +++ b/src/Billing/Controllers/FreshsalesController.cs @@ -1,4 +1,5 @@ -using System.Text.Json.Serialization; +using System.Net.Http.Headers; +using System.Text.Json.Serialization; using Bit.Core.Billing.Enums; using Bit.Core.Repositories; using Bit.Core.Settings; @@ -24,16 +25,23 @@ public FreshsalesController(IUserRepository userRepository, IOrganizationRepository organizationRepository, IOptions billingSettings, ILogger logger, - GlobalSettings globalSettings, - IHttpClientFactory httpClientFactory) + GlobalSettings globalSettings) { _userRepository = userRepository; _organizationRepository = organizationRepository; _logger = logger; _globalSettings = globalSettings; - _httpClient = httpClientFactory.CreateClient("Freshsales"); + + _httpClient = new HttpClient + { + BaseAddress = new Uri("https://bitwarden.freshsales.io/api/") + }; _freshsalesApiKey = billingSettings.Value.FreshsalesApiKey; + + _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue( + "Token", + $"token={_freshsalesApiKey}"); } diff --git a/src/Billing/Startup.cs b/src/Billing/Startup.cs index 63ed23c3d25f..afb01f4801c3 100644 --- a/src/Billing/Startup.cs +++ b/src/Billing/Startup.cs @@ -10,7 +10,6 @@ using Bit.Core.Utilities; using Bit.SharedWeb.Utilities; using Microsoft.Extensions.DependencyInjection.Extensions; -using Microsoft.Extensions.Options; using Quartz; using Stripe; @@ -103,15 +102,6 @@ public void ConfigureServices(IServiceCollection services) { client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", billingSettings.Onyx.ApiKey); }); - services.AddHttpClient("Freshsales", (sp, client) => - { - var billingSettings = sp.GetRequiredService>().Value; - client.BaseAddress = new Uri("https://bitwarden.freshsales.io/api/"); - client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue( - "Token", - $"token={billingSettings.FreshsalesApiKey}" - ); - }); services.AddScoped(); services.AddScoped(); diff --git a/test/Billing.Test/Controllers/FreshsalesControllerTests.cs b/test/Billing.Test/Controllers/FreshsalesControllerTests.cs index c9eb8c8e40c7..c9ae6efb1a1b 100644 --- a/test/Billing.Test/Controllers/FreshsalesControllerTests.cs +++ b/test/Billing.Test/Controllers/FreshsalesControllerTests.cs @@ -31,18 +31,12 @@ private static (FreshsalesController, IUserRepository, IOrganizationRepository) var globalSettings = new GlobalSettings(); globalSettings.BaseServiceUri.Admin = "https://test.com"; - var httpClientFactory = Substitute.For(); - httpClientFactory - .CreateClient("Freshsales") - .Returns(new HttpClient()); - var sut = new FreshsalesController( userRepository, organizationRepository, billingSettings, Substitute.For>(), - globalSettings, - httpClientFactory + globalSettings ); return (sut, userRepository, organizationRepository); diff --git a/util/Setup/Program.cs b/util/Setup/Program.cs index 68f5447c5f59..a951cbe17dc6 100644 --- a/util/Setup/Program.cs +++ b/util/Setup/Program.cs @@ -285,7 +285,6 @@ private static bool ValidateInstallation() url = $"{installationUrl}/installations/"; } - var response = new HttpClient().GetAsync(url + _context.Install.InstallationId).GetAwaiter().GetResult(); if (!response.IsSuccessStatusCode) From e2da4cc54152796cdf9f1ec94c55f21e129a055a Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Wed, 7 May 2025 14:11:03 -0700 Subject: [PATCH 23/41] remove unused code --- util/Setup/Program.cs | 6 +----- util/Setup/SetupHostEnvironment.cs | 12 ------------ 2 files changed, 1 insertion(+), 17 deletions(-) delete mode 100644 util/Setup/SetupHostEnvironment.cs diff --git a/util/Setup/Program.cs b/util/Setup/Program.cs index a951cbe17dc6..5cefd1ab8ed3 100644 --- a/util/Setup/Program.cs +++ b/util/Setup/Program.cs @@ -310,12 +310,8 @@ private static bool ValidateInstallation() return true; } - catch (Exception ex) + catch { - // TODO: Remove exception message before main merge?? - Console.WriteLine( - $"Unable to validate installation id. Problem contacting Bitwarden {cloudRegion.ToString()} server.\nError: {ex.Message}" - ); return false; } } diff --git a/util/Setup/SetupHostEnvironment.cs b/util/Setup/SetupHostEnvironment.cs deleted file mode 100644 index 97e088741afb..000000000000 --- a/util/Setup/SetupHostEnvironment.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Microsoft.Extensions.FileProviders; -using Microsoft.Extensions.Hosting; - -namespace Bit.Setup; - -internal class SetupHostEnvironment : IHostEnvironment -{ - public string ApplicationName { get; set; } = "Setup"; - public IFileProvider ContentRootFileProvider { get; set; } = new NullFileProvider(); - public string ContentRootPath { get; set; } = string.Empty; - public string EnvironmentName { get; set; } = "Production"; -} From 50e2db716d9823f71b14d3c9c55b9cf061dc22a3 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Wed, 7 May 2025 14:12:54 -0700 Subject: [PATCH 24/41] re-add error log for installation id --- util/Setup/Program.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/util/Setup/Program.cs b/util/Setup/Program.cs index 5cefd1ab8ed3..9f0789583840 100644 --- a/util/Setup/Program.cs +++ b/util/Setup/Program.cs @@ -312,6 +312,9 @@ private static bool ValidateInstallation() } catch { + Console.WriteLine( + $"Unable to validate installation id. Problem contacting Bitwarden {cloudRegion.ToString()} server.\nError: {ex.Message}" + ); return false; } } From 136f32ec7bc0802587b4bdb2e277638afeac56b1 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Wed, 7 May 2025 14:14:18 -0700 Subject: [PATCH 25/41] remove missing error message in log --- util/Setup/Program.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/util/Setup/Program.cs b/util/Setup/Program.cs index 9f0789583840..50f3046d6d7c 100644 --- a/util/Setup/Program.cs +++ b/util/Setup/Program.cs @@ -312,9 +312,7 @@ private static bool ValidateInstallation() } catch { - Console.WriteLine( - $"Unable to validate installation id. Problem contacting Bitwarden {cloudRegion.ToString()} server.\nError: {ex.Message}" - ); + Console.WriteLine($"Unable to validate installation id. Problem contacting Bitwarden {cloudRegion.ToString()} server."); return false; } } From a246d54122a494a7693b07596463e155961447b3 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Tue, 13 May 2025 05:48:20 -0700 Subject: [PATCH 26/41] build: remove duplicate docker+qemu setup steps Co-authored-by: Opeyemi --- .github/workflows/build.yml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d67ba7ce08f5..ade6a6cfd13b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -107,13 +107,6 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0 - ########## Set up Docker ########## - - name: Set up QEMU emulators - uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v3.0.0 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0 - ########## ACRs ########## - name: Log in to Azure - production subscription uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 From 30369d9a8a4f7695bf7f86d93ba78397a965fd0f Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Mon, 19 May 2025 10:52:07 -0700 Subject: [PATCH 27/41] build: optimize for simpler builds over caching --- bitwarden_license/src/Scim/Dockerfile | 23 ++----------- bitwarden_license/src/Sso/Dockerfile | 23 ++----------- src/Admin/Dockerfile | 48 +++++---------------------- src/Api/Dockerfile | 26 +++------------ src/Billing/Dockerfile | 22 +++--------- src/Events/Dockerfile | 22 +++--------- src/EventsProcessor/Dockerfile | 24 +++----------- src/Icons/Dockerfile | 22 +++--------- src/Identity/Dockerfile | 23 +++---------- src/Notifications/Dockerfile | 22 +++--------- util/Attachments/Dockerfile | 10 ++---- util/Setup/Dockerfile | 16 +++------ 12 files changed, 47 insertions(+), 234 deletions(-) diff --git a/bitwarden_license/src/Scim/Dockerfile b/bitwarden_license/src/Scim/Dockerfile index 356003559658..4baf01a57302 100644 --- a/bitwarden_license/src/Scim/Dockerfile +++ b/bitwarden_license/src/Scim/Dockerfile @@ -17,34 +17,15 @@ RUN if [ "$TARGETPLATFORM" = "linux/amd64" ]; then \ fi \ && echo "RID=$RID" > /tmp/rid.txt +# Copy required project files 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 . +COPY . ./ # 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 \ diff --git a/bitwarden_license/src/Sso/Dockerfile b/bitwarden_license/src/Sso/Dockerfile index d75d1ca50369..bb77d5526d38 100644 --- a/bitwarden_license/src/Sso/Dockerfile +++ b/bitwarden_license/src/Sso/Dockerfile @@ -17,34 +17,15 @@ RUN if [ "$TARGETPLATFORM" = "linux/amd64" ]; then \ fi \ && echo "RID=$RID" > /tmp/rid.txt +# Copy required project files 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 . +COPY . ./ # 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 \ diff --git a/src/Admin/Dockerfile b/src/Admin/Dockerfile index 8c74c1928961..b1a3d772c00c 100644 --- a/src/Admin/Dockerfile +++ b/src/Admin/Dockerfile @@ -17,21 +17,6 @@ RUN if [ "$TARGETPLATFORM" = "linux/amd64" ]; then \ 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 - \ @@ -40,33 +25,16 @@ RUN curl -fsSL https://deb.nodesource.com/setup_${NODE_VERSION}.x | bash - \ && 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 +# Copy required project files +WORKDIR /source +COPY . ./ # Restore project dependencies and tools +WORKDIR /source/src/Admin +RUN npm ci 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 \ @@ -79,11 +47,13 @@ RUN . /tmp/rid.txt && dotnet publish \ # App stage # ############################################### FROM mcr.microsoft.com/dotnet/aspnet:8.0 -LABEL com.bitwarden.product="bitwarden" -EXPOSE 5000 +ARG TARGETPLATFORM +LABEL com.bitwarden.product="bitwarden" +ENV ASPNETCORE_ENVIRONMENT=Production ENV ASPNETCORE_URLS=http://+:5000 ENV SSL_CERT_DIR=/etc/bitwarden/ca-certificates +EXPOSE 5000 RUN apt-get update \ && apt-get install -y --no-install-recommends \ diff --git a/src/Api/Dockerfile b/src/Api/Dockerfile index 3a3aafbfcd48..f5327a37f42b 100644 --- a/src/Api/Dockerfile +++ b/src/Api/Dockerfile @@ -18,36 +18,18 @@ RUN if [ "$TARGETPLATFORM" = "linux/amd64" ]; then \ fi \ && echo "RID=$RID" > /tmp/rid.txt -# Copy csproj files as distinct layers +# Copy required project files 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 . +COPY . ./ # 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 \ + -c release \ + --no-restore \ --self-contained \ /p:PublishSingleFile=true \ /p:SourceRevisionId="$GIT_COMMIT" \ diff --git a/src/Billing/Dockerfile b/src/Billing/Dockerfile index 1eef72733fc6..3a6b8aac481f 100644 --- a/src/Billing/Dockerfile +++ b/src/Billing/Dockerfile @@ -18,32 +18,18 @@ RUN if [ "$TARGETPLATFORM" = "linux/amd64" ]; then \ fi \ && echo "RID=$RID" > /tmp/rid.txt -# Copy csproj files as distinct layers +# Copy required project files 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 . +COPY . ./ # 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 \ + -c release \ + --no-restore \ --self-contained \ /p:PublishSingleFile=true \ /p:SourceRevisionId="$GIT_COMMIT" \ diff --git a/src/Events/Dockerfile b/src/Events/Dockerfile index 72d8e0a83390..708e96019f98 100644 --- a/src/Events/Dockerfile +++ b/src/Events/Dockerfile @@ -18,32 +18,18 @@ RUN if [ "$TARGETPLATFORM" = "linux/amd64" ]; then \ fi \ && echo "RID=$RID" > /tmp/rid.txt -# Copy csproj files as distinct layers +# Copy required project files 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 . +COPY . ./ # 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 \ + -c release \ + --no-restore \ --self-contained \ /p:PublishSingleFile=true \ /p:SourceRevisionId="$GIT_COMMIT" \ diff --git a/src/EventsProcessor/Dockerfile b/src/EventsProcessor/Dockerfile index 5bb4fd34a230..66cbd0e62186 100644 --- a/src/EventsProcessor/Dockerfile +++ b/src/EventsProcessor/Dockerfile @@ -18,33 +18,18 @@ RUN if [ "$TARGETPLATFORM" = "linux/amd64" ]; then \ fi \ && echo "RID=$RID" > /tmp/rid.txt -# Copy csproj files as distinct layers +# Copy required project files 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 . +COPY . ./ # 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 \ + -c release \ + --no-restore \ --self-contained \ /p:PublishSingleFile=true \ /p:SourceRevisionId="$GIT_COMMIT" \ @@ -71,7 +56,6 @@ RUN apt-get update \ curl \ && rm -rf /var/lib/apt/lists/* -# Copy app from the build stage # Copy app from the build stage WORKDIR /app COPY --from=build /source/src/EventsProcessor/out /app diff --git a/src/Icons/Dockerfile b/src/Icons/Dockerfile index eb844c646458..786d30af56e5 100644 --- a/src/Icons/Dockerfile +++ b/src/Icons/Dockerfile @@ -17,32 +17,18 @@ RUN if [ "$TARGETPLATFORM" = "linux/amd64" ]; then \ fi \ && echo "RID=$RID" > /tmp/rid.txt -# Copy csproj files as distinct layers +# Copy required project files 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 . +COPY . ./ # 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 \ + -c release \ + --no-restore \ --self-contained \ /p:PublishSingleFile=true \ /p:SourceRevisionId="$GIT_COMMIT" \ diff --git a/src/Identity/Dockerfile b/src/Identity/Dockerfile index 62439c82071e..5c2a8e406434 100644 --- a/src/Identity/Dockerfile +++ b/src/Identity/Dockerfile @@ -18,32 +18,18 @@ RUN if [ "$TARGETPLATFORM" = "linux/amd64" ]; then \ fi \ && echo "RID=$RID" > /tmp/rid.txt -# Copy csproj files as distinct layers +# Copy required project files 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 . +COPY . ./ # 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 \ + -c release \ + --no-restore \ --self-contained \ /p:PublishSingleFile=true \ /p:SourceRevisionId="$GIT_COMMIT" \ @@ -76,7 +62,6 @@ WORKDIR /app 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 ENTRYPOINT ["/entrypoint.sh"] diff --git a/src/Notifications/Dockerfile b/src/Notifications/Dockerfile index 8179e6be0414..bdf9373f487b 100644 --- a/src/Notifications/Dockerfile +++ b/src/Notifications/Dockerfile @@ -18,32 +18,18 @@ RUN if [ "$TARGETPLATFORM" = "linux/amd64" ]; then \ fi \ && echo "RID=$RID" > /tmp/rid.txt -# Copy csproj files as distinct layers +# Copy required project files 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 . +COPY . ./ # 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 \ + -c release \ + --no-restore \ --self-contained \ /p:PublishSingleFile=true \ /p:SourceRevisionId="$GIT_COMMIT" \ diff --git a/util/Attachments/Dockerfile b/util/Attachments/Dockerfile index 4bdfc43e76ab..47b8660d9ea0 100644 --- a/util/Attachments/Dockerfile +++ b/util/Attachments/Dockerfile @@ -17,20 +17,14 @@ RUN if [ "$TARGETPLATFORM" = "linux/amd64" ]; then \ fi \ && echo "RID=$RID" > /tmp/rid.txt -# Copy csproj files as distinct layers +# Copy required project files WORKDIR /source -COPY util/Server/*.csproj ./util/Server/ -COPY Directory.Build.props . -COPY .editorconfig . +COPY . ./ # 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 \ diff --git a/util/Setup/Dockerfile b/util/Setup/Dockerfile index d43ecac38f6b..eafae1b1bd28 100644 --- a/util/Setup/Dockerfile +++ b/util/Setup/Dockerfile @@ -18,27 +18,19 @@ RUN if [ "$TARGETPLATFORM" = "linux/amd64" ]; then \ fi \ && echo "RID=$RID" > /tmp/rid.txt -# Copy csproj files as distinct layers +# Copy required project files WORKDIR /source -COPY util/Setup/*.csproj ./util/Setup/ -COPY src/Core/*.csproj ./src/Core/ -COPY util/Migrator/*.csproj ./util/Migrator/ -COPY Directory.Build.props . +COPY . ./ # 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 \ + -c release \ + --no-restore \ --self-contained \ /p:SourceRevisionId="$GIT_COMMIT" \ -r $RID \ From 9d4a96b078b789b250e634276937f3b58e21e994 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Mon, 19 May 2025 11:20:42 -0700 Subject: [PATCH 28/41] build: restore previous method for getting the GIT_HASH --- Directory.Build.props | 17 +++++++++++++++++ bitwarden_license/src/Sso/Dockerfile | 1 - src/Admin/Dockerfile | 2 -- src/Api/Dockerfile | 2 -- src/Billing/Dockerfile | 2 -- src/Events/Dockerfile | 2 -- src/EventsProcessor/Dockerfile | 2 -- src/Icons/Dockerfile | 2 -- src/Identity/Dockerfile | 2 -- src/Notifications/Dockerfile | 2 -- util/Attachments/Dockerfile | 1 - util/MsSqlMigratorUtility/Dockerfile | 2 -- util/Setup/Dockerfile | 2 -- 13 files changed, 17 insertions(+), 22 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index 72fe2fc7af02..152b451825d4 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -52,4 +52,21 @@ 4.18.1 + + + + + + + + + + <_Parameter1>GitHash + <_Parameter2>$(SourceRevisionId) + + + diff --git a/bitwarden_license/src/Sso/Dockerfile b/bitwarden_license/src/Sso/Dockerfile index bb77d5526d38..ab9384d7d2d3 100644 --- a/bitwarden_license/src/Sso/Dockerfile +++ b/bitwarden_license/src/Sso/Dockerfile @@ -31,7 +31,6 @@ RUN . /tmp/rid.txt && dotnet publish \ --no-restore \ --self-contained \ /p:PublishSingleFile=true \ - /p:SourceRevisionId="$GIT_COMMIT" \ -r $RID \ -o out diff --git a/src/Admin/Dockerfile b/src/Admin/Dockerfile index b1a3d772c00c..cf839e56a986 100644 --- a/src/Admin/Dockerfile +++ b/src/Admin/Dockerfile @@ -2,7 +2,6 @@ # 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 @@ -39,7 +38,6 @@ RUN npm run build RUN . /tmp/rid.txt && dotnet publish \ --self-contained \ /p:PublishSingleFile=true \ - /p:SourceRevisionId="$GIT_COMMIT" \ -r $RID \ -o out diff --git a/src/Api/Dockerfile b/src/Api/Dockerfile index f5327a37f42b..a37c0ae8d442 100644 --- a/src/Api/Dockerfile +++ b/src/Api/Dockerfile @@ -2,7 +2,6 @@ # 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 @@ -32,7 +31,6 @@ RUN . /tmp/rid.txt && dotnet publish \ --no-restore \ --self-contained \ /p:PublishSingleFile=true \ - /p:SourceRevisionId="$GIT_COMMIT" \ -r $RID \ -o out diff --git a/src/Billing/Dockerfile b/src/Billing/Dockerfile index 3a6b8aac481f..50059cfcbd81 100644 --- a/src/Billing/Dockerfile +++ b/src/Billing/Dockerfile @@ -2,7 +2,6 @@ # 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 @@ -32,7 +31,6 @@ RUN . /tmp/rid.txt && dotnet publish \ --no-restore \ --self-contained \ /p:PublishSingleFile=true \ - /p:SourceRevisionId="$GIT_COMMIT" \ -r $RID \ -o out diff --git a/src/Events/Dockerfile b/src/Events/Dockerfile index 708e96019f98..490a862ebff2 100644 --- a/src/Events/Dockerfile +++ b/src/Events/Dockerfile @@ -2,7 +2,6 @@ # 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 @@ -32,7 +31,6 @@ RUN . /tmp/rid.txt && dotnet publish \ --no-restore \ --self-contained \ /p:PublishSingleFile=true \ - /p:SourceRevisionId="$GIT_COMMIT" \ -r $RID \ -o out diff --git a/src/EventsProcessor/Dockerfile b/src/EventsProcessor/Dockerfile index 66cbd0e62186..89ba4c3137ab 100644 --- a/src/EventsProcessor/Dockerfile +++ b/src/EventsProcessor/Dockerfile @@ -2,7 +2,6 @@ # 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 @@ -32,7 +31,6 @@ RUN . /tmp/rid.txt && dotnet publish \ --no-restore \ --self-contained \ /p:PublishSingleFile=true \ - /p:SourceRevisionId="$GIT_COMMIT" \ -r $RID \ -o out diff --git a/src/Icons/Dockerfile b/src/Icons/Dockerfile index 786d30af56e5..5f7c4e8e8ece 100644 --- a/src/Icons/Dockerfile +++ b/src/Icons/Dockerfile @@ -2,7 +2,6 @@ # 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 @@ -31,7 +30,6 @@ RUN . /tmp/rid.txt && dotnet publish \ --no-restore \ --self-contained \ /p:PublishSingleFile=true \ - /p:SourceRevisionId="$GIT_COMMIT" \ -r $RID \ -o out diff --git a/src/Identity/Dockerfile b/src/Identity/Dockerfile index 5c2a8e406434..dd81a05f334c 100644 --- a/src/Identity/Dockerfile +++ b/src/Identity/Dockerfile @@ -2,7 +2,6 @@ # 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 @@ -32,7 +31,6 @@ RUN . /tmp/rid.txt && dotnet publish \ --no-restore \ --self-contained \ /p:PublishSingleFile=true \ - /p:SourceRevisionId="$GIT_COMMIT" \ -r $RID \ -o out diff --git a/src/Notifications/Dockerfile b/src/Notifications/Dockerfile index bdf9373f487b..2d7aa340696d 100644 --- a/src/Notifications/Dockerfile +++ b/src/Notifications/Dockerfile @@ -2,7 +2,6 @@ # 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 @@ -32,7 +31,6 @@ RUN . /tmp/rid.txt && dotnet publish \ --no-restore \ --self-contained \ /p:PublishSingleFile=true \ - /p:SourceRevisionId="$GIT_COMMIT" \ -r $RID \ -o out diff --git a/util/Attachments/Dockerfile b/util/Attachments/Dockerfile index 47b8660d9ea0..efaf5bd50ce0 100644 --- a/util/Attachments/Dockerfile +++ b/util/Attachments/Dockerfile @@ -30,7 +30,6 @@ WORKDIR /source/util/Server RUN . /tmp/rid.txt && dotnet publish \ --self-contained \ /p:PublishSingleFile=true \ - /p:SourceRevisionId="$GIT_COMMIT" \ -r $RID \ -o out diff --git a/util/MsSqlMigratorUtility/Dockerfile b/util/MsSqlMigratorUtility/Dockerfile index eab9bf8b65c7..9d0c878199ad 100644 --- a/util/MsSqlMigratorUtility/Dockerfile +++ b/util/MsSqlMigratorUtility/Dockerfile @@ -2,7 +2,6 @@ # 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 @@ -46,7 +45,6 @@ WORKDIR /source/util/MsSqlMigratorUtility RUN . /tmp/rid.txt && dotnet publish \ --self-contained \ /p:PublishSingleFile=true \ - /p:SourceRevisionId="$GIT_COMMIT" \ -r $RID \ -o out diff --git a/util/Setup/Dockerfile b/util/Setup/Dockerfile index eafae1b1bd28..f36a32901922 100644 --- a/util/Setup/Dockerfile +++ b/util/Setup/Dockerfile @@ -2,7 +2,6 @@ # 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 @@ -32,7 +31,6 @@ RUN . /tmp/rid.txt && dotnet publish \ -c release \ --no-restore \ --self-contained \ - /p:SourceRevisionId="$GIT_COMMIT" \ -r $RID \ -o out From 50df44ba87c1ee65a6b55603f0d8a8641c421792 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Mon, 19 May 2025 13:42:24 -0700 Subject: [PATCH 29/41] fix: add missing build args to remaining images --- src/Admin/Dockerfile | 2 ++ util/Attachments/Dockerfile | 2 ++ util/MsSqlMigratorUtility/Dockerfile | 10 ++++++---- util/Setup/Dockerfile | 1 + 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/Admin/Dockerfile b/src/Admin/Dockerfile index cf839e56a986..d6b42eadfbac 100644 --- a/src/Admin/Dockerfile +++ b/src/Admin/Dockerfile @@ -36,6 +36,8 @@ RUN . /tmp/rid.txt && dotnet restore -r $RID # Build project RUN npm run build RUN . /tmp/rid.txt && dotnet publish \ + -c release \ + --no-restore \ --self-contained \ /p:PublishSingleFile=true \ -r $RID \ diff --git a/util/Attachments/Dockerfile b/util/Attachments/Dockerfile index efaf5bd50ce0..fc5445762cf4 100644 --- a/util/Attachments/Dockerfile +++ b/util/Attachments/Dockerfile @@ -28,6 +28,8 @@ RUN . /tmp/rid.txt && dotnet restore -r $RID # Build project WORKDIR /source/util/Server RUN . /tmp/rid.txt && dotnet publish \ + -c release \ + --no-restore \ --self-contained \ /p:PublishSingleFile=true \ -r $RID \ diff --git a/util/MsSqlMigratorUtility/Dockerfile b/util/MsSqlMigratorUtility/Dockerfile index 9d0c878199ad..ae47705eade2 100644 --- a/util/MsSqlMigratorUtility/Dockerfile +++ b/util/MsSqlMigratorUtility/Dockerfile @@ -43,10 +43,12 @@ COPY .editorconfig /source # Build project WORKDIR /source/util/MsSqlMigratorUtility RUN . /tmp/rid.txt && dotnet publish \ - --self-contained \ - /p:PublishSingleFile=true \ - -r $RID \ - -o out + -c release \ + --no-restore \ + --self-contained \ + /p:PublishSingleFile=true \ + -r $RID \ + -o out WORKDIR /app diff --git a/util/Setup/Dockerfile b/util/Setup/Dockerfile index f36a32901922..3c6f4063a3c8 100644 --- a/util/Setup/Dockerfile +++ b/util/Setup/Dockerfile @@ -31,6 +31,7 @@ RUN . /tmp/rid.txt && dotnet publish \ -c release \ --no-restore \ --self-contained \ + /p:PublishSingleFile=true \ -r $RID \ -o out From 54f3d6b9777e681d216945ffede86a30c853e24a Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Mon, 19 May 2025 13:42:49 -0700 Subject: [PATCH 30/41] fix: rm extraneous source revision id arg --- bitwarden_license/src/Scim/Dockerfile | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/bitwarden_license/src/Scim/Dockerfile b/bitwarden_license/src/Scim/Dockerfile index 4baf01a57302..df284de83af6 100644 --- a/bitwarden_license/src/Scim/Dockerfile +++ b/bitwarden_license/src/Scim/Dockerfile @@ -27,13 +27,12 @@ RUN . /tmp/rid.txt && dotnet restore -r $RID # Build project RUN . /tmp/rid.txt && dotnet publish \ - -c release \ - --no-restore \ - --self-contained \ - /p:PublishSingleFile=true \ - /p:SourceRevisionId="$GIT_COMMIT" \ - -r $RID \ - -o out + -c release \ + --no-restore \ + --self-contained \ + /p:PublishSingleFile=true \ + -r $RID \ + -o out WORKDIR /app From 8e399b83966ff115323d59a8439f47d2bab89e19 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Mon, 19 May 2025 13:43:58 -0700 Subject: [PATCH 31/41] fmt: apply consistent spacing and rm redundant WORKDIR directive --- bitwarden_license/src/Scim/Dockerfile | 8 +++----- bitwarden_license/src/Sso/Dockerfile | 2 -- src/Api/Dockerfile | 2 -- src/Billing/Dockerfile | 2 -- src/Events/Dockerfile | 2 -- src/EventsProcessor/Dockerfile | 2 -- src/Icons/Dockerfile | 2 -- src/Identity/Dockerfile | 2 -- src/Notifications/Dockerfile | 2 -- util/Attachments/Dockerfile | 2 -- util/Setup/Dockerfile | 2 -- 11 files changed, 3 insertions(+), 25 deletions(-) diff --git a/bitwarden_license/src/Scim/Dockerfile b/bitwarden_license/src/Scim/Dockerfile index df284de83af6..a0c5c88e494f 100644 --- a/bitwarden_license/src/Scim/Dockerfile +++ b/bitwarden_license/src/Scim/Dockerfile @@ -9,11 +9,11 @@ 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 ; \ + RID=linux-x64 ; \ elif [ "$TARGETPLATFORM" = "linux/arm64" ]; then \ - RID=linux-arm64 ; \ + RID=linux-arm64 ; \ elif [ "$TARGETPLATFORM" = "linux/arm/v7" ]; then \ - RID=linux-arm ; \ + RID=linux-arm ; \ fi \ && echo "RID=$RID" > /tmp/rid.txt @@ -34,8 +34,6 @@ RUN . /tmp/rid.txt && dotnet publish \ -r $RID \ -o out -WORKDIR /app - ############################################### # App stage # ############################################### diff --git a/bitwarden_license/src/Sso/Dockerfile b/bitwarden_license/src/Sso/Dockerfile index ab9384d7d2d3..d5d012b41658 100644 --- a/bitwarden_license/src/Sso/Dockerfile +++ b/bitwarden_license/src/Sso/Dockerfile @@ -34,8 +34,6 @@ RUN . /tmp/rid.txt && dotnet publish \ -r $RID \ -o out -WORKDIR /app - ############################################### # App stage # ############################################### diff --git a/src/Api/Dockerfile b/src/Api/Dockerfile index a37c0ae8d442..29adde878c2d 100644 --- a/src/Api/Dockerfile +++ b/src/Api/Dockerfile @@ -34,8 +34,6 @@ RUN . /tmp/rid.txt && dotnet publish \ -r $RID \ -o out -WORKDIR /app - ############################################### # App stage # ############################################### diff --git a/src/Billing/Dockerfile b/src/Billing/Dockerfile index 50059cfcbd81..5eb4e9c0e011 100644 --- a/src/Billing/Dockerfile +++ b/src/Billing/Dockerfile @@ -34,8 +34,6 @@ RUN . /tmp/rid.txt && dotnet publish \ -r $RID \ -o out -WORKDIR /app - ############################################### # App stage # ############################################### diff --git a/src/Events/Dockerfile b/src/Events/Dockerfile index 490a862ebff2..58fbbe3df192 100644 --- a/src/Events/Dockerfile +++ b/src/Events/Dockerfile @@ -34,8 +34,6 @@ RUN . /tmp/rid.txt && dotnet publish \ -r $RID \ -o out -WORKDIR /app - ############################################### # App stage # ############################################### diff --git a/src/EventsProcessor/Dockerfile b/src/EventsProcessor/Dockerfile index 89ba4c3137ab..928af7fb8622 100644 --- a/src/EventsProcessor/Dockerfile +++ b/src/EventsProcessor/Dockerfile @@ -34,8 +34,6 @@ RUN . /tmp/rid.txt && dotnet publish \ -r $RID \ -o out -WORKDIR /app - ############################################### # App stage # ############################################### diff --git a/src/Icons/Dockerfile b/src/Icons/Dockerfile index 5f7c4e8e8ece..16c88e22fac2 100644 --- a/src/Icons/Dockerfile +++ b/src/Icons/Dockerfile @@ -33,8 +33,6 @@ RUN . /tmp/rid.txt && dotnet publish \ -r $RID \ -o out -WORKDIR /app - ############################################### # App stage # ############################################### diff --git a/src/Identity/Dockerfile b/src/Identity/Dockerfile index dd81a05f334c..9b9ae41334e6 100644 --- a/src/Identity/Dockerfile +++ b/src/Identity/Dockerfile @@ -34,8 +34,6 @@ RUN . /tmp/rid.txt && dotnet publish \ -r $RID \ -o out -WORKDIR /app - ############################################### # App stage # ############################################### diff --git a/src/Notifications/Dockerfile b/src/Notifications/Dockerfile index 2d7aa340696d..9cbc10e664a7 100644 --- a/src/Notifications/Dockerfile +++ b/src/Notifications/Dockerfile @@ -34,8 +34,6 @@ RUN . /tmp/rid.txt && dotnet publish \ -r $RID \ -o out -WORKDIR /app - ############################################### # App stage # ############################################### diff --git a/util/Attachments/Dockerfile b/util/Attachments/Dockerfile index fc5445762cf4..24a315e99ded 100644 --- a/util/Attachments/Dockerfile +++ b/util/Attachments/Dockerfile @@ -35,8 +35,6 @@ RUN . /tmp/rid.txt && dotnet publish \ -r $RID \ -o out -WORKDIR /app - ############################################### # App stage # ############################################### diff --git a/util/Setup/Dockerfile b/util/Setup/Dockerfile index 3c6f4063a3c8..b94c1f564cf3 100644 --- a/util/Setup/Dockerfile +++ b/util/Setup/Dockerfile @@ -35,8 +35,6 @@ RUN . /tmp/rid.txt && dotnet publish \ -r $RID \ -o out -WORKDIR /app - ############################################### # App stage # ############################################### From 6d9739f1cb6f5784e2411c86ccdd3f2334c3b507 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Mon, 19 May 2025 13:45:06 -0700 Subject: [PATCH 32/41] build: update migrator to use simpler build; apply consistent spacing --- util/MsSqlMigratorUtility/Dockerfile | 35 +++++++--------------------- 1 file changed, 9 insertions(+), 26 deletions(-) diff --git a/util/MsSqlMigratorUtility/Dockerfile b/util/MsSqlMigratorUtility/Dockerfile index ae47705eade2..990c25a7fbc2 100644 --- a/util/MsSqlMigratorUtility/Dockerfile +++ b/util/MsSqlMigratorUtility/Dockerfile @@ -9,37 +9,22 @@ 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 + 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 +# Copy required project files 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 . +COPY . ./ # 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 \ @@ -50,8 +35,6 @@ RUN . /tmp/rid.txt && dotnet publish \ -r $RID \ -o out -WORKDIR /app - ############################################### # App stage # ############################################### From fbfd8bf54b1a3e6982b58fa6a4cd20ae61784a60 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Wed, 21 May 2025 07:44:38 -0700 Subject: [PATCH 33/41] fix: docker build context --- .github/workflows/build.yml | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 19eea71b6a8c..5008b25d54cd 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -48,6 +48,8 @@ jobs: node: true - project_name: Api base_path: ./src + - project_name: Attachments + base_path: ./util - project_name: Billing base_path: ./src - project_name: Events @@ -58,21 +60,20 @@ jobs: base_path: ./src - project_name: Identity base_path: ./src + - project_name: MsSql + base_path: ./util - project_name: MsSqlMigratorUtility base_path: ./util - dotnet: true + - project_name: Nginx + base_path: ./util - project_name: Notifications base_path: ./src - project_name: Scim base_path: ./bitwarden_license/src - dotnet: true - - project_name: Server - base_path: ./util - project_name: Setup base_path: ./util - project_name: Sso base_path: ./bitwarden_license/src - node: true steps: - name: Check secrets id: check-secrets @@ -294,9 +295,14 @@ jobs: id: build-docker uses: docker/build-push-action@67a2d409c0a876cbe6b11854e3e25193efe4e62d # v6.12.0 with: - context: ${{ matrix.base_path }}/${{ matrix.project_name }} + cache-from: type=registry,ref=${{ steps.cache-name.outputs.name }} + cache-to: type=registry,ref=${{ steps.cache-name.outputs.name}},mode=max + context: . file: ${{ matrix.base_path }}/${{ matrix.project_name }}/Dockerfile - platforms: linux/amd64 + platforms: | + linux/amd64, + linux/arm/v7, + linux/arm64 push: true tags: ${{ steps.image-tags.outputs.tags }} secrets: | From d62a5999cadfd4d2a1959c25848ae1068646251f Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Wed, 21 May 2025 08:42:54 -0700 Subject: [PATCH 34/41] build: simplify workflow changes --- .github/workflows/build.yml | 120 +++++++++--------------------------- 1 file changed, 28 insertions(+), 92 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5008b25d54cd..13aa6f588a5d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -32,48 +32,63 @@ jobs: - name: Verify format run: dotnet format --verify-no-changes - build-artifacts: - name: Build artifacts + build-docker: + name: Build Docker images runs-on: ubuntu-22.04 needs: - lint outputs: has_secrets: ${{ steps.check-secrets.outputs.has_secrets }} + permissions: + security-events: write + id-token: write strategy: fail-fast: false matrix: include: - project_name: Admin base_path: ./src + dotnet: true node: true - project_name: Api base_path: ./src + dotnet: true - project_name: Attachments base_path: ./util - project_name: Billing base_path: ./src + dotnet: true - project_name: Events base_path: ./src + dotnet: true - project_name: EventsProcessor base_path: ./src + dotnet: true - project_name: Icons base_path: ./src + dotnet: true - project_name: Identity base_path: ./src + dotnet: true - project_name: MsSql base_path: ./util - project_name: MsSqlMigratorUtility base_path: ./util + dotnet: true - project_name: Nginx base_path: ./util - project_name: Notifications base_path: ./src + dotnet: true - project_name: Scim base_path: ./bitwarden_license/src + dotnet: true - project_name: Setup base_path: ./util + dotnet: true - project_name: Sso base_path: ./bitwarden_license/src + dotnet: true steps: - name: Check secrets id: check-secrets @@ -134,82 +149,12 @@ jobs: path: ${{ matrix.base_path }}/${{ matrix.project_name }}/${{ matrix.project_name }}.zip if-no-files-found: error - build-docker: - name: Build Docker images - runs-on: ubuntu-22.04 - permissions: - security-events: write - id-token: write - needs: - - build-artifacts - if: ${{ needs.build-artifacts.outputs.has_secrets == 'true' }} - strategy: - fail-fast: false - matrix: - include: - - project_name: Admin - base_path: ./src - dotnet: true - - project_name: Api - base_path: ./src - dotnet: true - - project_name: Attachments - base_path: ./util - - project_name: Billing - base_path: ./src - dotnet: true - - project_name: Events - base_path: ./src - dotnet: true - - project_name: EventsProcessor - base_path: ./src - dotnet: true - - project_name: Icons - base_path: ./src - dotnet: true - - project_name: Identity - base_path: ./src - dotnet: true - - project_name: MsSql - base_path: ./util - - project_name: MsSqlMigratorUtility - base_path: ./util - dotnet: true - - project_name: Nginx - base_path: ./util - - project_name: Notifications - base_path: ./src - dotnet: true - - project_name: Scim - base_path: ./bitwarden_license/src - dotnet: true - - project_name: Server - base_path: ./util - dotnet: true - - project_name: Setup - base_path: ./util - dotnet: true - - project_name: Sso - base_path: ./bitwarden_license/src - dotnet: true - steps: - - name: Check out repo - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - ref: ${{ github.event.pull_request.head.sha }} - - - name: Check branch to publish - env: - PUBLISH_BRANCHES: "main,rc,hotfix-rc" - id: publish-branch-check - run: | - IFS="," read -a publish_branches <<< $PUBLISH_BRANCHES + ########## Set up Docker ########## + - name: Set up QEMU emulators + uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v3.0.0 - if [[ " ${publish_branches[*]} " =~ " ${GITHUB_REF:11} " ]]; then - echo "is_publish_branch=true" >> $GITHUB_ENV - else - echo "is_publish_branch=false" >> $GITHUB_ENV - fi + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0 ########## ACRs ########## - name: Log in to Azure - production subscription @@ -278,18 +223,11 @@ jobs: fi echo "tags=$TAGS" >> $GITHUB_OUTPUT - - name: Get build artifact - if: ${{ matrix.dotnet }} - uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 - with: - name: ${{ matrix.project_name }}.zip - - - name: Set up build artifact - if: ${{ matrix.dotnet }} - run: | - mkdir -p ${{ matrix.base_path}}/${{ matrix.project_name }}/obj/build-output/publish - unzip ${{ matrix.project_name }}.zip \ - -d ${{ matrix.base_path }}/${{ matrix.project_name }}/obj/build-output/publish + - name: Generate image full name + id: cache-name + env: + PROJECT_NAME: ${{ steps.setup.outputs.project_name }} + run: echo "name=${_AZ_REGISTRY}/${PROJECT_NAME}:buildcache" >> $GITHUB_OUTPUT - name: Build Docker image id: build-docker @@ -643,10 +581,9 @@ jobs: setup-ephemeral-environment: name: Setup Ephemeral Environment needs: - - build-artifacts - build-docker if: | - needs.build-artifacts.outputs.has_secrets == 'true' + needs.build-docker.outputs.has_secrets == 'true' && github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'ephemeral-environment') uses: bitwarden/gh-actions/.github/workflows/_ephemeral_environment_manager.yml@main @@ -661,7 +598,6 @@ jobs: runs-on: ubuntu-22.04 needs: - lint - - build-artifacts - build-docker - upload - build-mssqlmigratorutility From b304e5f44df9fb9e1936c9ceac893f04cb0b0b08 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Wed, 21 May 2025 08:48:42 -0700 Subject: [PATCH 35/41] fix: only build when dotnet is true --- .github/workflows/build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 13aa6f588a5d..f155492834ca 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -131,6 +131,7 @@ jobs: - name: Publish project working-directory: ${{ matrix.base_path }}/${{ matrix.project_name }} + if: ${{ matrix.dotnet }} run: | echo "Publish" dotnet publish -c "Release" -o obj/build-output/publish From 6eb6cb9b0d2aeec6e147446f81a1d6aeefe27d4e Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Wed, 21 May 2025 08:54:47 -0700 Subject: [PATCH 36/41] build: only upload artifects when dotnet is true --- .github/workflows/build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f155492834ca..c3afe5da7f7d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -145,6 +145,7 @@ jobs: - name: Upload project artifact uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 + if: ${{ matrix.dotnet }} with: name: ${{ matrix.project_name }}.zip path: ${{ matrix.base_path }}/${{ matrix.project_name }}/${{ matrix.project_name }}.zip From 6dd615ed9c75c88f64caba9bfd6c85983cc735e4 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Wed, 21 May 2025 09:05:41 -0700 Subject: [PATCH 37/41] chore: rename build-docker to build-artifacts --- .github/workflows/build.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c3afe5da7f7d..03b993e3320c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -32,7 +32,7 @@ jobs: - name: Verify format run: dotnet format --verify-no-changes - build-docker: + build-artifacts: name: Build Docker images runs-on: ubuntu-22.04 needs: @@ -232,7 +232,7 @@ jobs: run: echo "name=${_AZ_REGISTRY}/${PROJECT_NAME}:buildcache" >> $GITHUB_OUTPUT - name: Build Docker image - id: build-docker + id: build-artifacts uses: docker/build-push-action@67a2d409c0a876cbe6b11854e3e25193efe4e62d # v6.12.0 with: cache-from: type=registry,ref=${{ steps.cache-name.outputs.name }} @@ -255,7 +255,7 @@ jobs: - name: Sign image with Cosign if: github.event_name != 'pull_request' && github.ref == 'refs/heads/main' env: - DIGEST: ${{ steps.build-docker.outputs.digest }} + DIGEST: ${{ steps.build-artifacts.outputs.digest }} TAGS: ${{ steps.image-tags.outputs.tags }} run: | IFS="," read -a tags <<< "${TAGS}" @@ -283,7 +283,7 @@ jobs: upload: name: Upload runs-on: ubuntu-22.04 - needs: build-docker + needs: build-artifacts steps: - name: Check out repo uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 @@ -516,7 +516,7 @@ jobs: && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/rc' || github.ref == 'refs/heads/hotfix-rc') runs-on: ubuntu-22.04 needs: - - build-docker + - build-artifacts steps: - name: Log in to Azure - CI subscription uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 @@ -550,7 +550,7 @@ jobs: if: github.event_name != 'pull_request' && github.ref == 'refs/heads/main' runs-on: ubuntu-22.04 needs: - - build-docker + - build-artifacts steps: - name: Log in to Azure - CI subscription uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 @@ -583,9 +583,9 @@ jobs: setup-ephemeral-environment: name: Setup Ephemeral Environment needs: - - build-docker + - build-artifacts if: | - needs.build-docker.outputs.has_secrets == 'true' + needs.build-artifacts.outputs.has_secrets == 'true' && github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'ephemeral-environment') uses: bitwarden/gh-actions/.github/workflows/_ephemeral_environment_manager.yml@main @@ -600,7 +600,7 @@ jobs: runs-on: ubuntu-22.04 needs: - lint - - build-docker + - build-artifacts - upload - build-mssqlmigratorutility - self-host-build From a13c680744babc89eca6175c08f51b58614698de Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Wed, 21 May 2025 13:35:38 -0700 Subject: [PATCH 38/41] Update build.yml --- .github/workflows/build.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 03b993e3320c..4f2cb38246d1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -67,6 +67,9 @@ jobs: - project_name: Icons base_path: ./src dotnet: true + - project_name: Server + base_path: ./util + dotnet: true - project_name: Identity base_path: ./src dotnet: true From 3f7b695aeff90f85966ed40fbd5b56b07de00b4b Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Wed, 21 May 2025 13:44:02 -0700 Subject: [PATCH 39/41] add 'check branch' back --- .github/workflows/build.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4f2cb38246d1..17414edc4ee8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -106,6 +106,13 @@ jobs: with: ref: ${{ github.event.pull_request.head.sha }} + - name: Check branch to publish + env: + PUBLISH_BRANCHES: "main,rc,hotfix-rc" + id: publish-branch-check + run: | + IFS="," read -a publish_branches <<< $PUBLISH_BRANCHES + - name: Set up .NET uses: actions/setup-dotnet@87b7050bc53ea08284295505d98d2aa94301e852 # v4.2.0 From 11aa37dae5d2df15ed818d53f13ebf2f28481813 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Wed, 21 May 2025 13:45:02 -0700 Subject: [PATCH 40/41] Update build.yml --- .github/workflows/build.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 17414edc4ee8..55f6e06a6755 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -113,6 +113,12 @@ jobs: run: | IFS="," read -a publish_branches <<< $PUBLISH_BRANCHES + if [[ " ${publish_branches[*]} " =~ " ${GITHUB_REF:11} " ]]; then + echo "is_publish_branch=true" >> $GITHUB_ENV + else + echo "is_publish_branch=false" >> $GITHUB_ENV + fi + - name: Set up .NET uses: actions/setup-dotnet@87b7050bc53ea08284295505d98d2aa94301e852 # v4.2.0 From 26e188291655415a2f9e9fe4caa95443313a9412 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Wed, 21 May 2025 14:09:25 -0700 Subject: [PATCH 41/41] Update build.yml --- .github/workflows/build.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 55f6e06a6755..614adbd0404b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -67,9 +67,6 @@ jobs: - project_name: Icons base_path: ./src dotnet: true - - project_name: Server - base_path: ./util - dotnet: true - project_name: Identity base_path: ./src dotnet: true