From 07e9ab5727ade57b212be5578d6d14346701da1d Mon Sep 17 00:00:00 2001 From: Ash Davies <3853061+DrizzlyOwl@users.noreply.github.com> Date: Mon, 25 Nov 2024 12:16:07 +0000 Subject: [PATCH] Switch to Azure Linux base image * Reduces the overall final image size by using Azure Linux * Offers maximum compatibility with Azure infrastructure * Uses arbitrary user instead of 'root' * Supported by Microsoft --- Dockerfile | 57 ++++++++++++++--------------- terraform/README.md | 1 + terraform/container-apps-hosting.tf | 1 + terraform/locals.tf | 1 + terraform/variables.tf | 6 +++ 5 files changed, 37 insertions(+), 29 deletions(-) diff --git a/Dockerfile b/Dockerfile index 763369b9d..404b761fd 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,36 +1,35 @@ -# Stage 1 - Restore and publish .NET layers -ARG ASPNET_IMAGE_TAG=8.0-bookworm-slim -ARG NODEJS_IMAGE_TAG=18.20-bullseye -FROM mcr.microsoft.com/dotnet/sdk:8.0 AS publish -WORKDIR /build +# Set the major version of dotnet +ARG DOTNET_VERSION=8.0 +# Set the major version of nodejs +ARG NODEJS_VERSION_MAJOR=22 -COPY ./Dfe.PrepareConversions/ ./Dfe.PrepareConversions/ +# Build assets +FROM "node:${NODEJS_VERSION_MAJOR}-bullseye-slim" AS assets +WORKDIR /app +COPY ./Dfe.PrepareConversions/Dfe.PrepareConversions/wwwroot /app +RUN npm install +RUN npm run build -# for info on secrets see https://docs.docker.com/build/ci/github-actions/secrets/ -# and https://render.com/docs/docker-secrets +# Build the app using the dotnet SDK +FROM "mcr.microsoft.com/dotnet/sdk:${DOTNET_VERSION}-azurelinux3.0" AS build +WORKDIR /build +COPY ./Dfe.PrepareConversions/ /build +COPY ./script/web-docker-entrypoint.sh /app/docker-entrypoint.sh -WORKDIR /build/Dfe.PrepareConversions +# 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" -RUN dotnet restore Dfe.PrepareConversions.sln -RUN dotnet build -c Release Dfe.PrepareConversions.sln --no-restore -RUN dotnet publish Dfe.PrepareConversions -c Release -o /app --no-restore -# Stage 2 - Build assets -FROM node:${NODEJS_IMAGE_TAG} as build -COPY ./Dfe.PrepareConversions/Dfe.PrepareConversions/wwwroot /app/wwwroot -WORKDIR /app/wwwroot -RUN npm install -RUN npm run build - -# Stage 3 - Final -ARG ASPNET_IMAGE_TAG -FROM "mcr.microsoft.com/dotnet/aspnet:${ASPNET_IMAGE_TAG}" AS final -LABEL org.opencontainers.image.source=https://github.com/DFE-Digital/prepare-academy-conversions -COPY --from=publish /app /app -COPY --from=build /app/wwwroot /app/wwwroot +RUN ["dotnet", "restore", "Dfe.PrepareConversions"] +RUN ["dotnet", "build", "Dfe.PrepareConversions", "--no-restore", "-c", "Release"] +RUN ["dotnet", "publish", "Dfe.PrepareConversions", "--no-build", "-o", "/app"] +# Build a runtime environment +FROM "mcr.microsoft.com/dotnet/aspnet:${DOTNET_VERSION}-azurelinux3.0" AS base WORKDIR /app -COPY ./script/web-docker-entrypoint.sh ./docker-entrypoint.sh -RUN chmod +x ./docker-entrypoint.sh -ENV ASPNETCORE_HTTP_PORTS=80 -EXPOSE 80/tcp +LABEL org.opencontainers.image.source="https://github.com/DFE-Digital/prepare-academy-conversions" + +COPY --from=build /app /app +COPY --from=assets /app /app/wwwroot +RUN ["chmod", "+x", "./docker-entrypoint.sh"] + +USER $APP_UID diff --git a/terraform/README.md b/terraform/README.md index 6d8d62bb2..eefb56e38 100644 --- a/terraform/README.md +++ b/terraform/README.md @@ -172,6 +172,7 @@ No resources. | [container\_command](#input\_container\_command) | Container command | `list(any)` | n/a | yes | | [container\_health\_probe\_path](#input\_container\_health\_probe\_path) | Specifies the path that is used to determine the liveness of the Container | `string` | n/a | yes | | [container\_max\_replicas](#input\_container\_max\_replicas) | Container max replicas | `number` | n/a | yes | +| [container\_port](#input\_container\_port) | Container port | `number` | `8080` | no | | [container\_scale\_http\_concurrency](#input\_container\_scale\_http\_concurrency) | When the number of concurrent HTTP requests exceeds this value, then another replica is added. Replicas continue to add to the pool up to the max-replicas amount. | `number` | `10` | no | | [container\_secret\_environment\_variables](#input\_container\_secret\_environment\_variables) | Container secret environment variables | `map(string)` | n/a | yes | | [dns\_mx\_records](#input\_dns\_mx\_records) | DNS MX records to add to the DNS Zone |
map(| `{}` | no | diff --git a/terraform/container-apps-hosting.tf b/terraform/container-apps-hosting.tf index 05ec46b0d..383c18dd2 100644 --- a/terraform/container-apps-hosting.tf +++ b/terraform/container-apps-hosting.tf @@ -29,6 +29,7 @@ module "azure_container_apps_hosting" { container_secret_environment_variables = local.container_secret_environment_variables container_max_replicas = local.container_max_replicas container_scale_http_concurrency = local.container_scale_http_concurrency + container_port = local.container_port enable_health_insights_api = local.enable_health_insights_api health_insights_api_cors_origins = local.health_insights_api_cors_origins health_insights_api_ipv4_allow_list = local.health_insights_api_ipv4_allow_list diff --git a/terraform/locals.tf b/terraform/locals.tf index ad0353af0..2a4197b6c 100644 --- a/terraform/locals.tf +++ b/terraform/locals.tf @@ -14,6 +14,7 @@ locals { container_secret_environment_variables = var.container_secret_environment_variables container_max_replicas = var.container_max_replicas container_scale_http_concurrency = var.container_scale_http_concurrency + container_port = var.container_port enable_event_hub = var.enable_event_hub enable_logstash_consumer = var.enable_logstash_consumer eventhub_export_log_analytics_table_names = var.eventhub_export_log_analytics_table_names diff --git a/terraform/variables.tf b/terraform/variables.tf index 425144cfb..9b1643434 100644 --- a/terraform/variables.tf +++ b/terraform/variables.tf @@ -376,3 +376,9 @@ variable "enable_container_app_file_share" { type = bool default = false } + +variable "container_port" { + description = "Container port" + type = number + default = 8080 +}
object({
ttl : optional(number, 300),
records : list(
object({
preference : number,
exchange : string
})
)
})
)