Add Docker arm64 builds
đ Objective
This PR modifies all of the Dockerfiles in this repository to use multi-stage builds. This is very similar to the logic used to build the container image for Bitwarden Unified. Making this change enables us to build for multiple architectures. I have specified the architectures linux/amd64, linux/arm64, and linux/arm/v7 in this PR.
â° Reminders before review
- Contributor guidelines followed
- All formatters and local linters executed and passed
- Written new unit and / or integration tests where applicable
- Protected functional changes with optionality (feature flags)
- Used internationalization (i18n) for all UI strings
- CI builds passed
- Communicated to DevOps any deployment requirements
- Updated any necessary documentation (Confluence, contributing docs) or informed the documentation team
đĻŽ Reviewer guidelines
- đ (
:+1:) or similar for great changes - đ (
:memo:) or âšī¸ (:information_source:) for notes or general info - â (
:question:) for questions - đ¤ (
:thinking:) or đ (:thought_balloon:) for more open inquiry that's not quite a confirmed issue and could potentially benefit from discussion - đ¨ (
:art:) for suggestions / improvements - â (
:x:) or â ī¸ (:warning:) for more significant problems or concerns needing attention - đą (
:seedling:) or âģī¸ (:recycle:) for future improvements or indications of technical debt - â (
:pick:) for minor or nitpick changes
Checkmarx One â Scan Summary & Details â 989126ed-281e-418d-8c5e-8fd2b9d414bc
Great job, no security vulnerabilities found in this Pull Request
Codecov Report
:white_check_mark: All modified and coverable lines are covered by tests.
:white_check_mark: Project coverage is 47.27%. Comparing base (5700347) to head (3eb40f7).
:warning: Report is 327 commits behind head on main.
Additional details and impacted files
@@ Coverage Diff @@
## main #5529 +/- ##
==========================================
- Coverage 47.28% 47.27% -0.01%
==========================================
Files 1645 1645
Lines 74695 74695
Branches 6723 6723
==========================================
- Hits 35316 35313 -3
- Misses 37921 37923 +2
- Partials 1458 1459 +1
:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.
:rocket: New features to boost your workflow:
- :snowflake: Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
- :package: JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.
This pull request sets up GitHub code scanning for this repository. Once the scans have completed and the checks have passed, the analysis results for this pull request branch will appear on this overview. Once you merge this pull request, the 'Security' tab will show more code scanning analysis results (for example, for the default branch). Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results. For more information about GitHub code scanning, check out the documentation.
LGMT, though I am not a SME on our Dockerfiles. Those CVE alerts seem out of place and are clearly unrelated. Any idea what's triggering them @vgrassia ?
I have no idea why those CVE alerts are happening. They all point to the first line in the Dockerfiles which is a stylized comment block.
LGMT, though I am not a SME on our Dockerfiles. Those CVE alerts seem out of place and are clearly unrelated. Any idea what's triggering them @vgrassia ?
I have no idea why those CVE alerts are happening. They all point to the first line in the Dockerfiles which is a stylized comment block.
Hi!
We recently fixed the reporting of Checkmarx data in PRs to upload the SARIF to the proper branch. Because of this, it's now allowing GitHub to show the vulnerabilities line by line outside of Checkmarx. However, the Checkmarx Container scanning reports to the individual Dockerfile, not to a specific line, so it's defaulting to the first line, which isn't super great as a display. So you just hadn't seen these before, because it wasn't uploading properly, but the vulns are not necessarily new.
The CVE vulns are affecting these Dockerfiles, mainly because the final container is using FROM mcr.microsoft.com/dotnet/aspnet:8.0 as an example. This image has a number of vulnerabilities that are existing in a number of our containers. I've been pushing to move to a distroless/rootless setup for these images to help reduce them, but it's a work in progress. See this for an example I was able to migrate to mcr.microsoft.com/dotnet/aspnet:9.0.3-azurelinux3.0-distroless which has 0 vulns.
You can see the vulnerabilities in these images using multiple tools:
Grype
grype mcr.microsoft.com/dotnet/aspnet:8.0
Trivy
trivy image mcr.microsoft.com/dotnet/aspnet:8.0
Docker Scout
docker scout cves mcr.microsoft.com/dotnet/aspnet:8.0
You'll see a multitude of CVEs listed in each tool. For example:
If you're in there making changes to our Dockerfiles, you might consider it a good time to update to a newer image, or select a rootless/distroless or more minimal image as the final image. I'm happy to chat offline about it as well, as it's a current project.
I started looking at the Dockerfile files for this one, to see how it would be affected.
The first one in the list was for bitwarden_license/src/Scim/Dockerfile, which I'm using as an example. I converted it to using mcr.microsoft.com/dotnet/aspnet:8.0.15-azurelinux3.0-distroless as the final image. I haven't yet done the kerberos work for it (I may have to chat to someone who knows more on this topic), so this is definitely not finalized, but it's at least promising so far:
Potential replacement Dockerfile:
###############################################
# Build stage #
###############################################
FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:8.0 AS build
USER root
# 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 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 .editorconfig .
# Restore project dependencies and tools
WORKDIR /source/bitwarden_license/src/Scim
RUN . /tmp/rid.txt && dotnet restore -r $RID
# Copy required project files
WORKDIR /source
COPY 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/
# Build project
WORKDIR /source/bitwarden_license/src/Scim
RUN . /tmp/rid.txt && dotnet publish -c release -o /app/Scim --no-restore --no-self-contained -r $RID
# Update CAs (if applicable)
RUN find /etc/ -path /etc/bitwarden/ca-certificates/* -name *.crt -exec cp {} /usr/local/share/ca-certificates/ \; 2>/dev/null \
&& update-ca-certificates
# Handle Kerberos config
# TODO: Dockerize this script from entrypoint.sh:
# TODO: Maybe install krb5-user in the build script, and initialize kerberos, then copy any relevant krb files in the creation of the final image?
# 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
# fi
WORKDIR /app
###############################################
# App stage #
###############################################
FROM mcr.microsoft.com/dotnet/aspnet:8.0.15-azurelinux3.0-distroless
USER app
ARG TARGETPLATFORM
LABEL com.bitwarden.product="bitwarden"
ENV ASPNETCORE_ENVIRONMENT=Production
ENV ASPNETCORE_URLS=http://+:5000
EXPOSE 5000
# Copy app from the build stage
WORKDIR /app
COPY --from=build /app/Scim ./
COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
# Use alexaka1's distroless healthcheck to avoid installing curl in image
COPY --from=ghcr.io/alexaka1/distroless-dotnet-healthchecks:1 / /healthchecks
HEALTHCHECK CMD ["/healthchecks/Distroless.HealthChecks", "--uri", "http://localhost:5000/alive"]
ENTRYPOINT ["dotnet", "/app/Scim.dll"]
With that configuration (minus the krb portion), it goes to 0 vulns in Grype (and likely Checkmarx):
grype bitwarden/server-bitwarden_license-scim:distroless
â Loaded image bitwarden/server-bitwarden_license-scim:distroless
â Parsed image sha256:bfc126331c46551f7da8a24a0fd0c22b854a90b6a16121c0371166e5
â Cataloged contents fa4e727c7b6efce6fa296beabca36851722cf12b195a4c9b57d9445b7c700c2
âââ â Packages [156 packages]
âââ â File metadata [504 locations]
âââ â Executables [528 executables]
âââ â File digests [504 files]
â Scanned for vulnerabilities [0 vulnerability matches]
âââ by severity: 0 critical, 0 high, 0 medium, 0 low, 0 negligible
âââ by status: 0 fixed, 0 not-fixed, 0 ignored
No vulnerabilities found
This would significantly reduce the attack surface of our docker images, although would require additional work for each Dockerfile. But if we're already working through all of them, it could be a good time to rip off this bandaid.
Quality Gate passed
Issues
34 New issues
0 Accepted issues
Measures
3 Security Hotspots
0.0% Coverage on New Code
0.0% Duplication on New Code
@vgrassia I just happen to see this PR since I was tagged on it for review. is this still relevant? looks like @mandreko-bitwarden's latest comment has since been resolved by some other initiatives we worked on.