From a4b27d05150414ed0dece3edbca1402d6dd42b35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=B6rner?= Date: Thu, 25 Dec 2025 10:01:02 +0100 Subject: [PATCH 01/13] Move Dockerfile to new folder --- .../turnierplan/amd64}/Dockerfile | 9 ++++----- .../Client/cypress/docker/docker-compose.yaml | 4 ++-- src/Turnierplan.App/Turnierplan.App.csproj | 6 ------ 3 files changed, 6 insertions(+), 13 deletions(-) rename {src/Turnierplan.App => docker/turnierplan/amd64}/Dockerfile (90%) diff --git a/src/Turnierplan.App/Dockerfile b/docker/turnierplan/amd64/Dockerfile similarity index 90% rename from src/Turnierplan.App/Dockerfile rename to docker/turnierplan/amd64/Dockerfile index 6115e3fe..94e1bd0a 100644 --- a/src/Turnierplan.App/Dockerfile +++ b/docker/turnierplan/amd64/Dockerfile @@ -1,13 +1,12 @@ -FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS base +FROM mcr.microsoft.com/dotnet/aspnet:10.0.1-noble-amd64 AS base -# Where are the files stored in the container? This folder should be mapped as a volume +# Where are the files stored inside the container? This folder should be mapped as a volume ARG DATA_DIRECTORY=/var/turnierplan -FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build +FROM mcr.microsoft.com/dotnet/sdk:10.0.101-noble-amd64 AS build # Copy the source files and build the solution. -WORKDIR /src -COPY . . +COPY src /src/ WORKDIR "/src/Turnierplan.App" RUN dotnet build "./Turnierplan.App.csproj" -c Release -o /app/build diff --git a/src/Turnierplan.App/Client/cypress/docker/docker-compose.yaml b/src/Turnierplan.App/Client/cypress/docker/docker-compose.yaml index b306079b..855a0039 100644 --- a/src/Turnierplan.App/Client/cypress/docker/docker-compose.yaml +++ b/src/Turnierplan.App/Client/cypress/docker/docker-compose.yaml @@ -3,8 +3,8 @@ services: turnierplan.e2e.application: build: - dockerfile: 'Turnierplan.App/Dockerfile' - context: '../../../../' + dockerfile: 'docker/turnierplan/amd64/Dockerfile' + context: '../../../../../' ports: - "45001:8080" environment: diff --git a/src/Turnierplan.App/Turnierplan.App.csproj b/src/Turnierplan.App/Turnierplan.App.csproj index b1897606..751f1ef2 100644 --- a/src/Turnierplan.App/Turnierplan.App.csproj +++ b/src/Turnierplan.App/Turnierplan.App.csproj @@ -33,12 +33,6 @@ - - - .dockerignore - - - From 5429559c1b45351dfb1975d30fdca69d0c9bf6eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=B6rner?= Date: Thu, 25 Dec 2025 10:03:12 +0100 Subject: [PATCH 02/13] Update build workflow --- .github/workflows/build.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 587ef2c4..a69d5f57 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -51,8 +51,8 @@ jobs: - name: 'Build and push container image' uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4 with: - context: ./src - file: ./src/Turnierplan.App/Dockerfile + context: . + file: ./docker/turnierplan/amd64/Dockerfile push: true # Note: Always push "latest" even when building from a non-main branch. This is because currently, no patches are released for a non-latest minor release. tags: 'ghcr.io/turnierplan-net/turnierplan:latest,ghcr.io/turnierplan-net/turnierplan:${{ needs.extract-version.outputs.turnierplan_version }}' From a6486f80dd84cc238f908eb4e63018738ebe2dd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=B6rner?= Date: Thu, 25 Dec 2025 10:27:07 +0100 Subject: [PATCH 03/13] Use alpine in amd64 image --- docker/turnierplan/amd64/Dockerfile | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/docker/turnierplan/amd64/Dockerfile b/docker/turnierplan/amd64/Dockerfile index 94e1bd0a..06f63022 100644 --- a/docker/turnierplan/amd64/Dockerfile +++ b/docker/turnierplan/amd64/Dockerfile @@ -1,4 +1,4 @@ -FROM mcr.microsoft.com/dotnet/aspnet:10.0.1-noble-amd64 AS base +FROM mcr.microsoft.com/dotnet/aspnet:10.0.1-alpine3.23-amd64 AS base # Where are the files stored inside the container? This folder should be mapped as a volume ARG DATA_DIRECTORY=/var/turnierplan @@ -20,16 +20,11 @@ RUN dotnet publish "./Turnierplan.App.csproj" -c Release --runtime linux-x64 -o FROM base AS final -# Since .NET 8, the official container image no longer includes the 'Kerberos' package. Since Npgsql 10.0, an -# error is shown upon startup if that package is not installed. Because of this, we install the package manually. -# The official documentation states you have to install the 'libkrb5-3' package: -# - https://learn.microsoft.com/en-us/dotnet/core/compatibility/containers/8.0/krb5-libs-package -# However, this seems to have no effect. By digging in the 'dotnet-docker' repository, you can find the Dockerfile -# used for the .NET 6 images which states the 'libgssapi-krb5-2' package which is installed below. -# - source: https://github.com/dotnet/dotnet-docker/blob/0a4258cc250885be5162d01f178bff5c856291f4/src/runtime-deps/6.0/jammy/amd64/Dockerfile -RUN apt-get update \ - && apt-get -y install libgssapi-krb5-2 \ - && rm -rf /var/lib/apt/lists/* +# Install some packages: +# - 'gcompat' to run QuestPDF dependencies on Alpine Linux +# - 'krb5-libs' to enable Npgsql GSS session encryption +# - 'tzdata' contains relevant time zone information +RUN apk add gcompat krb5-libs tzdata # Prepare the directory used by the turnierplan.NET application RUN mkdir "$DATA_DIRECTORY" && chown "$APP_UID" "$DATA_DIRECTORY" From cf18532307044a329f8a7db6c7c23bb801e6b442 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=B6rner?= Date: Thu, 25 Dec 2025 10:28:09 +0100 Subject: [PATCH 04/13] Simplify folder structure --- .github/workflows/build.yaml | 2 +- docker/{turnierplan/amd64 => turnierplan-amd64}/Dockerfile | 0 src/Turnierplan.App/Client/cypress/docker/docker-compose.yaml | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename docker/{turnierplan/amd64 => turnierplan-amd64}/Dockerfile (100%) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index a69d5f57..6af42a30 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -52,7 +52,7 @@ jobs: uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4 with: context: . - file: ./docker/turnierplan/amd64/Dockerfile + file: ./docker/turnierplan-amd64/Dockerfile push: true # Note: Always push "latest" even when building from a non-main branch. This is because currently, no patches are released for a non-latest minor release. tags: 'ghcr.io/turnierplan-net/turnierplan:latest,ghcr.io/turnierplan-net/turnierplan:${{ needs.extract-version.outputs.turnierplan_version }}' diff --git a/docker/turnierplan/amd64/Dockerfile b/docker/turnierplan-amd64/Dockerfile similarity index 100% rename from docker/turnierplan/amd64/Dockerfile rename to docker/turnierplan-amd64/Dockerfile diff --git a/src/Turnierplan.App/Client/cypress/docker/docker-compose.yaml b/src/Turnierplan.App/Client/cypress/docker/docker-compose.yaml index 855a0039..bec915aa 100644 --- a/src/Turnierplan.App/Client/cypress/docker/docker-compose.yaml +++ b/src/Turnierplan.App/Client/cypress/docker/docker-compose.yaml @@ -3,7 +3,7 @@ services: turnierplan.e2e.application: build: - dockerfile: 'docker/turnierplan/amd64/Dockerfile' + dockerfile: 'docker/turnierplan-amd64/Dockerfile' context: '../../../../../' ports: - "45001:8080" From 7d761a297c694e276dc108d7f35dc0b38bad70c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=B6rner?= Date: Thu, 25 Dec 2025 10:32:00 +0100 Subject: [PATCH 05/13] Add arm64 dockerfile which may or may not work --- docker/turnierplan-arm64v8/Dockerfile | 46 +++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 docker/turnierplan-arm64v8/Dockerfile diff --git a/docker/turnierplan-arm64v8/Dockerfile b/docker/turnierplan-arm64v8/Dockerfile new file mode 100644 index 00000000..ff32b8b8 --- /dev/null +++ b/docker/turnierplan-arm64v8/Dockerfile @@ -0,0 +1,46 @@ +FROM mcr.microsoft.com/dotnet/aspnet:10.0.1-alpine3.23-arm64v8 AS base + +# Where are the files stored inside the container? This folder should be mapped as a volume +ARG DATA_DIRECTORY=/var/turnierplan + +FROM mcr.microsoft.com/dotnet/sdk:10.0.101-noble-arm64v8 AS build + +# Copy the source files and build the solution. +COPY src /src/ +WORKDIR "/src/Turnierplan.App" +RUN dotnet build "./Turnierplan.App.csproj" -c Release -o /app/build + +FROM build AS publish + +# Install nodejs, this is required for the client app build which is part of the dotnet publish. +RUN curl -fsSL https://deb.nodesource.com/setup_24.x | bash - && apt-get install -y nodejs + +# Publish the solution. By specifying the publish runtime 'linux-arm64', no unnecessary native libraries are included in the image +RUN dotnet publish "./Turnierplan.App.csproj" -c Release --runtime linux-arm64 -o /app/publish /p:UseAppHost=false + +FROM base AS final + +# Install some packages: +# - 'gcompat' to run QuestPDF dependencies on Alpine Linux +# - 'krb5-libs' to enable Npgsql GSS session encryption +# - 'tzdata' contains relevant time zone information +RUN apk add gcompat krb5-libs tzdata + +# Prepare the directory used by the turnierplan.NET application +RUN mkdir "$DATA_DIRECTORY" && chown "$APP_UID" "$DATA_DIRECTORY" + +# Miscellaneous configurations +USER $APP_UID +WORKDIR /app +EXPOSE 8080 +EXPOSE 8081 + +# Copy the publish output i.e. the application binaries and the static web assets including the client application +COPY --from=publish /app/publish . + +# Set the environment variables based on the data directory +ENV Identity__StoragePath=$DATA_DIRECTORY/identity +ENV ImageStorage__StoragePath=$DATA_DIRECTORY/images + +# Entrypoint is the DLL of the Turnierplan.App project +ENTRYPOINT ["dotnet", "Turnierplan.App.dll"] From 526eb300313e87c093e12cda035174244bbda1f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=B6rner?= Date: Thu, 25 Dec 2025 10:35:06 +0100 Subject: [PATCH 06/13] Add arm64 e2e test workflow which may or may not work --- .github/workflows/validate.yaml | 29 +++++++++++++++++-- .../Client/cypress/docker/docker-compose.yaml | 12 +++++++- src/Turnierplan.App/Client/package.json | 3 +- 3 files changed, 39 insertions(+), 5 deletions(-) diff --git a/.github/workflows/validate.yaml b/.github/workflows/validate.yaml index 4411e655..944dba0d 100644 --- a/.github/workflows/validate.yaml +++ b/.github/workflows/validate.yaml @@ -72,8 +72,8 @@ jobs: if: ${{ env.RUN_SONARQUBE_ANALYSIS == 'true' }} run: 'dotnet-sonarscanner end /d:sonar.token="${{ secrets.SONAR_TOKEN }}"' working-directory: './src' - e2e: - name: 'E2E Tests' + e2e-amd64: + name: 'E2E Tests (amd64)' runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v2 @@ -87,7 +87,30 @@ jobs: run: 'npm ci' working-directory: './src/Turnierplan.App/Client/' - name: 'Prepare e2e test environment' - run: 'npm run e2e:prepare' + run: 'npm run e2e:prepare:amd64' + working-directory: './src/Turnierplan.App/Client/' + - name: 'Run e2e tests' + run: 'npm run e2e:run' + working-directory: './src/Turnierplan.App/Client/' + - name: 'Destroy e2e test environment' + run: 'npm run e2e:destroy' + working-directory: './src/Turnierplan.App/Client/' + e2e-arm64v8: + name: 'E2E Tests (arm64v8)' + runs-on: ubuntu-24.04-arm + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + - name: 'Setup Node.js 24.x' + uses: actions/setup-node@v3 + with: + node-version: '24.x' + - name: 'Install npm packages' + run: 'npm ci' + working-directory: './src/Turnierplan.App/Client/' + - name: 'Prepare e2e test environment' + run: 'npm run e2e:prepare:arm64v8' working-directory: './src/Turnierplan.App/Client/' - name: 'Run e2e tests' run: 'npm run e2e:run' diff --git a/src/Turnierplan.App/Client/cypress/docker/docker-compose.yaml b/src/Turnierplan.App/Client/cypress/docker/docker-compose.yaml index bec915aa..166b9082 100644 --- a/src/Turnierplan.App/Client/cypress/docker/docker-compose.yaml +++ b/src/Turnierplan.App/Client/cypress/docker/docker-compose.yaml @@ -1,7 +1,7 @@ # This docker compose file is used for running the E2E tests during the CI workflow services: - turnierplan.e2e.application: + turnierplan.e2e.application:amd64: build: dockerfile: 'docker/turnierplan-amd64/Dockerfile' context: '../../../../../' @@ -11,3 +11,13 @@ services: - Database__InMemory=true - Turnierplan__ApplicationUrl=http://localhost:45001 - Turnierplan__InitialUserPassword=P@ssw0rd + turnierplan.e2e.application:arm64v8: + build: + dockerfile: 'docker/turnierplan-arm64v8/Dockerfile' + context: '../../../../../' + ports: + - "45001:8080" + environment: + - Database__InMemory=true + - Turnierplan__ApplicationUrl=http://localhost:45001 + - Turnierplan__InitialUserPassword=P@ssw0rd diff --git a/src/Turnierplan.App/Client/package.json b/src/Turnierplan.App/Client/package.json index f22d77ee..d4c74a5c 100644 --- a/src/Turnierplan.App/Client/package.json +++ b/src/Turnierplan.App/Client/package.json @@ -21,7 +21,8 @@ "test:ci": "ng test --watch=false --source-map=true --code-coverage --browsers ChromeHeadless", "e2e:swap-environment": "replace-in-file \"environment.prod.ts\" \"environment.e2e.ts\" angular.json", "e2e:swap-environment-back": "replace-in-file \"environment.e2e.ts\" \"environment.prod.ts\" angular.json", - "e2e:prepare": "npm run e2e:swap-environment && docker compose -f cypress/docker/docker-compose.yaml up --build -d && npm run e2e:swap-environment-back", + "e2e:prepare:amd64": "npm run e2e:swap-environment && docker compose -f cypress/docker/docker-compose.yaml up --build -d turnierplan.e2e.application:amd64 && npm run e2e:swap-environment-back", + "e2e:prepare:arm64v8": "npm run e2e:swap-environment && docker compose -f cypress/docker/docker-compose.yaml up --build -d turnierplan.e2e.application:arm64v8 && npm run e2e:swap-environment-back", "e2e:destroy": "docker compose -f cypress/docker/docker-compose.yaml down", "e2e:open": "npx cypress open", "e2e:run": "npx cypress run" From 6c59a7d1ce80596a713913dfb2c1072f290ffc0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=B6rner?= Date: Thu, 25 Dec 2025 10:38:03 +0100 Subject: [PATCH 07/13] Fix docker compose --- src/Turnierplan.App/Client/cypress/docker/docker-compose.yaml | 4 ++-- src/Turnierplan.App/Client/package.json | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Turnierplan.App/Client/cypress/docker/docker-compose.yaml b/src/Turnierplan.App/Client/cypress/docker/docker-compose.yaml index 166b9082..4d2da3ad 100644 --- a/src/Turnierplan.App/Client/cypress/docker/docker-compose.yaml +++ b/src/Turnierplan.App/Client/cypress/docker/docker-compose.yaml @@ -1,7 +1,7 @@ # This docker compose file is used for running the E2E tests during the CI workflow services: - turnierplan.e2e.application:amd64: + turnierplan.e2e.application.amd64: build: dockerfile: 'docker/turnierplan-amd64/Dockerfile' context: '../../../../../' @@ -11,7 +11,7 @@ services: - Database__InMemory=true - Turnierplan__ApplicationUrl=http://localhost:45001 - Turnierplan__InitialUserPassword=P@ssw0rd - turnierplan.e2e.application:arm64v8: + turnierplan.e2e.application.arm64v8: build: dockerfile: 'docker/turnierplan-arm64v8/Dockerfile' context: '../../../../../' diff --git a/src/Turnierplan.App/Client/package.json b/src/Turnierplan.App/Client/package.json index d4c74a5c..b2d92705 100644 --- a/src/Turnierplan.App/Client/package.json +++ b/src/Turnierplan.App/Client/package.json @@ -21,8 +21,8 @@ "test:ci": "ng test --watch=false --source-map=true --code-coverage --browsers ChromeHeadless", "e2e:swap-environment": "replace-in-file \"environment.prod.ts\" \"environment.e2e.ts\" angular.json", "e2e:swap-environment-back": "replace-in-file \"environment.e2e.ts\" \"environment.prod.ts\" angular.json", - "e2e:prepare:amd64": "npm run e2e:swap-environment && docker compose -f cypress/docker/docker-compose.yaml up --build -d turnierplan.e2e.application:amd64 && npm run e2e:swap-environment-back", - "e2e:prepare:arm64v8": "npm run e2e:swap-environment && docker compose -f cypress/docker/docker-compose.yaml up --build -d turnierplan.e2e.application:arm64v8 && npm run e2e:swap-environment-back", + "e2e:prepare:amd64": "npm run e2e:swap-environment && docker compose -f cypress/docker/docker-compose.yaml up --build -d turnierplan.e2e.application.amd64 && npm run e2e:swap-environment-back", + "e2e:prepare:arm64v8": "npm run e2e:swap-environment && docker compose -f cypress/docker/docker-compose.yaml up --build -d turnierplan.e2e.application.arm64v8 && npm run e2e:swap-environment-back", "e2e:destroy": "docker compose -f cypress/docker/docker-compose.yaml down", "e2e:open": "npx cypress open", "e2e:run": "npx cypress run" From d648f1fbb7e88e2596778a35d96ef8ad29eb2061 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=B6rner?= Date: Thu, 25 Dec 2025 10:47:29 +0100 Subject: [PATCH 08/13] Build container image for arm64v8 --- .github/workflows/build.yaml | 35 +++++++++++++++++++++++++++++++-- .github/workflows/validate.yaml | 2 ++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 6af42a30..b35bb087 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -26,8 +26,8 @@ jobs: outputs: turnierplan_version: ${{ steps.extract-version.outputs.turnierplan_version }} - container-image: - name: 'Build container image' + container-image-amd64: + name: 'Build container image (amd64)' runs-on: ubuntu-24.04 permissions: contents: read @@ -57,6 +57,37 @@ jobs: # Note: Always push "latest" even when building from a non-main branch. This is because currently, no patches are released for a non-latest minor release. tags: 'ghcr.io/turnierplan-net/turnierplan:latest,ghcr.io/turnierplan-net/turnierplan:${{ needs.extract-version.outputs.turnierplan_version }}' + container-image-arm64v8: + name: 'Build container image (arm64v8)' + runs-on: ubuntu-24.04-arm + permissions: + contents: read + packages: write + needs: + - extract-version + steps: + - uses: actions/checkout@v2 + - name: 'Replace environment tokens' + uses: cschleiden/replace-tokens@v1 + with: + files: '["**/environment.prod.ts"]' + env: + TOKEN_APPLICATION_VERSION: "${{ needs.extract-version.outputs.turnierplan_version }}" + - name: Login to container registry + uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: 'Build and push container image' + uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4 + with: + context: . + file: ./docker/turnierplan-amd64/Dockerfile + push: true + # Note: Always push "latest-arm64v8" even when building from a non-main branch. This is because currently, no patches are released for a non-latest minor release. + tags: 'ghcr.io/turnierplan-net/turnierplan:latest-arm64v8,ghcr.io/turnierplan-net/turnierplan:${{ needs.extract-version.outputs.turnierplan_version }}-arm64v8' + nuget-package: name: 'Build NuGet package' runs-on: ubuntu-24.04 diff --git a/.github/workflows/validate.yaml b/.github/workflows/validate.yaml index 944dba0d..58e452a6 100644 --- a/.github/workflows/validate.yaml +++ b/.github/workflows/validate.yaml @@ -72,6 +72,7 @@ jobs: if: ${{ env.RUN_SONARQUBE_ANALYSIS == 'true' }} run: 'dotnet-sonarscanner end /d:sonar.token="${{ secrets.SONAR_TOKEN }}"' working-directory: './src' + e2e-amd64: name: 'E2E Tests (amd64)' runs-on: ubuntu-24.04 @@ -95,6 +96,7 @@ jobs: - name: 'Destroy e2e test environment' run: 'npm run e2e:destroy' working-directory: './src/Turnierplan.App/Client/' + e2e-arm64v8: name: 'E2E Tests (arm64v8)' runs-on: ubuntu-24.04-arm From ba2e9fcf088c056ed9db4495d76822072504b535 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=B6rner?= Date: Thu, 25 Dec 2025 18:44:58 +0100 Subject: [PATCH 09/13] Remove arm64v8 for now and add empty readme --- .github/workflows/build.yaml | 31 ------------- .github/workflows/validate.yaml | 24 ---------- README.md | 2 +- docker/README.md | 3 ++ docker/turnierplan-arm64v8/Dockerfile | 46 ------------------- .../Client/cypress/docker/docker-compose.yaml | 10 ---- src/Turnierplan.App/Client/package.json | 1 - 7 files changed, 4 insertions(+), 113 deletions(-) create mode 100644 docker/README.md delete mode 100644 docker/turnierplan-arm64v8/Dockerfile diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index b35bb087..31a0f3ed 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -57,37 +57,6 @@ jobs: # Note: Always push "latest" even when building from a non-main branch. This is because currently, no patches are released for a non-latest minor release. tags: 'ghcr.io/turnierplan-net/turnierplan:latest,ghcr.io/turnierplan-net/turnierplan:${{ needs.extract-version.outputs.turnierplan_version }}' - container-image-arm64v8: - name: 'Build container image (arm64v8)' - runs-on: ubuntu-24.04-arm - permissions: - contents: read - packages: write - needs: - - extract-version - steps: - - uses: actions/checkout@v2 - - name: 'Replace environment tokens' - uses: cschleiden/replace-tokens@v1 - with: - files: '["**/environment.prod.ts"]' - env: - TOKEN_APPLICATION_VERSION: "${{ needs.extract-version.outputs.turnierplan_version }}" - - name: Login to container registry - uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - name: 'Build and push container image' - uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4 - with: - context: . - file: ./docker/turnierplan-amd64/Dockerfile - push: true - # Note: Always push "latest-arm64v8" even when building from a non-main branch. This is because currently, no patches are released for a non-latest minor release. - tags: 'ghcr.io/turnierplan-net/turnierplan:latest-arm64v8,ghcr.io/turnierplan-net/turnierplan:${{ needs.extract-version.outputs.turnierplan_version }}-arm64v8' - nuget-package: name: 'Build NuGet package' runs-on: ubuntu-24.04 diff --git a/.github/workflows/validate.yaml b/.github/workflows/validate.yaml index 58e452a6..e0b7ba61 100644 --- a/.github/workflows/validate.yaml +++ b/.github/workflows/validate.yaml @@ -96,27 +96,3 @@ jobs: - name: 'Destroy e2e test environment' run: 'npm run e2e:destroy' working-directory: './src/Turnierplan.App/Client/' - - e2e-arm64v8: - name: 'E2E Tests (arm64v8)' - runs-on: ubuntu-24.04-arm - steps: - - uses: actions/checkout@v2 - with: - fetch-depth: 0 - - name: 'Setup Node.js 24.x' - uses: actions/setup-node@v3 - with: - node-version: '24.x' - - name: 'Install npm packages' - run: 'npm ci' - working-directory: './src/Turnierplan.App/Client/' - - name: 'Prepare e2e test environment' - run: 'npm run e2e:prepare:arm64v8' - working-directory: './src/Turnierplan.App/Client/' - - name: 'Run e2e tests' - run: 'npm run e2e:run' - working-directory: './src/Turnierplan.App/Client/' - - name: 'Destroy e2e test environment' - run: 'npm run e2e:destroy' - working-directory: './src/Turnierplan.App/Client/' diff --git a/README.md b/README.md index 8fa5a9ee..4ce20359 100644 --- a/README.md +++ b/README.md @@ -163,7 +163,7 @@ If you have an Entra ID app registration with the necessary permissions on the s ## Documentation -The developer documentation of **turnierplan.NET** is located in the `docs` directory of this repository. +The developer documentation of **turnierplan.NET** is located in the `docs` directory of this repository. Information about the container images and how to build them can be found in the [README.md in the docker folder](./docker/README.md). ## Development diff --git a/docker/README.md b/docker/README.md new file mode 100644 index 00000000..ec23811d --- /dev/null +++ b/docker/README.md @@ -0,0 +1,3 @@ +# turnierplan.NET · Docker Images + +### TODO: Write this documentation diff --git a/docker/turnierplan-arm64v8/Dockerfile b/docker/turnierplan-arm64v8/Dockerfile deleted file mode 100644 index ff32b8b8..00000000 --- a/docker/turnierplan-arm64v8/Dockerfile +++ /dev/null @@ -1,46 +0,0 @@ -FROM mcr.microsoft.com/dotnet/aspnet:10.0.1-alpine3.23-arm64v8 AS base - -# Where are the files stored inside the container? This folder should be mapped as a volume -ARG DATA_DIRECTORY=/var/turnierplan - -FROM mcr.microsoft.com/dotnet/sdk:10.0.101-noble-arm64v8 AS build - -# Copy the source files and build the solution. -COPY src /src/ -WORKDIR "/src/Turnierplan.App" -RUN dotnet build "./Turnierplan.App.csproj" -c Release -o /app/build - -FROM build AS publish - -# Install nodejs, this is required for the client app build which is part of the dotnet publish. -RUN curl -fsSL https://deb.nodesource.com/setup_24.x | bash - && apt-get install -y nodejs - -# Publish the solution. By specifying the publish runtime 'linux-arm64', no unnecessary native libraries are included in the image -RUN dotnet publish "./Turnierplan.App.csproj" -c Release --runtime linux-arm64 -o /app/publish /p:UseAppHost=false - -FROM base AS final - -# Install some packages: -# - 'gcompat' to run QuestPDF dependencies on Alpine Linux -# - 'krb5-libs' to enable Npgsql GSS session encryption -# - 'tzdata' contains relevant time zone information -RUN apk add gcompat krb5-libs tzdata - -# Prepare the directory used by the turnierplan.NET application -RUN mkdir "$DATA_DIRECTORY" && chown "$APP_UID" "$DATA_DIRECTORY" - -# Miscellaneous configurations -USER $APP_UID -WORKDIR /app -EXPOSE 8080 -EXPOSE 8081 - -# Copy the publish output i.e. the application binaries and the static web assets including the client application -COPY --from=publish /app/publish . - -# Set the environment variables based on the data directory -ENV Identity__StoragePath=$DATA_DIRECTORY/identity -ENV ImageStorage__StoragePath=$DATA_DIRECTORY/images - -# Entrypoint is the DLL of the Turnierplan.App project -ENTRYPOINT ["dotnet", "Turnierplan.App.dll"] diff --git a/src/Turnierplan.App/Client/cypress/docker/docker-compose.yaml b/src/Turnierplan.App/Client/cypress/docker/docker-compose.yaml index 4d2da3ad..8cbdf49e 100644 --- a/src/Turnierplan.App/Client/cypress/docker/docker-compose.yaml +++ b/src/Turnierplan.App/Client/cypress/docker/docker-compose.yaml @@ -11,13 +11,3 @@ services: - Database__InMemory=true - Turnierplan__ApplicationUrl=http://localhost:45001 - Turnierplan__InitialUserPassword=P@ssw0rd - turnierplan.e2e.application.arm64v8: - build: - dockerfile: 'docker/turnierplan-arm64v8/Dockerfile' - context: '../../../../../' - ports: - - "45001:8080" - environment: - - Database__InMemory=true - - Turnierplan__ApplicationUrl=http://localhost:45001 - - Turnierplan__InitialUserPassword=P@ssw0rd diff --git a/src/Turnierplan.App/Client/package.json b/src/Turnierplan.App/Client/package.json index b2d92705..c5bb28f7 100644 --- a/src/Turnierplan.App/Client/package.json +++ b/src/Turnierplan.App/Client/package.json @@ -22,7 +22,6 @@ "e2e:swap-environment": "replace-in-file \"environment.prod.ts\" \"environment.e2e.ts\" angular.json", "e2e:swap-environment-back": "replace-in-file \"environment.e2e.ts\" \"environment.prod.ts\" angular.json", "e2e:prepare:amd64": "npm run e2e:swap-environment && docker compose -f cypress/docker/docker-compose.yaml up --build -d turnierplan.e2e.application.amd64 && npm run e2e:swap-environment-back", - "e2e:prepare:arm64v8": "npm run e2e:swap-environment && docker compose -f cypress/docker/docker-compose.yaml up --build -d turnierplan.e2e.application.arm64v8 && npm run e2e:swap-environment-back", "e2e:destroy": "docker compose -f cypress/docker/docker-compose.yaml down", "e2e:open": "npx cypress open", "e2e:run": "npx cypress run" From 1463e77029208186ed96e8e9e23c0a98a2e97745 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=B6rner?= Date: Sat, 10 Jan 2026 10:01:52 +0100 Subject: [PATCH 10/13] readme + 8081 --- docker/README.md | 14 +++++++++++++- docker/turnierplan-amd64/Dockerfile | 1 - 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/docker/README.md b/docker/README.md index ec23811d..64383526 100644 --- a/docker/README.md +++ b/docker/README.md @@ -1,3 +1,15 @@ # turnierplan.NET · Docker Images -### TODO: Write this documentation +Currently, there exists one Dockerfile with the `dotnet/aspnet:10.0-alpine` base image for the amd64 architecture. To build the container image, run the following command from the *repository root*: + +```shell +docker build -t turnierplan:dev -f docker/turnierplan-amd64/Dockerfile . +``` + +> ![WARNING] Manually built container images should not be used in production! This is because the relevant GitHub workflow performs other important steps before actually building the images. + +The resulting container image can be run as described in the [main readme](../README.md). The following minimal example uses an in-memory data store and does not mount any volumes: + +```shell +docker run -p 80:8080 -e Turnierplan__ApplicationUrl="http://localhost" -e Database__InMemory="true" turnierplan:dev +``` diff --git a/docker/turnierplan-amd64/Dockerfile b/docker/turnierplan-amd64/Dockerfile index 06f63022..0177b991 100644 --- a/docker/turnierplan-amd64/Dockerfile +++ b/docker/turnierplan-amd64/Dockerfile @@ -33,7 +33,6 @@ RUN mkdir "$DATA_DIRECTORY" && chown "$APP_UID" "$DATA_DIRECTORY" USER $APP_UID WORKDIR /app EXPOSE 8080 -EXPOSE 8081 # Copy the publish output i.e. the application binaries and the static web assets including the client application COPY --from=publish /app/publish . From 59480f2606193bc891c49981d229b5a0d9b64960 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=B6rner?= Date: Sat, 10 Jan 2026 10:03:52 +0100 Subject: [PATCH 11/13] syntax --- docker/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/README.md b/docker/README.md index 64383526..276bad5f 100644 --- a/docker/README.md +++ b/docker/README.md @@ -6,7 +6,7 @@ Currently, there exists one Dockerfile with the `dotnet/aspnet:10.0-alpine` base docker build -t turnierplan:dev -f docker/turnierplan-amd64/Dockerfile . ``` -> ![WARNING] Manually built container images should not be used in production! This is because the relevant GitHub workflow performs other important steps before actually building the images. +> [!WARNING] Manually built container images should not be used in production! This is because the relevant GitHub workflow performs other important steps before actually building the images. The resulting container image can be run as described in the [main readme](../README.md). The following minimal example uses an in-memory data store and does not mount any volumes: From a119e67e847209ae944586c60ec335ff21277a45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=B6rner?= Date: Sat, 10 Jan 2026 10:04:15 +0100 Subject: [PATCH 12/13] syntax --- docker/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docker/README.md b/docker/README.md index 276bad5f..ee6bcce5 100644 --- a/docker/README.md +++ b/docker/README.md @@ -6,7 +6,8 @@ Currently, there exists one Dockerfile with the `dotnet/aspnet:10.0-alpine` base docker build -t turnierplan:dev -f docker/turnierplan-amd64/Dockerfile . ``` -> [!WARNING] Manually built container images should not be used in production! This is because the relevant GitHub workflow performs other important steps before actually building the images. +> [!WARNING] +> Manually built container images should not be used in production! This is because the relevant GitHub workflow performs other important steps before actually building the images. The resulting container image can be run as described in the [main readme](../README.md). The following minimal example uses an in-memory data store and does not mount any volumes: From dea06a427c5eee813064ff3db01c7a79464fcdf9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=B6rner?= Date: Sat, 10 Jan 2026 10:04:35 +0100 Subject: [PATCH 13/13] order --- docker/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docker/README.md b/docker/README.md index ee6bcce5..078489c2 100644 --- a/docker/README.md +++ b/docker/README.md @@ -6,11 +6,11 @@ Currently, there exists one Dockerfile with the `dotnet/aspnet:10.0-alpine` base docker build -t turnierplan:dev -f docker/turnierplan-amd64/Dockerfile . ``` -> [!WARNING] -> Manually built container images should not be used in production! This is because the relevant GitHub workflow performs other important steps before actually building the images. - The resulting container image can be run as described in the [main readme](../README.md). The following minimal example uses an in-memory data store and does not mount any volumes: ```shell docker run -p 80:8080 -e Turnierplan__ApplicationUrl="http://localhost" -e Database__InMemory="true" turnierplan:dev ``` + +> [!WARNING] +> Manually built container images should not be used in production! This is because the relevant GitHub workflow performs other important steps before actually building the images.