Loading .gitlab-ci.template.yml→.gitlab-ci.yml +5 −6 Original line number Diff line number Diff line variables: NPM_REGISTRY_PROJECTID: "81583" PRIVATE_SSH_KEY: $ID_ECDSA_BASE64 IMAGE_TAG: $CI_REGISTRY_IMAGE CONTAINER_NAME_PREFIX: Visor CLOUDWATCH_LOG_GROUP: cals_Visor EXTERNAL_PORT: "5433" # define per environment if deploying prod/staging to same server CONTAINER_NAME_PREFIX: visor CLOUDWATCH_LOG_GROUP: visor EXTERNAL_PORT: "5434" # define per environment if deploying prod/staging to same server DOCKER_VERSION: "28.3.2" stages: Loading Loading @@ -49,7 +48,7 @@ deploy-staging-docker: AZURE_PFX_PASSWORD: $AZURE_PFXPASSWORD_STAGING DEPLOY_ENVIRONMENT: staging ASPNETCORE_ENVIRONMENT: Staging CLOUDWATCH_LOG_STREAM: staging CLOUDWATCH_LOG_STREAM: api_staging rules: - if: $CI_COMMIT_BRANCH == "staging" changes: Loading @@ -76,7 +75,7 @@ deploy-prod-docker: AZURE_PFX_PASSWORD: $AZURE_PFXPASSWORD_PROD DEPLOY_ENVIRONMENT: prod ASPNETCORE_ENVIRONMENT: Production CLOUDWATCH_LOG_STREAM: prod CLOUDWATCH_LOG_STREAM: api_prod rules: - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH changes: Loading Cals.Visor.sln +3 −3 Original line number Diff line number Diff line Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.5.33530.505 # Visual Studio Version 18 VisualStudioVersion = 18.0.11222.15 d18.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{FFCF88A3-E4D2-43DC-A729-C0E628CE47C9}" ProjectSection(SolutionItems) = preProject Loading Loading @@ -42,8 +42,8 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "deploy", "deploy", "{5755EAA3-A196-4ACC-B87C-549F6E6972E3}" ProjectSection(SolutionItems) = preProject .dockerignore = .dockerignore .gitlab-ci.template.yml = .gitlab-ci.template.yml docker-compose.yml = docker-compose.yml .gitlab-ci.yml = .gitlab-ci.yml Dockerfile = Dockerfile EndProjectSection EndProject Loading Dockerfile +7 −38 Original line number Diff line number Diff line # DOCKER LOCATION REFERENCES # /app/spa Directory containing appsettings.Development.json # /app/spa/ClientApp Directory containing Vite/Vue source code # /app/api Directory containing appsettings.Development.json # /src Directory containing solution (.sln) file # /src/src Directory containing src subfolder from .Net project # /src/src/spa Directory containing SPA ASP.NET project source files # /src/src/api Directory containing API ASP.NET project source files # /app/publish Directory containing compiled .Net executable and related files # /app/spa/wwwroot Directory containing compiled Vue files # /src/src/spa/wwwroot Directory containing compiled Vue files (after being copied over after npm build) # REMINDER: in a COPY command, the first path argument is RELATIVE TO THE REPO ROOT, # while the second path argument is RELATIVE TO THE MOST RECENT WORKDIR declaration # -------- Stage 1: Build frontend assets -------- FROM node:20-alpine AS frontend-builder # althought not use, it is referenced in vite.config.ts WORKDIR /app/src/spa COPY src/spa/appsettings.Development.json . # used in main.ts for Gtag information COPY src/spa/appsettings.json . WORKDIR /app/src/spa/ClientApp COPY src/spa/ClientApp/package*.json ./ # custom NPM regsitry information # TODO - GET TOKEN FROM ENVIRONMENT VARIABLE COPY .npmrc . RUN npm install COPY src/spa/ClientApp/ ./ RUN npm run build # Remove .npmrc as it contains sensitive informaition RUN rm -f .npmrc # -------- Stage 2: Build .NET app -------- # -------- Stage 1: Build .NET app -------- FROM mcr.microsoft.com/dotnet/sdk:8.0-alpine AS dotnet-builder WORKDIR /src Loading @@ -48,17 +20,14 @@ COPY ./nuget.config ./ COPY ./Directory.Build.* ./ # Copy only the project file and restore first for caching COPY src/spa/SPA.csproj src/spa/ COPY src/api/Api.csproj src/api/ RUN dotnet restore Cals.Visor.sln -p:Configuration=Release # Copy the remaining source code COPY src/ ./src/ # Copy built frontend assets to the project wwwroot COPY --from=frontend-builder /app/src/spa/wwwroot ./src/spa/wwwroot/ # Publish the project as self-contained for Alpine (musl) RUN dotnet publish src/spa/SPA.csproj \ RUN dotnet publish src/api/Api.csproj \ -c Release \ -r linux-musl-x64 \ --self-contained true \ Loading @@ -66,7 +35,7 @@ RUN dotnet publish src/spa/SPA.csproj \ -p:PublishSingleFile=true \ -o /app/publish # -------- Stage 3: Minimal Runtime -------- # -------- Stage 2: Minimal Runtime -------- FROM alpine:3.20 AS runtime WORKDIR /app Loading @@ -82,7 +51,7 @@ ENV ASPNETCORE_URLS=http://+:8080 EXPOSE 8080 # Run the app ENTRYPOINT ["./Cals.Visor.Spa"] ENTRYPOINT ["./Cals.Visor.Api"] Loading
.gitlab-ci.template.yml→.gitlab-ci.yml +5 −6 Original line number Diff line number Diff line variables: NPM_REGISTRY_PROJECTID: "81583" PRIVATE_SSH_KEY: $ID_ECDSA_BASE64 IMAGE_TAG: $CI_REGISTRY_IMAGE CONTAINER_NAME_PREFIX: Visor CLOUDWATCH_LOG_GROUP: cals_Visor EXTERNAL_PORT: "5433" # define per environment if deploying prod/staging to same server CONTAINER_NAME_PREFIX: visor CLOUDWATCH_LOG_GROUP: visor EXTERNAL_PORT: "5434" # define per environment if deploying prod/staging to same server DOCKER_VERSION: "28.3.2" stages: Loading Loading @@ -49,7 +48,7 @@ deploy-staging-docker: AZURE_PFX_PASSWORD: $AZURE_PFXPASSWORD_STAGING DEPLOY_ENVIRONMENT: staging ASPNETCORE_ENVIRONMENT: Staging CLOUDWATCH_LOG_STREAM: staging CLOUDWATCH_LOG_STREAM: api_staging rules: - if: $CI_COMMIT_BRANCH == "staging" changes: Loading @@ -76,7 +75,7 @@ deploy-prod-docker: AZURE_PFX_PASSWORD: $AZURE_PFXPASSWORD_PROD DEPLOY_ENVIRONMENT: prod ASPNETCORE_ENVIRONMENT: Production CLOUDWATCH_LOG_STREAM: prod CLOUDWATCH_LOG_STREAM: api_prod rules: - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH changes: Loading
Cals.Visor.sln +3 −3 Original line number Diff line number Diff line Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.5.33530.505 # Visual Studio Version 18 VisualStudioVersion = 18.0.11222.15 d18.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{FFCF88A3-E4D2-43DC-A729-C0E628CE47C9}" ProjectSection(SolutionItems) = preProject Loading Loading @@ -42,8 +42,8 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "deploy", "deploy", "{5755EAA3-A196-4ACC-B87C-549F6E6972E3}" ProjectSection(SolutionItems) = preProject .dockerignore = .dockerignore .gitlab-ci.template.yml = .gitlab-ci.template.yml docker-compose.yml = docker-compose.yml .gitlab-ci.yml = .gitlab-ci.yml Dockerfile = Dockerfile EndProjectSection EndProject Loading
Dockerfile +7 −38 Original line number Diff line number Diff line # DOCKER LOCATION REFERENCES # /app/spa Directory containing appsettings.Development.json # /app/spa/ClientApp Directory containing Vite/Vue source code # /app/api Directory containing appsettings.Development.json # /src Directory containing solution (.sln) file # /src/src Directory containing src subfolder from .Net project # /src/src/spa Directory containing SPA ASP.NET project source files # /src/src/api Directory containing API ASP.NET project source files # /app/publish Directory containing compiled .Net executable and related files # /app/spa/wwwroot Directory containing compiled Vue files # /src/src/spa/wwwroot Directory containing compiled Vue files (after being copied over after npm build) # REMINDER: in a COPY command, the first path argument is RELATIVE TO THE REPO ROOT, # while the second path argument is RELATIVE TO THE MOST RECENT WORKDIR declaration # -------- Stage 1: Build frontend assets -------- FROM node:20-alpine AS frontend-builder # althought not use, it is referenced in vite.config.ts WORKDIR /app/src/spa COPY src/spa/appsettings.Development.json . # used in main.ts for Gtag information COPY src/spa/appsettings.json . WORKDIR /app/src/spa/ClientApp COPY src/spa/ClientApp/package*.json ./ # custom NPM regsitry information # TODO - GET TOKEN FROM ENVIRONMENT VARIABLE COPY .npmrc . RUN npm install COPY src/spa/ClientApp/ ./ RUN npm run build # Remove .npmrc as it contains sensitive informaition RUN rm -f .npmrc # -------- Stage 2: Build .NET app -------- # -------- Stage 1: Build .NET app -------- FROM mcr.microsoft.com/dotnet/sdk:8.0-alpine AS dotnet-builder WORKDIR /src Loading @@ -48,17 +20,14 @@ COPY ./nuget.config ./ COPY ./Directory.Build.* ./ # Copy only the project file and restore first for caching COPY src/spa/SPA.csproj src/spa/ COPY src/api/Api.csproj src/api/ RUN dotnet restore Cals.Visor.sln -p:Configuration=Release # Copy the remaining source code COPY src/ ./src/ # Copy built frontend assets to the project wwwroot COPY --from=frontend-builder /app/src/spa/wwwroot ./src/spa/wwwroot/ # Publish the project as self-contained for Alpine (musl) RUN dotnet publish src/spa/SPA.csproj \ RUN dotnet publish src/api/Api.csproj \ -c Release \ -r linux-musl-x64 \ --self-contained true \ Loading @@ -66,7 +35,7 @@ RUN dotnet publish src/spa/SPA.csproj \ -p:PublishSingleFile=true \ -o /app/publish # -------- Stage 3: Minimal Runtime -------- # -------- Stage 2: Minimal Runtime -------- FROM alpine:3.20 AS runtime WORKDIR /app Loading @@ -82,7 +51,7 @@ ENV ASPNETCORE_URLS=http://+:8080 EXPOSE 8080 # Run the app ENTRYPOINT ["./Cals.Visor.Spa"] ENTRYPOINT ["./Cals.Visor.Api"]