From a37e8a5ccb5b13e5f13fba4c8d9270a58147ef51 Mon Sep 17 00:00:00 2001 From: Ash Davies <3853061+DrizzlyOwl@users.noreply.github.com> Date: Tue, 17 Dec 2024 12:40:51 +0000 Subject: [PATCH 1/3] Use Azure Linux docker image - This enables us to make use of upstream Microsoft patches - Also runs as a non-root user - Removed initContainer for the time being --- Dockerfile | 78 ++++++++++++++++++++++-------------------------------- 1 file changed, 32 insertions(+), 46 deletions(-) diff --git a/Dockerfile b/Dockerfile index fea62db..e86c93a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,52 +1,38 @@ -ARG PROJECT_NAME="Dfe.Complete.Api" -ARG REPO_ORIGIN="https://github.com/DFE-Digital/rsd-ddd-clean-architecture" -ARG DOTNET_SDK_TAG=8.0 -ARG DOTNET_EF_TAG=8.0.8 -ARG DOTNET_ASPNET_TAG=8.0-bookworm-slim -ARG NUGET_SOURCE="https://nuget.pkg.github.com/DFE-Digital/index.json" -ARG CI +# Set the major version of dotnet +ARG DOTNET_VERSION=8.0 +# Set the major version of nodejs +ARG NODEJS_VERSION_MAJOR=22 -# ============================================== -# Base SDK -# ============================================== -FROM "mcr.microsoft.com/dotnet/sdk:${DOTNET_SDK_TAG}" AS builder -ENV CI=${CI} -WORKDIR /build -COPY . . -RUN --mount=type=secret,id=github_token dotnet nuget add source --username USERNAME --password $(cat /run/secrets/github_token) --store-password-in-clear-text --name github ${NUGET_SOURCE} -RUN dotnet restore ${PROJECT_NAME} -RUN dotnet build -c Release ${PROJECT_NAME} -p:CI=${CI} -RUN dotnet publish ${PROJECT_NAME} -c Release -o /app --no-build +# Build assets +FROM "node:${NODEJS_VERSION_MAJOR}-bullseye-slim" AS assets +WORKDIR /app +COPY ./src/Frontend/Dfe.Complete/wwwroot /app +RUN npm install +RUN npm run build -# ============================================== -# Entity Framework: Migration Builder -# ============================================== -FROM builder AS efbuilder +# Build the app using the dotnet SDK +FROM "mcr.microsoft.com/dotnet/sdk:${DOTNET_VERSION}-azurelinux3.0" AS build WORKDIR /build -ENV PATH=$PATH:/root/.dotnet/tools -RUN dotnet tool install --global dotnet-ef --version ${DOTNET_EF_TAG} -RUN mkdir /sql -RUN dotnet ef migrations bundle -r linux-x64 --configuration Release -p ${PROJECT_NAME} --no-build -o /sql/migratedb +COPY ./Dfe.Complete.sln /build +COPY ./Directory.Build.props /build +COPY ./src/ /build/src +COPY ./script/docker-entrypoint.sh /app/docker-entrypoint.sh -# ============================================== -# Entity Framework: Migration Runner -# ============================================== -FROM "mcr.microsoft.com/dotnet/aspnet:${DOTNET_ASPNET_TAG}" AS initcontainer -WORKDIR /sql -COPY --from=efbuilder /sql /sql -COPY --from=builder /app/appsettings* /${PROJECT_NAME}/ +# Mount GitHub Token as a Docker secret so that NuGet Feed can be accessed +RUN --mount=type=secret,id=github_token dotnet nuget add source --username USERNAME --password $(cat /run/secrets/github_token) --store-password-in-clear-text --name github "https://nuget.pkg.github.com/DFE-Digital/index.json" -# ============================================== -# Application -# ============================================== -FROM "mcr.microsoft.com/dotnet/aspnet:${DOTNET_ASPNET_TAG}" AS final -LABEL org.opencontainers.image.source=${REPO_ORIGIN} -ARG COMMIT_SHA -COPY --from=builder /app /app -COPY ./script/docker-entrypoint.sh /app/docker-entrypoint.sh +RUN ["dotnet", "restore", "Dfe.Complete.sln"] +WORKDIR /build/src/Frontend/Dfe.Complete/ +RUN ["dotnet", "build", "--no-restore", "-c", "Release"] +RUN ["dotnet", "publish", "--no-build", "-o", "/app"] + +# Build a runtime environment +FROM "mcr.microsoft.com/dotnet/aspnet:${DOTNET_VERSION}-azurelinux3.0" AS base WORKDIR /app -RUN chown -R app:app /app -RUN chmod +x ./docker-entrypoint.sh -USER app -ENV ASPNETCORE_HTTP_PORTS 80 -EXPOSE 80/tcp +LABEL org.opencontainers.image.source="https://github.com/DFE-Digital/complete-api" + +COPY --from=build /app /app +COPY --from=assets /app /app/wwwroot +RUN ["chmod", "+x", "./docker-entrypoint.sh"] + +USER $APP_UID From 4b0dd329c0fb7439d100dd17b39c670939ff1ba9 Mon Sep 17 00:00:00 2001 From: Ash Davies <3853061+DrizzlyOwl@users.noreply.github.com> Date: Tue, 17 Dec 2024 12:43:00 +0000 Subject: [PATCH 2/3] Update Workflow to match new image --- .github/workflows/docker-test.yml | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/.github/workflows/docker-test.yml b/.github/workflows/docker-test.yml index cc85f49..167cbc1 100644 --- a/.github/workflows/docker-test.yml +++ b/.github/workflows/docker-test.yml @@ -13,14 +13,6 @@ on: jobs: build: runs-on: ubuntu-latest - strategy: - matrix: - stage: [ - "final", - "initcontainer" - ] - outputs: - image: ${{ steps.build.outputs.imageid }} steps: - name: Checkout code uses: actions/checkout@v4 @@ -33,8 +25,6 @@ jobs: id: build with: secrets: github_token=${{ secrets.GITHUB_TOKEN }} - load: true cache-from: type=gha cache-to: type=gha - target: ${{ matrix.stage }} push: false From 40c5d3727610d68b1fe25fb59d4740cefcbc944a Mon Sep 17 00:00:00 2001 From: Ash Davies <3853061+DrizzlyOwl@users.noreply.github.com> Date: Tue, 17 Dec 2024 12:46:31 +0000 Subject: [PATCH 3/3] Added Docker CVE scanner workflow and renamed old test file to -build.yml --- .github/workflows/docker-build.yml | 30 +++++++++++++++++++++++++ .github/workflows/docker-test.yml | 36 ++++++++++++++++++++++-------- 2 files changed, 57 insertions(+), 9 deletions(-) create mode 100644 .github/workflows/docker-build.yml diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml new file mode 100644 index 0000000..167cbc1 --- /dev/null +++ b/.github/workflows/docker-build.yml @@ -0,0 +1,30 @@ +name: Dockerfile + +on: + push: + branches: main + paths: + - Dockerfile + pull_request: + paths: + - Dockerfile + types: [opened, synchronize] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Build Docker image + uses: docker/build-push-action@v6 + id: build + with: + secrets: github_token=${{ secrets.GITHUB_TOKEN }} + cache-from: type=gha + cache-to: type=gha + push: false diff --git a/.github/workflows/docker-test.yml b/.github/workflows/docker-test.yml index 167cbc1..f684461 100644 --- a/.github/workflows/docker-test.yml +++ b/.github/workflows/docker-test.yml @@ -1,18 +1,15 @@ -name: Dockerfile +name: Docker on: push: branches: main - paths: - - Dockerfile - pull_request: - paths: - - Dockerfile - types: [opened, synchronize] jobs: - build: + scan: + name: Scan for CVEs runs-on: ubuntu-latest + outputs: + image: ${{ steps.build.outputs.imageid }} steps: - name: Checkout code uses: actions/checkout@v4 @@ -20,11 +17,32 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - - name: Build Docker image + - name: Build docker image uses: docker/build-push-action@v6 id: build with: secrets: github_token=${{ secrets.GITHUB_TOKEN }} + load: true cache-from: type=gha cache-to: type=gha push: false + + - name: Export docker image as tar + run: docker save -o ${{ github.ref_name }}.tar ${{ steps.build.outputs.imageid }} + + - name: Scan Docker image for CVEs + uses: aquasecurity/trivy-action@0.24.0 + with: + input: ${{ github.ref_name }}.tar + format: 'sarif' + output: 'trivy-results.sarif' + limit-severities-for-sarif: true + ignore-unfixed: true + severity: 'CRITICAL,HIGH' + github-pat: ${{ secrets.GITHUB_TOKEN }} + + - name: Upload scan results to GitHub Security + uses: github/codeql-action/upload-sarif@v2 + if: always() + with: + sarif_file: 'trivy-results.sarif'