From 3c28f7cf510575202ee5140e979ba3077689bbc6 Mon Sep 17 00:00:00 2001 From: Max Martin Date: Fri, 10 Jul 2026 10:00:59 +0100 Subject: [PATCH 01/16] Refactor Dockerfiles to use ARG for base images and add ACR sync workflow --- .github/workflows/build_docker_images.yml | 14 +++ .github/workflows/sync_acr_base_images.yml | 107 ++++++++++++++++++ api_app/Dockerfile | 3 +- resource_processor/vmss_porter/Dockerfile | 3 +- .../shared_services/gitea/docker/Dockerfile | 3 +- .../gitea/docker/Dockerfile | 3 +- .../guacamole-server/docker/Dockerfile | 6 +- 7 files changed, 133 insertions(+), 6 deletions(-) create mode 100644 .github/workflows/sync_acr_base_images.yml diff --git a/.github/workflows/build_docker_images.yml b/.github/workflows/build_docker_images.yml index 6589f0b9fe..59539119c9 100644 --- a/.github/workflows/build_docker_images.yml +++ b/.github/workflows/build_docker_images.yml @@ -137,6 +137,8 @@ jobs: with: context: ./api_app/ file: ./api_app/Dockerfile + build-args: | + PYTHON_BASE_IMAGE=${{ vars.ACR_BASE_IMAGE_PREFIX != '' && format('{0}/mirror/library/python:3.12-slim-bookworm', vars.ACR_BASE_IMAGE_PREFIX) || 'python:3.12-slim-bookworm' }} outputs: type=local,dest=test-results target: test-results cache-from: type=gha @@ -157,6 +159,8 @@ jobs: with: context: ./api_app/ file: ./api_app/Dockerfile + build-args: | + PYTHON_BASE_IMAGE=${{ vars.ACR_BASE_IMAGE_PREFIX != '' && format('{0}/mirror/library/python:3.12-slim-bookworm', vars.ACR_BASE_IMAGE_PREFIX) || 'python:3.12-slim-bookworm' }} cache-from: type=gha cache-to: type=gha,mode=max @@ -168,6 +172,8 @@ jobs: with: context: ./resource_processor file: ./resource_processor/vmss_porter/Dockerfile + build-args: | + PYTHON_BASE_IMAGE=${{ vars.ACR_BASE_IMAGE_PREFIX != '' && format('{0}/mirror/library/python:3.12-slim-bookworm', vars.ACR_BASE_IMAGE_PREFIX) || 'python:3.12-slim-bookworm' }} cache-from: type=gha cache-to: type=gha,mode=max @@ -179,6 +185,9 @@ jobs: with: context: ./templates/workspace_services/guacamole/guacamole-server file: ./templates/workspace_services/guacamole/guacamole-server/docker/Dockerfile + build-args: | + MAVEN_BASE_IMAGE=${{ vars.ACR_BASE_IMAGE_PREFIX != '' && format('{0}/mirror/library/maven:3.9-eclipse-temurin-17-alpine', vars.ACR_BASE_IMAGE_PREFIX) || 'maven:3.9-eclipse-temurin-17-alpine' }} + GUACD_BASE_IMAGE=${{ vars.ACR_BASE_IMAGE_PREFIX != '' && format('{0}/mirror/guacamole/guacd:1.6.0', vars.ACR_BASE_IMAGE_PREFIX) || 'guacamole/guacd:1.6.0' }} outputs: type=local,dest=test-results target: test-results cache-from: type=gha @@ -199,6 +208,9 @@ jobs: with: context: ./templates/workspace_services/guacamole/guacamole-server file: ./templates/workspace_services/guacamole/guacamole-server/docker/Dockerfile + build-args: | + MAVEN_BASE_IMAGE=${{ vars.ACR_BASE_IMAGE_PREFIX != '' && format('{0}/mirror/library/maven:3.9-eclipse-temurin-17-alpine', vars.ACR_BASE_IMAGE_PREFIX) || 'maven:3.9-eclipse-temurin-17-alpine' }} + GUACD_BASE_IMAGE=${{ vars.ACR_BASE_IMAGE_PREFIX != '' && format('{0}/mirror/guacamole/guacd:1.6.0', vars.ACR_BASE_IMAGE_PREFIX) || 'guacamole/guacd:1.6.0' }} cache-from: type=gha cache-to: type=gha,mode=max @@ -210,6 +222,8 @@ jobs: with: context: ./templates/shared_services/gitea/docker file: ./templates/shared_services/gitea/docker/Dockerfile + build-args: | + GITEA_BASE_IMAGE_REPO=${{ vars.ACR_BASE_IMAGE_PREFIX != '' && format('{0}/mirror/gitea/gitea', vars.ACR_BASE_IMAGE_PREFIX) || 'gitea/gitea' }} cache-from: type=gha cache-to: type=gha,mode=max diff --git a/.github/workflows/sync_acr_base_images.yml b/.github/workflows/sync_acr_base_images.yml new file mode 100644 index 0000000000..6c1eef0237 --- /dev/null +++ b/.github/workflows/sync_acr_base_images.yml @@ -0,0 +1,107 @@ +name: Sync ACR Base Images + +on: # yamllint disable-line rule:truthy + schedule: + - cron: "23 2 * * *" + workflow_dispatch: + +permissions: + contents: read + id-token: write + +jobs: + sync: + name: Import newer upstream base images into ACR + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v6 + with: + persist-credentials: false + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v4 + + - name: Validate required secrets + run: | + if [ "${{ secrets.ACR_NAME }}" = '' ]; then + echo "Missing secret: ACR_NAME" && exit 1 + fi + if [ "${{ secrets.AZURE_CLIENT_ID }}" = '' ]; then + echo "Missing secret: AZURE_CLIENT_ID" && exit 1 + fi + if [ "${{ secrets.AZURE_TENANT_ID }}" = '' ]; then + echo "Missing secret: AZURE_TENANT_ID" && exit 1 + fi + if [ "${{ secrets.AZURE_SUBSCRIPTION_ID }}" = '' ]; then + echo "Missing secret: AZURE_SUBSCRIPTION_ID" && exit 1 + fi + + - name: Azure Login + uses: azure/login@v3 + with: + client-id: ${{ secrets.AZURE_CLIENT_ID }} + tenant-id: ${{ secrets.AZURE_TENANT_ID }} + subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} + environment: ${{ (vars.AZURE_ENVIRONMENT != '' && vars.AZURE_ENVIRONMENT) || 'AzureCloud' }} + + - name: Login to ACR + run: az acr login --name "${{ secrets.ACR_NAME }}" + + - name: Sync image mirrors + env: + ACR_NAME: ${{ secrets.ACR_NAME }} + run: | + set -euo pipefail + + acr_domain_suffix=$(az cloud show --query suffixes.acrLoginServerEndpoint --output tsv) + ACR_LOGIN_SERVER="${ACR_NAME}${acr_domain_suffix}" + + # source_repo|target_repo|tag + IMAGES=( + "docker.io/library/python|mirror/library/python|3.12-slim-bookworm" + "docker.io/library/maven|mirror/library/maven|3.9-eclipse-temurin-17-alpine" + "docker.io/guacamole/guacd|mirror/guacamole/guacd|1.6.0" + "docker.io/gitea/gitea|mirror/gitea/gitea|1.15" + "docker.io/gitea/gitea|mirror/gitea/gitea|1.17.3" + "docker.io/library/debian|mirror/library/debian|bookworm-slim" + "docker.io/library/debian|mirror/library/debian|bullseye-slim" + ) + + sync_image() { + local source_repo="$1" + local target_repo="$2" + local tag="$3" + local source_ref="${source_repo}:${tag}" + local target_ref="${ACR_LOGIN_SERVER}/${target_repo}:${tag}" + + local source_digest + local target_digest + + source_digest=$(docker buildx imagetools inspect "${source_ref}" --format '{{json .Manifest.Digest}}' 2>/dev/null | tr -d '"' || true) + target_digest=$(docker buildx imagetools inspect "${target_ref}" --format '{{json .Manifest.Digest}}' 2>/dev/null | tr -d '"' || true) + + if [[ -n "${source_digest}" && -n "${target_digest}" && "${source_digest}" == "${target_digest}" ]]; then + echo "Up-to-date: ${target_repo}:${tag} (${source_digest})" + return 0 + fi + + echo "Importing ${source_ref} -> ${target_repo}:${tag}" + az acr import \ + --name "${ACR_NAME}" \ + --source "${source_ref}" \ + --image "${target_repo}:${tag}" \ + --force + } + + for image in "${IMAGES[@]}"; do + IFS='|' read -r source_repo target_repo tag <<< "${image}" + sync_image "${source_repo}" "${target_repo}" "${tag}" + done + + - name: Emit repository variable hint + env: + ACR_NAME: ${{ secrets.ACR_NAME }} + run: | + acr_domain_suffix=$(az cloud show --query suffixes.acrLoginServerEndpoint --output tsv) + echo "Set repository variable ACR_BASE_IMAGE_PREFIX to: ${ACR_NAME}${acr_domain_suffix}" diff --git a/api_app/Dockerfile b/api_app/Dockerfile index fc8b93c676..43c6826025 100644 --- a/api_app/Dockerfile +++ b/api_app/Dockerfile @@ -1,4 +1,5 @@ -FROM python:3.12-slim-bookworm AS base +ARG PYTHON_BASE_IMAGE=python:3.12-slim-bookworm +FROM ${PYTHON_BASE_IMAGE} AS base COPY requirements.txt /. RUN pip3 install --no-cache-dir -r requirements.txt diff --git a/resource_processor/vmss_porter/Dockerfile b/resource_processor/vmss_porter/Dockerfile index a49d19aade..522f2b3f1d 100644 --- a/resource_processor/vmss_porter/Dockerfile +++ b/resource_processor/vmss_porter/Dockerfile @@ -1,5 +1,6 @@ # syntax=docker/dockerfile:1 -FROM python:3.12-slim-bookworm +ARG PYTHON_BASE_IMAGE=python:3.12-slim-bookworm +FROM ${PYTHON_BASE_IMAGE} SHELL ["/bin/bash", "-o", "pipefail", "-c"] diff --git a/templates/shared_services/gitea/docker/Dockerfile b/templates/shared_services/gitea/docker/Dockerfile index 16b4fd3bff..07c498c4c0 100644 --- a/templates/shared_services/gitea/docker/Dockerfile +++ b/templates/shared_services/gitea/docker/Dockerfile @@ -1,7 +1,8 @@ ARG GITEA_TAG=1.15 +ARG GITEA_BASE_IMAGE_REPO=gitea/gitea ARG CERTIFICATE_URL=https://www.digicert.com/CACerts/BaltimoreCyberTrustRoot.crt.pem -FROM gitea/gitea:${GITEA_TAG} +FROM ${GITEA_BASE_IMAGE_REPO}:${GITEA_TAG} # need to pass args to stage ARG CERTIFICATE_URL RUN wget -nv -O /usr/local/share/ca-certificates/mysql.crt.pem ${CERTIFICATE_URL} && update-ca-certificates diff --git a/templates/workspace_services/gitea/docker/Dockerfile b/templates/workspace_services/gitea/docker/Dockerfile index c82267de82..85eb04864f 100644 --- a/templates/workspace_services/gitea/docker/Dockerfile +++ b/templates/workspace_services/gitea/docker/Dockerfile @@ -1,7 +1,8 @@ ARG GITEA_TAG=1.17.3 +ARG GITEA_BASE_IMAGE_REPO=gitea/gitea ARG CERTIFICATE_URL=https://www.digicert.com/CACerts/BaltimoreCyberTrustRoot.crt.pem -FROM gitea/gitea:${GITEA_TAG} +FROM ${GITEA_BASE_IMAGE_REPO}:${GITEA_TAG} # need to pass args to stage ARG CERTIFICATE_URL RUN wget -q -O /usr/local/share/ca-certificates/mysql.crt.pem ${CERTIFICATE_URL} && update-ca-certificates diff --git a/templates/workspace_services/guacamole/guacamole-server/docker/Dockerfile b/templates/workspace_services/guacamole/guacamole-server/docker/Dockerfile index 912777575a..016650fa48 100644 --- a/templates/workspace_services/guacamole/guacamole-server/docker/Dockerfile +++ b/templates/workspace_services/guacamole/guacamole-server/docker/Dockerfile @@ -1,4 +1,6 @@ -FROM maven:3.9-eclipse-temurin-17-alpine AS client_build +ARG MAVEN_BASE_IMAGE=maven:3.9-eclipse-temurin-17-alpine +ARG GUACD_BASE_IMAGE=guacamole/guacd:1.6.0 +FROM ${MAVEN_BASE_IMAGE} AS client_build COPY ./guacamole-auth-azure/pom.xml /pom.xml # cache dependencies in a separate layer @@ -11,7 +13,7 @@ RUN bash /tmp/maven_package_and_exit_succesfully.sh FROM scratch AS test-results COPY --from=client_build /target/surefire-reports/* / -FROM guacamole/guacd:1.6.0 +FROM ${GUACD_BASE_IMAGE} ARG GUACAMOLE_AZURE_VERSION=0.5.0 From 7989da0ef2396b759c3ff9fcb1c903695481dcc2 Mon Sep 17 00:00:00 2001 From: Max Martin Date: Fri, 10 Jul 2026 10:23:51 +0100 Subject: [PATCH 02/16] Documentation changes --- .../cicd-pre-deployment-steps.md | 15 +++++++++++++++ docs/tre-admins/setup-instructions/workflows.md | 15 +++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/docs/tre-admins/setup-instructions/cicd-pre-deployment-steps.md b/docs/tre-admins/setup-instructions/cicd-pre-deployment-steps.md index 68e8aa7ad7..a1e1409ddc 100644 --- a/docs/tre-admins/setup-instructions/cicd-pre-deployment-steps.md +++ b/docs/tre-admins/setup-instructions/cicd-pre-deployment-steps.md @@ -95,6 +95,7 @@ Configure the following **variables** in your github environment: | ----------- | ----------- | | `AZURE_ENVIRONMENT` | Optional. The Azure cloud environment. Default is `AzureCloud`. Use `AzureUSGovernment` for US Government cloud | | `LOCATION` | The Azure location (region) for all resources. E.g. `westeurope` | +| `ACR_BASE_IMAGE_PREFIX` | Optional. ACR login server prefix used by image build workflows to pull mirrored base images instead of directly pulling from Docker Hub. Example value: `myacr.azurecr.io`. | | `TERRAFORM_STATE_CONTAINER_NAME` | Optional. The name of the blob container to hold the Terraform state. Default value is `tfstate`. | | `CORE_ADDRESS_SPACE` | Optional. The address space for the Azure TRE core virtual network. Default value is `10.0.0.0/22`. | | `TRE_ADDRESS_SPACE` | Optional. The address space for the whole TRE environment virtual network where workspaces networks will be created (can include the core network as well). Default value is `10.0.0.0/16` | @@ -108,6 +109,20 @@ Configure the following **variables** in your github environment: | `CUSTOM_DOMAIN` | Optional. Custom domain name to access the Azure TRE portal. See [Custom domain name](../custom-domain.md). | | `ENABLE_CMK_ENCRYPTION` | Optional. Default is `false`, if set to `true` customer-managed key encryption will be enabled for all supported resources. | +### Optional: Mirror Docker Hub base images into ACR for CI + +To reduce Docker Hub rate-limit exposure in CI, Azure TRE includes a dedicated workflow to mirror selected upstream base images into your ACR and use those mirrors during image builds. + +1. Set repository/environment variable `ACR_BASE_IMAGE_PREFIX` to your ACR login server (for example, `myacr.azurecr.io`). +1. Ensure the following secrets are configured for the mirror workflow: + - `ACR_NAME` + - `AZURE_CLIENT_ID` + - `AZURE_TENANT_ID` + - `AZURE_SUBSCRIPTION_ID` +1. Run `/.github/workflows/sync_acr_base_images.yml` manually once to seed mirrored images, then allow the scheduled run to keep them up to date. + +The Docker image build workflow (`/.github/workflows/build_docker_images.yml`) automatically uses mirrored base images when `ACR_BASE_IMAGE_PREFIX` is set, and falls back to upstream image sources when it is not set. + ### Configure Authentication Secrets In a previous [Setup Auth configuration](./setup-auth-entities.md) step authentication configuration was added in `config.yaml` file. Go to this file and add those env vars to your github environment: diff --git a/docs/tre-admins/setup-instructions/workflows.md b/docs/tre-admins/setup-instructions/workflows.md index 9176768f9c..1ab1b02933 100644 --- a/docs/tre-admins/setup-instructions/workflows.md +++ b/docs/tre-admins/setup-instructions/workflows.md @@ -147,6 +147,7 @@ Configure variables used in the deployment workflow: |
Variable name
| Description | | ----------- | ----------- | | `LOCATION` | The Azure location (region) for all resources. E.g. `westeurope` | +| `ACR_BASE_IMAGE_PREFIX` | Optional. ACR login server prefix used by image build workflows to pull mirrored base images instead of directly pulling from Docker Hub. Example value: `myacr.azurecr.io`. | | `TERRAFORM_STATE_CONTAINER_NAME` | Optional. The name of the blob container to hold the Terraform state. Default value is `tfstate`. | | `CORE_ADDRESS_SPACE` | Optional. The address space for the Azure TRE core virtual network. Default value is `10.0.0.0/22`. | | `TRE_ADDRESS_SPACE` | Optional. The address space for the whole TRE environment virtual network where workspaces networks will be created (can include the core network as well). Default value is `10.0.0.0/16` | @@ -159,6 +160,20 @@ Configure variables used in the deployment workflow: | `APP_GATEWAY_SKU` | Optional. The SKU of the Application Gateway. Default value is `Standard_v2`. Allowed values [`Standard_v2`, `WAF_v2`] | | `ENABLE_CMK_ENCRYPTION` | Optional. Default is `false`, if set to `true` customer-managed key encryption will be enabled for all supported resources. | +### Optional: Mirror Docker Hub base images into ACR for CI + +To reduce Docker Hub rate-limit exposure in CI, Azure TRE includes a dedicated workflow to mirror selected upstream base images into your ACR and use those mirrors during image builds. + +1. Set repository/environment variable `ACR_BASE_IMAGE_PREFIX` to your ACR login server (for example, `myacr.azurecr.io`). +1. Ensure the following secrets are configured for the mirror workflow: + - `ACR_NAME` + - `AZURE_CLIENT_ID` + - `AZURE_TENANT_ID` + - `AZURE_SUBSCRIPTION_ID` +1. Run `/.github/workflows/sync_acr_base_images.yml` manually once to seed mirrored images, then allow the scheduled run to keep them up to date. + +The Docker image build workflow (`/.github/workflows/build_docker_images.yml`) automatically uses mirrored base images when `ACR_BASE_IMAGE_PREFIX` is set, and falls back to upstream image sources when it is not set. + ### Deploy the TRE using the workflow With all the repository secrets set, you can trigger a workflow run by pushing to develop/main of your fork, or by dispatching the workflow manually. From fefe1b9d708e2106a00ac68efd69ab18d389a298 Mon Sep 17 00:00:00 2001 From: Max Martin Date: Fri, 10 Jul 2026 10:55:14 +0100 Subject: [PATCH 03/16] Iterate minor version --- api_app/_version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api_app/_version.py b/api_app/_version.py index eda2a21a48..7df7ad28da 100644 --- a/api_app/_version.py +++ b/api_app/_version.py @@ -1 +1 @@ -__version__ = "0.25.26" +__version__ = "0.25.27" From cc297b955bee92f25aac07c4222fa78348069a6b Mon Sep 17 00:00:00 2001 From: Max Martin Date: Fri, 10 Jul 2026 11:12:09 +0100 Subject: [PATCH 04/16] Iterate minor version (again) --- api_app/_version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api_app/_version.py b/api_app/_version.py index 7df7ad28da..07adb6c906 100644 --- a/api_app/_version.py +++ b/api_app/_version.py @@ -1 +1 @@ -__version__ = "0.25.27" +__version__ = "0.25.28" From 687fa044cc8a3b521aeb39c6bbedca7e1cf01049 Mon Sep 17 00:00:00 2001 From: Max Martin Date: Fri, 10 Jul 2026 11:51:04 +0100 Subject: [PATCH 05/16] Fix issues raised by linter --- .github/workflows/build_docker_images.yml | 33 ++++++++++++++----- .github/workflows/sync_acr_base_images.yml | 8 +++-- .../cicd-pre-deployment-steps.md | 12 +++---- .../setup-instructions/workflows.md | 30 ++++++++--------- resource_processor/_version.py | 2 +- 5 files changed, 53 insertions(+), 32 deletions(-) diff --git a/.github/workflows/build_docker_images.yml b/.github/workflows/build_docker_images.yml index 59539119c9..e1f1e4e976 100644 --- a/.github/workflows/build_docker_images.yml +++ b/.github/workflows/build_docker_images.yml @@ -21,6 +21,23 @@ jobs: docker_build: name: Build images runs-on: ubuntu-latest + env: + PYTHON_BASE_IMAGE: >- + ${{ vars.ACR_BASE_IMAGE_PREFIX != '' && + format('{0}/mirror/library/python:3.12-slim-bookworm', vars.ACR_BASE_IMAGE_PREFIX) + || 'python:3.12-slim-bookworm' }} + MAVEN_BASE_IMAGE: >- + ${{ vars.ACR_BASE_IMAGE_PREFIX != '' && + format('{0}/mirror/library/maven:3.9-eclipse-temurin-17-alpine', vars.ACR_BASE_IMAGE_PREFIX) + || 'maven:3.9-eclipse-temurin-17-alpine' }} + GUACD_BASE_IMAGE: >- + ${{ vars.ACR_BASE_IMAGE_PREFIX != '' && + format('{0}/mirror/guacamole/guacd:1.6.0', vars.ACR_BASE_IMAGE_PREFIX) + || 'guacamole/guacd:1.6.0' }} + GITEA_BASE_IMAGE_REPO: >- + ${{ vars.ACR_BASE_IMAGE_PREFIX != '' && + format('{0}/mirror/gitea/gitea', vars.ACR_BASE_IMAGE_PREFIX) + || 'gitea/gitea' }} permissions: contents: read actions: write # For uploading artifacts @@ -138,7 +155,7 @@ jobs: context: ./api_app/ file: ./api_app/Dockerfile build-args: | - PYTHON_BASE_IMAGE=${{ vars.ACR_BASE_IMAGE_PREFIX != '' && format('{0}/mirror/library/python:3.12-slim-bookworm', vars.ACR_BASE_IMAGE_PREFIX) || 'python:3.12-slim-bookworm' }} + PYTHON_BASE_IMAGE=${{ env.PYTHON_BASE_IMAGE }} outputs: type=local,dest=test-results target: test-results cache-from: type=gha @@ -160,7 +177,7 @@ jobs: context: ./api_app/ file: ./api_app/Dockerfile build-args: | - PYTHON_BASE_IMAGE=${{ vars.ACR_BASE_IMAGE_PREFIX != '' && format('{0}/mirror/library/python:3.12-slim-bookworm', vars.ACR_BASE_IMAGE_PREFIX) || 'python:3.12-slim-bookworm' }} + PYTHON_BASE_IMAGE=${{ env.PYTHON_BASE_IMAGE }} cache-from: type=gha cache-to: type=gha,mode=max @@ -173,7 +190,7 @@ jobs: context: ./resource_processor file: ./resource_processor/vmss_porter/Dockerfile build-args: | - PYTHON_BASE_IMAGE=${{ vars.ACR_BASE_IMAGE_PREFIX != '' && format('{0}/mirror/library/python:3.12-slim-bookworm', vars.ACR_BASE_IMAGE_PREFIX) || 'python:3.12-slim-bookworm' }} + PYTHON_BASE_IMAGE=${{ env.PYTHON_BASE_IMAGE }} cache-from: type=gha cache-to: type=gha,mode=max @@ -186,8 +203,8 @@ jobs: context: ./templates/workspace_services/guacamole/guacamole-server file: ./templates/workspace_services/guacamole/guacamole-server/docker/Dockerfile build-args: | - MAVEN_BASE_IMAGE=${{ vars.ACR_BASE_IMAGE_PREFIX != '' && format('{0}/mirror/library/maven:3.9-eclipse-temurin-17-alpine', vars.ACR_BASE_IMAGE_PREFIX) || 'maven:3.9-eclipse-temurin-17-alpine' }} - GUACD_BASE_IMAGE=${{ vars.ACR_BASE_IMAGE_PREFIX != '' && format('{0}/mirror/guacamole/guacd:1.6.0', vars.ACR_BASE_IMAGE_PREFIX) || 'guacamole/guacd:1.6.0' }} + MAVEN_BASE_IMAGE=${{ env.MAVEN_BASE_IMAGE }} + GUACD_BASE_IMAGE=${{ env.GUACD_BASE_IMAGE }} outputs: type=local,dest=test-results target: test-results cache-from: type=gha @@ -209,8 +226,8 @@ jobs: context: ./templates/workspace_services/guacamole/guacamole-server file: ./templates/workspace_services/guacamole/guacamole-server/docker/Dockerfile build-args: | - MAVEN_BASE_IMAGE=${{ vars.ACR_BASE_IMAGE_PREFIX != '' && format('{0}/mirror/library/maven:3.9-eclipse-temurin-17-alpine', vars.ACR_BASE_IMAGE_PREFIX) || 'maven:3.9-eclipse-temurin-17-alpine' }} - GUACD_BASE_IMAGE=${{ vars.ACR_BASE_IMAGE_PREFIX != '' && format('{0}/mirror/guacamole/guacd:1.6.0', vars.ACR_BASE_IMAGE_PREFIX) || 'guacamole/guacd:1.6.0' }} + MAVEN_BASE_IMAGE=${{ env.MAVEN_BASE_IMAGE }} + GUACD_BASE_IMAGE=${{ env.GUACD_BASE_IMAGE }} cache-from: type=gha cache-to: type=gha,mode=max @@ -223,7 +240,7 @@ jobs: context: ./templates/shared_services/gitea/docker file: ./templates/shared_services/gitea/docker/Dockerfile build-args: | - GITEA_BASE_IMAGE_REPO=${{ vars.ACR_BASE_IMAGE_PREFIX != '' && format('{0}/mirror/gitea/gitea', vars.ACR_BASE_IMAGE_PREFIX) || 'gitea/gitea' }} + GITEA_BASE_IMAGE_REPO=${{ env.GITEA_BASE_IMAGE_REPO }} cache-from: type=gha cache-to: type=gha,mode=max diff --git a/.github/workflows/sync_acr_base_images.yml b/.github/workflows/sync_acr_base_images.yml index 6c1eef0237..4a52c3b811 100644 --- a/.github/workflows/sync_acr_base_images.yml +++ b/.github/workflows/sync_acr_base_images.yml @@ -1,3 +1,4 @@ +--- name: Sync ACR Base Images on: # yamllint disable-line rule:truthy @@ -74,12 +75,15 @@ jobs: local tag="$3" local source_ref="${source_repo}:${tag}" local target_ref="${ACR_LOGIN_SERVER}/${target_repo}:${tag}" + local digest_format='{{json .Manifest.Digest}}' local source_digest local target_digest - source_digest=$(docker buildx imagetools inspect "${source_ref}" --format '{{json .Manifest.Digest}}' 2>/dev/null | tr -d '"' || true) - target_digest=$(docker buildx imagetools inspect "${target_ref}" --format '{{json .Manifest.Digest}}' 2>/dev/null | tr -d '"' || true) + source_digest=$(docker buildx imagetools inspect "${source_ref}" \ + --format "${digest_format}" 2>/dev/null | tr -d '"' || true) + target_digest=$(docker buildx imagetools inspect "${target_ref}" \ + --format "${digest_format}" 2>/dev/null | tr -d '"' || true) if [[ -n "${source_digest}" && -n "${target_digest}" && "${source_digest}" == "${target_digest}" ]]; then echo "Up-to-date: ${target_repo}:${tag} (${source_digest})" diff --git a/docs/tre-admins/setup-instructions/cicd-pre-deployment-steps.md b/docs/tre-admins/setup-instructions/cicd-pre-deployment-steps.md index a1e1409ddc..0c8ad5b55a 100644 --- a/docs/tre-admins/setup-instructions/cicd-pre-deployment-steps.md +++ b/docs/tre-admins/setup-instructions/cicd-pre-deployment-steps.md @@ -114,12 +114,12 @@ Configure the following **variables** in your github environment: To reduce Docker Hub rate-limit exposure in CI, Azure TRE includes a dedicated workflow to mirror selected upstream base images into your ACR and use those mirrors during image builds. 1. Set repository/environment variable `ACR_BASE_IMAGE_PREFIX` to your ACR login server (for example, `myacr.azurecr.io`). -1. Ensure the following secrets are configured for the mirror workflow: - - `ACR_NAME` - - `AZURE_CLIENT_ID` - - `AZURE_TENANT_ID` - - `AZURE_SUBSCRIPTION_ID` -1. Run `/.github/workflows/sync_acr_base_images.yml` manually once to seed mirrored images, then allow the scheduled run to keep them up to date. +2. Ensure the following secrets are configured for the mirror workflow: +- `ACR_NAME` +- `AZURE_CLIENT_ID` +- `AZURE_TENANT_ID` +- `AZURE_SUBSCRIPTION_ID` +3. Run `/.github/workflows/sync_acr_base_images.yml` manually once to seed mirrored images, then allow the scheduled run to keep them up to date. The Docker image build workflow (`/.github/workflows/build_docker_images.yml`) automatically uses mirrored base images when `ACR_BASE_IMAGE_PREFIX` is set, and falls back to upstream image sources when it is not set. diff --git a/docs/tre-admins/setup-instructions/workflows.md b/docs/tre-admins/setup-instructions/workflows.md index 1ab1b02933..8c32e99de5 100644 --- a/docs/tre-admins/setup-instructions/workflows.md +++ b/docs/tre-admins/setup-instructions/workflows.md @@ -12,12 +12,12 @@ Before you can run the `deploy_tre.yml` workflow there are some one-time configu In some of the steps below, you are asked to configure repository secrets. Follow the [GitHub guide](https://docs.github.com/en/actions/security-guides/encrypted-secrets) on creating repository secrets if you are unfamiliar with this step. 1. Create a service principal for the subscription so that the workflow can provision Azure resources. -1. Decide on a TRE ID and the location for the Azure resources -1. Create app registrations for API authentication -1. Create app registrations and a user for the E2E tests -1. Create a workspace app registration for setting up workspaces (for the E2E tests) -1. Configure repository secrets -1. Deploy the TRE using the workflow +2. Decide on a TRE ID and the location for the Azure resources +3. Create app registrations for API authentication +4. Create app registrations and a user for the E2E tests +5. Create a workspace app registration for setting up workspaces (for the E2E tests) +6. Configure repository secrets +7. Deploy the TRE using the workflow ### Create a service principal and configure OIDC authentication @@ -33,7 +33,7 @@ Before you can run the `deploy_tre.yml` workflow there are some one-time configu See [Sign in with Azure CLI](https://docs.microsoft.com/cli/azure/authenticate-azure-cli) for more details. -1. Create a service principal +2. Create a service principal A service principal needs to be created to authorize CI/CD workflows to provision resources for the TRE workspaces and workspace services. @@ -46,7 +46,7 @@ Before you can run the `deploy_tre.yml` workflow there are some one-time configu !!! caution Save the output (especially the `appId` and `tenant`) - you will need it for the next steps -1. Configure federated identity credentials for GitHub Actions OIDC +3. Configure federated identity credentials for GitHub Actions OIDC Configure the service principal to trust GitHub Actions OIDC tokens from your repository: @@ -72,7 +72,7 @@ Before you can run the `deploy_tre.yml` workflow there are some one-time configu See [Configure a federated identity credential on an app](https://learn.microsoft.com/entra/workload-id/workload-identity-federation-create-trust?pivots=identity-wif-apps-methods-azcli) for more details. -1. Configure repository secrets for OIDC authentication +4. Configure repository secrets for OIDC authentication Configure the following **secrets** (not variables) in your repository or environment: @@ -165,12 +165,12 @@ Configure variables used in the deployment workflow: To reduce Docker Hub rate-limit exposure in CI, Azure TRE includes a dedicated workflow to mirror selected upstream base images into your ACR and use those mirrors during image builds. 1. Set repository/environment variable `ACR_BASE_IMAGE_PREFIX` to your ACR login server (for example, `myacr.azurecr.io`). -1. Ensure the following secrets are configured for the mirror workflow: - - `ACR_NAME` - - `AZURE_CLIENT_ID` - - `AZURE_TENANT_ID` - - `AZURE_SUBSCRIPTION_ID` -1. Run `/.github/workflows/sync_acr_base_images.yml` manually once to seed mirrored images, then allow the scheduled run to keep them up to date. +2. Ensure the following secrets are configured for the mirror workflow: +- `ACR_NAME` +- `AZURE_CLIENT_ID` +- `AZURE_TENANT_ID` +- `AZURE_SUBSCRIPTION_ID` +3. Run `/.github/workflows/sync_acr_base_images.yml` manually once to seed mirrored images, then allow the scheduled run to keep them up to date. The Docker image build workflow (`/.github/workflows/build_docker_images.yml`) automatically uses mirrored base images when `ACR_BASE_IMAGE_PREFIX` is set, and falls back to upstream image sources when it is not set. diff --git a/resource_processor/_version.py b/resource_processor/_version.py index f2b93b13de..7c37594d81 100644 --- a/resource_processor/_version.py +++ b/resource_processor/_version.py @@ -1 +1 @@ -__version__ = "0.13.4" +__version__ = "0.13.5" From 593e48f9cd58831dae004705b42dc3da52423075 Mon Sep 17 00:00:00 2001 From: Max Martin Date: Fri, 10 Jul 2026 12:00:27 +0100 Subject: [PATCH 06/16] Iterate minor versions for workspace templates --- templates/shared_services/gitea/docker/version.txt | 2 +- templates/workspace_services/gitea/version.txt | 2 +- .../guacamole/guacamole-server/docker/version.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/templates/shared_services/gitea/docker/version.txt b/templates/shared_services/gitea/docker/version.txt index df0ed33211..8a3be2e00c 100644 --- a/templates/shared_services/gitea/docker/version.txt +++ b/templates/shared_services/gitea/docker/version.txt @@ -1 +1 @@ -__version__ = "0.3.12" +__version__ = "0.3.13" diff --git a/templates/workspace_services/gitea/version.txt b/templates/workspace_services/gitea/version.txt index 43c4ab0058..22049ab2c4 100644 --- a/templates/workspace_services/gitea/version.txt +++ b/templates/workspace_services/gitea/version.txt @@ -1 +1 @@ -__version__ = "0.6.1" +__version__ = "0.6.2" diff --git a/templates/workspace_services/guacamole/guacamole-server/docker/version.txt b/templates/workspace_services/guacamole/guacamole-server/docker/version.txt index 61fb31cae0..1f4c4d43b2 100644 --- a/templates/workspace_services/guacamole/guacamole-server/docker/version.txt +++ b/templates/workspace_services/guacamole/guacamole-server/docker/version.txt @@ -1 +1 @@ -__version__ = "0.10.0" +__version__ = "0.10.1" From 72ed8efd3ccebaf943269bd7105b87e71ed0423a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 13 Jul 2026 08:50:26 +0000 Subject: [PATCH 07/16] Pin GitHub Actions in ACR sync workflow --- .github/workflows/sync_acr_base_images.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/sync_acr_base_images.yml b/.github/workflows/sync_acr_base_images.yml index 4a52c3b811..5232de4fd6 100644 --- a/.github/workflows/sync_acr_base_images.yml +++ b/.github/workflows/sync_acr_base_images.yml @@ -16,12 +16,12 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: persist-credentials: false - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v4 + uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd - name: Validate required secrets run: | @@ -39,7 +39,7 @@ jobs: fi - name: Azure Login - uses: azure/login@v3 + uses: azure/login@532459ea530d8321f2fb9bb10d1e0bcf23869a43 # v3.0.0 with: client-id: ${{ secrets.AZURE_CLIENT_ID }} tenant-id: ${{ secrets.AZURE_TENANT_ID }} From c89d8372fe7d19164b50812607f5e8d43c16cdee Mon Sep 17 00:00:00 2001 From: Max Martin Date: Tue, 14 Jul 2026 09:53:27 +0100 Subject: [PATCH 08/16] Bump versions --- api_app/_version.py | 2 +- resource_processor/_version.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/api_app/_version.py b/api_app/_version.py index 07adb6c906..605b3cd20e 100644 --- a/api_app/_version.py +++ b/api_app/_version.py @@ -1 +1 @@ -__version__ = "0.25.28" +__version__ = "0.25.29" diff --git a/resource_processor/_version.py b/resource_processor/_version.py index 7c37594d81..e318db3960 100644 --- a/resource_processor/_version.py +++ b/resource_processor/_version.py @@ -1 +1 @@ -__version__ = "0.13.5" +__version__ = "0.13.6" From e2a617b0e31e2238b616a8b158cd2cbded83886a Mon Sep 17 00:00:00 2001 From: Max Martin Date: Fri, 17 Jul 2026 14:59:43 +0100 Subject: [PATCH 09/16] Refactor Dockerfiles to use ARG for base images and tags for improved configurability --- .devcontainer/Dockerfile | 4 +- .github/workflows/sync_acr_base_images.yml | 61 +++++++++++++++++-- CHANGELOG.md | 1 + airlock_processor/Dockerfile | 4 +- api_app/Dockerfile | 5 +- resource_processor/vmss_porter/Dockerfile | 5 +- .../shared_services/admin-vm/Dockerfile.tmpl | 4 +- .../airlock_notifier/Dockerfile.tmpl | 4 +- .../shared_services/certs/Dockerfile.tmpl | 4 +- .../cyclecloud/Dockerfile.tmpl | 4 +- .../databricks-auth/Dockerfile.tmpl | 4 +- .../shared_services/firewall/Dockerfile.tmpl | 4 +- .../shared_services/gitea/Dockerfile.tmpl | 4 +- .../sonatype-nexus-vm/Dockerfile.tmpl | 4 +- .../azureml/Dockerfile.tmpl | 4 +- .../aml_compute/Dockerfile.tmpl | 4 +- .../azuresql/Dockerfile.tmpl | 4 +- .../databricks/Dockerfile.tmpl | 4 +- .../workspace_services/gitea/Dockerfile.tmpl | 4 +- .../guacamole/Dockerfile.tmpl | 4 +- .../guacamole/e2e-tests/playwright/Dockerfile | 4 +- .../guacamole-server/docker/Dockerfile | 10 +-- .../Dockerfile.tmpl | 4 +- .../Dockerfile.tmpl | 4 +- .../guacamole-azure-linuxvm/Dockerfile.tmpl | 4 +- .../guacamole-azure-windowsvm/Dockerfile.tmpl | 4 +- .../health-services/Dockerfile.tmpl | 4 +- .../workspace_services/mysql/Dockerfile.tmpl | 4 +- .../workspace_services/ohdsi/Dockerfile.tmpl | 4 +- .../workspace_services/openai/Dockerfile.tmpl | 4 +- .../airlock-import-review/Dockerfile.tmpl | 4 +- templates/workspaces/base/Dockerfile.tmpl | 4 +- .../workspaces/unrestricted/Dockerfile.tmpl | 4 +- 33 files changed, 152 insertions(+), 42 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index dd858658cf..13ee2d17aa 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -2,8 +2,10 @@ # [Choice] Python version: 3.11 3.12, 3.13 ARG VARIANT="3.12" +ARG DEVCONTAINER_TAG=dev-${VARIANT}-bookworm +ARG DEVCONTAINER_BASE_IMAGE=mcr.microsoft.com/vscode/devcontainers/python ARG TARGETPLATFORM="linux/amd64" -FROM --platform="${TARGETPLATFORM}" mcr.microsoft.com/vscode/devcontainers/python:dev-${VARIANT}-bookworm +FROM --platform="${TARGETPLATFORM}" ${DEVCONTAINER_BASE_IMAGE}:${DEVCONTAINER_TAG} # This will be set to true when running in VSCode ARG INTERACTIVE="false" diff --git a/.github/workflows/sync_acr_base_images.yml b/.github/workflows/sync_acr_base_images.yml index 5232de4fd6..2e2c78114e 100644 --- a/.github/workflows/sync_acr_base_images.yml +++ b/.github/workflows/sync_acr_base_images.yml @@ -80,10 +80,26 @@ jobs: local source_digest local target_digest - source_digest=$(docker buildx imagetools inspect "${source_ref}" \ - --format "${digest_format}" 2>/dev/null | tr -d '"' || true) - target_digest=$(docker buildx imagetools inspect "${target_ref}" \ - --format "${digest_format}" 2>/dev/null | tr -d '"' || true) + if ! source_digest=$(docker buildx imagetools inspect "${source_ref}" \ + --format "${digest_format}" | tr -d '"'); then + echo "::error::Failed to inspect source image ${source_ref}. Aborting to avoid unintended forced import." + return 1 + fi + + if ! target_digest=$(docker buildx imagetools inspect "${target_ref}" \ + --format "${digest_format}" | tr -d '"'); then + echo "::warning::Failed to inspect target image ${target_ref}. Proceeding with import." + target_digest="" + fi + + if [[ -z "${source_digest}" ]]; then + echo "::error::Source digest for ${source_ref} is empty. Aborting to avoid unintended forced import." + return 1 + fi + + if [[ -z "${target_digest}" ]]; then + echo "::warning::Target digest for ${target_ref} is empty. Import will proceed." + fi if [[ -n "${source_digest}" && -n "${target_digest}" && "${source_digest}" == "${target_digest}" ]]; then echo "Up-to-date: ${target_repo}:${tag} (${source_digest})" @@ -103,9 +119,42 @@ jobs: sync_image "${source_repo}" "${target_repo}" "${tag}" done - - name: Emit repository variable hint + - name: Publish sync summary env: ACR_NAME: ${{ secrets.ACR_NAME }} + CURRENT_ACR_BASE_IMAGE_PREFIX: ${{ vars.ACR_BASE_IMAGE_PREFIX }} run: | + set -euo pipefail + acr_domain_suffix=$(az cloud show --query suffixes.acrLoginServerEndpoint --output tsv) - echo "Set repository variable ACR_BASE_IMAGE_PREFIX to: ${ACR_NAME}${acr_domain_suffix}" + expected_prefix="${ACR_NAME}${acr_domain_suffix}" + + { + echo "## ACR base image sync summary" + echo + echo "- Expected ACR_BASE_IMAGE_PREFIX: ${expected_prefix}" + + if [[ -n "${CURRENT_ACR_BASE_IMAGE_PREFIX}" ]]; then + echo "- Current ACR_BASE_IMAGE_PREFIX: ${CURRENT_ACR_BASE_IMAGE_PREFIX}" + else + echo "- Current ACR_BASE_IMAGE_PREFIX: (not set)" + fi + + echo + if [[ -z "${CURRENT_ACR_BASE_IMAGE_PREFIX}" ]]; then + echo "Repository variable ACR_BASE_IMAGE_PREFIX is not set." + echo "Please set it to ${expected_prefix}." + echo "See: Repository Settings > Secrets and variables > Actions > Variables" + elif [[ "${CURRENT_ACR_BASE_IMAGE_PREFIX}" != "${expected_prefix}" ]]; then + echo "Repository variable ACR_BASE_IMAGE_PREFIX does not match the expected value." + echo "Please update it to ${expected_prefix}." + else + echo "Repository variable ACR_BASE_IMAGE_PREFIX is correctly configured." + fi + } >> "${GITHUB_STEP_SUMMARY}" + + if [[ -z "${CURRENT_ACR_BASE_IMAGE_PREFIX}" ]]; then + echo "::warning::Repository variable ACR_BASE_IMAGE_PREFIX is not set. Expected: ${expected_prefix}" + elif [[ "${CURRENT_ACR_BASE_IMAGE_PREFIX}" != "${expected_prefix}" ]]; then + echo "::warning::Repository variable ACR_BASE_IMAGE_PREFIX mismatch. Current: ${CURRENT_ACR_BASE_IMAGE_PREFIX}, Expected: ${expected_prefix}" + fi diff --git a/CHANGELOG.md b/CHANGELOG.md index 54926d6548..6caf13e16a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ ENHANCEMENTS: * Add Windows Server 2025 image support to Guacamole. ([#4890](https://github.com/microsoft/AzureTRE/issues/4890)) * Add support for setting resource processor VMSS SKU via environment variables ([#4936](https://github.com/microsoft/AzureTRE/issues/4936)) * Exclude recovery service vaults from e2e tests ([#4920](https://github.com/microsoft/AzureTRE/issues/4920)) +* Add ACR base-image mirroring workflow and configurable Docker base-image arguments for CI builds ([#4952](https://github.com/microsoft/AzureTRE/pull/4952)) * Update API, CLI, and UI dependencies to address high-severity Dependabot alerts, including `PyJWT`, `Vite`, `lodash`, `fast-uri`, `flatted`, `immutable`, and `minimatch`. * Update dependencies to address Dependabot security alerts: `aiohttp` to 3.14.1, `Pygments` to 2.20.0, `esbuild`, `ws`, `js-yaml`, `@babel/core`, `flatted` (via vitest upgrade), and `react-router-dom`. ([#4950](https://github.com/microsoft/AzureTRE/issues/4950)) * Added support for formatting UI code via `pre-commit` and fixed existing formatting issues. ([#4955](https://github.com/microsoft/AzureTRE/issues/4955)) diff --git a/airlock_processor/Dockerfile b/airlock_processor/Dockerfile index 68d1174ffc..faa443e4ec 100644 --- a/airlock_processor/Dockerfile +++ b/airlock_processor/Dockerfile @@ -1,6 +1,8 @@ # To enable ssh & remote debugging on app service change the base image to the one below # FROM mcr.microsoft.com/azure-functions/python:4-python3.8-appservice as base -FROM mcr.microsoft.com/azure-functions/python:4-python3.12 AS base +ARG PYTHON_TAG=4-python3.12 +ARG PYTHON_BASE_IMAGE=mcr.microsoft.com/azure-functions/python +FROM ${PYTHON_BASE_IMAGE}:${PYTHON_TAG} AS base COPY requirements.txt / RUN pip install --no-cache-dir -r /requirements.txt diff --git a/api_app/Dockerfile b/api_app/Dockerfile index 43c6826025..8ee5f281f5 100644 --- a/api_app/Dockerfile +++ b/api_app/Dockerfile @@ -1,5 +1,6 @@ -ARG PYTHON_BASE_IMAGE=python:3.12-slim-bookworm -FROM ${PYTHON_BASE_IMAGE} AS base +ARG PYTHON_TAG=3.12-slim-bookworm +ARG PYTHON_BASE_IMAGE=python +FROM ${PYTHON_BASE_IMAGE}:${PYTHON_TAG} AS base COPY requirements.txt /. RUN pip3 install --no-cache-dir -r requirements.txt diff --git a/resource_processor/vmss_porter/Dockerfile b/resource_processor/vmss_porter/Dockerfile index 522f2b3f1d..1a17e09820 100644 --- a/resource_processor/vmss_porter/Dockerfile +++ b/resource_processor/vmss_porter/Dockerfile @@ -1,6 +1,7 @@ # syntax=docker/dockerfile:1 -ARG PYTHON_BASE_IMAGE=python:3.12-slim-bookworm -FROM ${PYTHON_BASE_IMAGE} +ARG PYTHON_TAG=3.12-slim-bookworm +ARG PYTHON_BASE_IMAGE=python +FROM ${PYTHON_BASE_IMAGE}:${PYTHON_TAG} SHELL ["/bin/bash", "-o", "pipefail", "-c"] diff --git a/templates/shared_services/admin-vm/Dockerfile.tmpl b/templates/shared_services/admin-vm/Dockerfile.tmpl index a8c0026343..c21796d5a6 100644 --- a/templates/shared_services/admin-vm/Dockerfile.tmpl +++ b/templates/shared_services/admin-vm/Dockerfile.tmpl @@ -1,5 +1,7 @@ # syntax=docker/dockerfile-upstream:1.4.0 -FROM --platform=linux/amd64 debian:bookworm-slim +ARG DEBIAN_TAG=bookworm-slim +ARG DEBIAN_BASE_IMAGE=debian +FROM --platform=linux/amd64 ${DEBIAN_BASE_IMAGE}:${DEBIAN_TAG} # PORTER_INIT diff --git a/templates/shared_services/airlock_notifier/Dockerfile.tmpl b/templates/shared_services/airlock_notifier/Dockerfile.tmpl index 816a6fb388..70d881496f 100644 --- a/templates/shared_services/airlock_notifier/Dockerfile.tmpl +++ b/templates/shared_services/airlock_notifier/Dockerfile.tmpl @@ -1,5 +1,7 @@ # syntax=docker/dockerfile-upstream:1.4.0 -FROM --platform=linux/amd64 debian:bookworm-slim +ARG DEBIAN_TAG=bookworm-slim +ARG DEBIAN_BASE_IMAGE=debian +FROM --platform=linux/amd64 ${DEBIAN_BASE_IMAGE}:${DEBIAN_TAG} # PORTER_INIT diff --git a/templates/shared_services/certs/Dockerfile.tmpl b/templates/shared_services/certs/Dockerfile.tmpl index f61b684795..1f392d71a0 100644 --- a/templates/shared_services/certs/Dockerfile.tmpl +++ b/templates/shared_services/certs/Dockerfile.tmpl @@ -1,5 +1,7 @@ # syntax=docker/dockerfile-upstream:1.4.0 -FROM --platform=linux/amd64 python:3.13-slim-bookworm +ARG PYTHON_TAG=3.13-slim-bookworm +ARG PYTHON_BASE_IMAGE=python +FROM --platform=linux/amd64 ${PYTHON_BASE_IMAGE}:${PYTHON_TAG} # PORTER_INIT diff --git a/templates/shared_services/cyclecloud/Dockerfile.tmpl b/templates/shared_services/cyclecloud/Dockerfile.tmpl index abc241c3a1..8cf4c593a6 100644 --- a/templates/shared_services/cyclecloud/Dockerfile.tmpl +++ b/templates/shared_services/cyclecloud/Dockerfile.tmpl @@ -1,5 +1,7 @@ # syntax=docker/dockerfile-upstream:1.4.0 -FROM --platform=linux/amd64 debian:bookworm-slim +ARG DEBIAN_TAG=bookworm-slim +ARG DEBIAN_BASE_IMAGE=debian +FROM --platform=linux/amd64 ${DEBIAN_BASE_IMAGE}:${DEBIAN_TAG} # PORTER_INIT diff --git a/templates/shared_services/databricks-auth/Dockerfile.tmpl b/templates/shared_services/databricks-auth/Dockerfile.tmpl index abc241c3a1..8cf4c593a6 100644 --- a/templates/shared_services/databricks-auth/Dockerfile.tmpl +++ b/templates/shared_services/databricks-auth/Dockerfile.tmpl @@ -1,5 +1,7 @@ # syntax=docker/dockerfile-upstream:1.4.0 -FROM --platform=linux/amd64 debian:bookworm-slim +ARG DEBIAN_TAG=bookworm-slim +ARG DEBIAN_BASE_IMAGE=debian +FROM --platform=linux/amd64 ${DEBIAN_BASE_IMAGE}:${DEBIAN_TAG} # PORTER_INIT diff --git a/templates/shared_services/firewall/Dockerfile.tmpl b/templates/shared_services/firewall/Dockerfile.tmpl index 4494f207a1..95c4e67f38 100644 --- a/templates/shared_services/firewall/Dockerfile.tmpl +++ b/templates/shared_services/firewall/Dockerfile.tmpl @@ -1,5 +1,7 @@ # syntax=docker/dockerfile-upstream:1.4.0 -FROM --platform=linux/amd64 debian:bookworm-slim +ARG DEBIAN_TAG=bookworm-slim +ARG DEBIAN_BASE_IMAGE=debian +FROM --platform=linux/amd64 ${DEBIAN_BASE_IMAGE}:${DEBIAN_TAG} # PORTER_INIT diff --git a/templates/shared_services/gitea/Dockerfile.tmpl b/templates/shared_services/gitea/Dockerfile.tmpl index abc241c3a1..8cf4c593a6 100644 --- a/templates/shared_services/gitea/Dockerfile.tmpl +++ b/templates/shared_services/gitea/Dockerfile.tmpl @@ -1,5 +1,7 @@ # syntax=docker/dockerfile-upstream:1.4.0 -FROM --platform=linux/amd64 debian:bookworm-slim +ARG DEBIAN_TAG=bookworm-slim +ARG DEBIAN_BASE_IMAGE=debian +FROM --platform=linux/amd64 ${DEBIAN_BASE_IMAGE}:${DEBIAN_TAG} # PORTER_INIT diff --git a/templates/shared_services/sonatype-nexus-vm/Dockerfile.tmpl b/templates/shared_services/sonatype-nexus-vm/Dockerfile.tmpl index 4494f207a1..95c4e67f38 100644 --- a/templates/shared_services/sonatype-nexus-vm/Dockerfile.tmpl +++ b/templates/shared_services/sonatype-nexus-vm/Dockerfile.tmpl @@ -1,5 +1,7 @@ # syntax=docker/dockerfile-upstream:1.4.0 -FROM --platform=linux/amd64 debian:bookworm-slim +ARG DEBIAN_TAG=bookworm-slim +ARG DEBIAN_BASE_IMAGE=debian +FROM --platform=linux/amd64 ${DEBIAN_BASE_IMAGE}:${DEBIAN_TAG} # PORTER_INIT diff --git a/templates/workspace_services/azureml/Dockerfile.tmpl b/templates/workspace_services/azureml/Dockerfile.tmpl index 44ffe027c8..14df9b4af3 100644 --- a/templates/workspace_services/azureml/Dockerfile.tmpl +++ b/templates/workspace_services/azureml/Dockerfile.tmpl @@ -1,5 +1,7 @@ # syntax=docker/dockerfile-upstream:1.4.0 -FROM --platform=linux/amd64 debian:bookworm-slim +ARG DEBIAN_TAG=bookworm-slim +ARG DEBIAN_BASE_IMAGE=debian +FROM --platform=linux/amd64 ${DEBIAN_BASE_IMAGE}:${DEBIAN_TAG} # PORTER_INIT diff --git a/templates/workspace_services/azureml/user_resources/aml_compute/Dockerfile.tmpl b/templates/workspace_services/azureml/user_resources/aml_compute/Dockerfile.tmpl index 4494f207a1..95c4e67f38 100644 --- a/templates/workspace_services/azureml/user_resources/aml_compute/Dockerfile.tmpl +++ b/templates/workspace_services/azureml/user_resources/aml_compute/Dockerfile.tmpl @@ -1,5 +1,7 @@ # syntax=docker/dockerfile-upstream:1.4.0 -FROM --platform=linux/amd64 debian:bookworm-slim +ARG DEBIAN_TAG=bookworm-slim +ARG DEBIAN_BASE_IMAGE=debian +FROM --platform=linux/amd64 ${DEBIAN_BASE_IMAGE}:${DEBIAN_TAG} # PORTER_INIT diff --git a/templates/workspace_services/azuresql/Dockerfile.tmpl b/templates/workspace_services/azuresql/Dockerfile.tmpl index abc241c3a1..8cf4c593a6 100644 --- a/templates/workspace_services/azuresql/Dockerfile.tmpl +++ b/templates/workspace_services/azuresql/Dockerfile.tmpl @@ -1,5 +1,7 @@ # syntax=docker/dockerfile-upstream:1.4.0 -FROM --platform=linux/amd64 debian:bookworm-slim +ARG DEBIAN_TAG=bookworm-slim +ARG DEBIAN_BASE_IMAGE=debian +FROM --platform=linux/amd64 ${DEBIAN_BASE_IMAGE}:${DEBIAN_TAG} # PORTER_INIT diff --git a/templates/workspace_services/databricks/Dockerfile.tmpl b/templates/workspace_services/databricks/Dockerfile.tmpl index c85d6bd038..8cb83087fa 100644 --- a/templates/workspace_services/databricks/Dockerfile.tmpl +++ b/templates/workspace_services/databricks/Dockerfile.tmpl @@ -1,5 +1,7 @@ # syntax=docker/dockerfile-upstream:1.4.0 -FROM --platform=linux/amd64 debian:bookworm-slim +ARG DEBIAN_TAG=bookworm-slim +ARG DEBIAN_BASE_IMAGE=debian +FROM --platform=linux/amd64 ${DEBIAN_BASE_IMAGE}:${DEBIAN_TAG} # PORTER_INIT diff --git a/templates/workspace_services/gitea/Dockerfile.tmpl b/templates/workspace_services/gitea/Dockerfile.tmpl index abc241c3a1..8cf4c593a6 100644 --- a/templates/workspace_services/gitea/Dockerfile.tmpl +++ b/templates/workspace_services/gitea/Dockerfile.tmpl @@ -1,5 +1,7 @@ # syntax=docker/dockerfile-upstream:1.4.0 -FROM --platform=linux/amd64 debian:bookworm-slim +ARG DEBIAN_TAG=bookworm-slim +ARG DEBIAN_BASE_IMAGE=debian +FROM --platform=linux/amd64 ${DEBIAN_BASE_IMAGE}:${DEBIAN_TAG} # PORTER_INIT diff --git a/templates/workspace_services/guacamole/Dockerfile.tmpl b/templates/workspace_services/guacamole/Dockerfile.tmpl index abc241c3a1..8cf4c593a6 100644 --- a/templates/workspace_services/guacamole/Dockerfile.tmpl +++ b/templates/workspace_services/guacamole/Dockerfile.tmpl @@ -1,5 +1,7 @@ # syntax=docker/dockerfile-upstream:1.4.0 -FROM --platform=linux/amd64 debian:bookworm-slim +ARG DEBIAN_TAG=bookworm-slim +ARG DEBIAN_BASE_IMAGE=debian +FROM --platform=linux/amd64 ${DEBIAN_BASE_IMAGE}:${DEBIAN_TAG} # PORTER_INIT diff --git a/templates/workspace_services/guacamole/e2e-tests/playwright/Dockerfile b/templates/workspace_services/guacamole/e2e-tests/playwright/Dockerfile index 202b4336af..4b15b177bf 100644 --- a/templates/workspace_services/guacamole/e2e-tests/playwright/Dockerfile +++ b/templates/workspace_services/guacamole/e2e-tests/playwright/Dockerfile @@ -1,4 +1,6 @@ -FROM mcr.microsoft.com/playwright:v1.56.1-noble +ARG PLAYWRIGHT_TAG=v1.56.1-noble +ARG PLAYWRIGHT_BASE_IMAGE=mcr.microsoft.com/playwright +FROM ${PLAYWRIGHT_BASE_IMAGE}:${PLAYWRIGHT_TAG} WORKDIR /app diff --git a/templates/workspace_services/guacamole/guacamole-server/docker/Dockerfile b/templates/workspace_services/guacamole/guacamole-server/docker/Dockerfile index 016650fa48..1115bd92e8 100644 --- a/templates/workspace_services/guacamole/guacamole-server/docker/Dockerfile +++ b/templates/workspace_services/guacamole/guacamole-server/docker/Dockerfile @@ -1,6 +1,8 @@ -ARG MAVEN_BASE_IMAGE=maven:3.9-eclipse-temurin-17-alpine -ARG GUACD_BASE_IMAGE=guacamole/guacd:1.6.0 -FROM ${MAVEN_BASE_IMAGE} AS client_build +ARG MAVEN_TAG=3.9-eclipse-temurin-17-alpine +ARG MAVEN_BASE_IMAGE=maven +ARG GUACD_TAG=1.6.0 +ARG GUACD_BASE_IMAGE=guacamole/guacd +FROM ${MAVEN_BASE_IMAGE}:${MAVEN_TAG} AS client_build COPY ./guacamole-auth-azure/pom.xml /pom.xml # cache dependencies in a separate layer @@ -13,7 +15,7 @@ RUN bash /tmp/maven_package_and_exit_succesfully.sh FROM scratch AS test-results COPY --from=client_build /target/surefire-reports/* / -FROM ${GUACD_BASE_IMAGE} +FROM ${GUACD_BASE_IMAGE}:${GUACD_TAG} ARG GUACAMOLE_AZURE_VERSION=0.5.0 diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-export-reviewvm/Dockerfile.tmpl b/templates/workspace_services/guacamole/user_resources/guacamole-azure-export-reviewvm/Dockerfile.tmpl index 4494f207a1..95c4e67f38 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-export-reviewvm/Dockerfile.tmpl +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-export-reviewvm/Dockerfile.tmpl @@ -1,5 +1,7 @@ # syntax=docker/dockerfile-upstream:1.4.0 -FROM --platform=linux/amd64 debian:bookworm-slim +ARG DEBIAN_TAG=bookworm-slim +ARG DEBIAN_BASE_IMAGE=debian +FROM --platform=linux/amd64 ${DEBIAN_BASE_IMAGE}:${DEBIAN_TAG} # PORTER_INIT diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-import-reviewvm/Dockerfile.tmpl b/templates/workspace_services/guacamole/user_resources/guacamole-azure-import-reviewvm/Dockerfile.tmpl index 4494f207a1..95c4e67f38 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-import-reviewvm/Dockerfile.tmpl +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-import-reviewvm/Dockerfile.tmpl @@ -1,5 +1,7 @@ # syntax=docker/dockerfile-upstream:1.4.0 -FROM --platform=linux/amd64 debian:bookworm-slim +ARG DEBIAN_TAG=bookworm-slim +ARG DEBIAN_BASE_IMAGE=debian +FROM --platform=linux/amd64 ${DEBIAN_BASE_IMAGE}:${DEBIAN_TAG} # PORTER_INIT diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/Dockerfile.tmpl b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/Dockerfile.tmpl index 4494f207a1..95c4e67f38 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/Dockerfile.tmpl +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/Dockerfile.tmpl @@ -1,5 +1,7 @@ # syntax=docker/dockerfile-upstream:1.4.0 -FROM --platform=linux/amd64 debian:bookworm-slim +ARG DEBIAN_TAG=bookworm-slim +ARG DEBIAN_BASE_IMAGE=debian +FROM --platform=linux/amd64 ${DEBIAN_BASE_IMAGE}:${DEBIAN_TAG} # PORTER_INIT diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/Dockerfile.tmpl b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/Dockerfile.tmpl index 4494f207a1..95c4e67f38 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/Dockerfile.tmpl +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/Dockerfile.tmpl @@ -1,5 +1,7 @@ # syntax=docker/dockerfile-upstream:1.4.0 -FROM --platform=linux/amd64 debian:bookworm-slim +ARG DEBIAN_TAG=bookworm-slim +ARG DEBIAN_BASE_IMAGE=debian +FROM --platform=linux/amd64 ${DEBIAN_BASE_IMAGE}:${DEBIAN_TAG} # PORTER_INIT diff --git a/templates/workspace_services/health-services/Dockerfile.tmpl b/templates/workspace_services/health-services/Dockerfile.tmpl index 44ffe027c8..14df9b4af3 100644 --- a/templates/workspace_services/health-services/Dockerfile.tmpl +++ b/templates/workspace_services/health-services/Dockerfile.tmpl @@ -1,5 +1,7 @@ # syntax=docker/dockerfile-upstream:1.4.0 -FROM --platform=linux/amd64 debian:bookworm-slim +ARG DEBIAN_TAG=bookworm-slim +ARG DEBIAN_BASE_IMAGE=debian +FROM --platform=linux/amd64 ${DEBIAN_BASE_IMAGE}:${DEBIAN_TAG} # PORTER_INIT diff --git a/templates/workspace_services/mysql/Dockerfile.tmpl b/templates/workspace_services/mysql/Dockerfile.tmpl index abc241c3a1..8cf4c593a6 100644 --- a/templates/workspace_services/mysql/Dockerfile.tmpl +++ b/templates/workspace_services/mysql/Dockerfile.tmpl @@ -1,5 +1,7 @@ # syntax=docker/dockerfile-upstream:1.4.0 -FROM --platform=linux/amd64 debian:bookworm-slim +ARG DEBIAN_TAG=bookworm-slim +ARG DEBIAN_BASE_IMAGE=debian +FROM --platform=linux/amd64 ${DEBIAN_BASE_IMAGE}:${DEBIAN_TAG} # PORTER_INIT diff --git a/templates/workspace_services/ohdsi/Dockerfile.tmpl b/templates/workspace_services/ohdsi/Dockerfile.tmpl index 12a32994a5..e89442d0d3 100644 --- a/templates/workspace_services/ohdsi/Dockerfile.tmpl +++ b/templates/workspace_services/ohdsi/Dockerfile.tmpl @@ -1,5 +1,7 @@ # syntax=docker/dockerfile-upstream:1.4.0 -FROM --platform=linux/amd64 debian:bullseye-slim +ARG DEBIAN_TAG=bullseye-slim +ARG DEBIAN_BASE_IMAGE=debian +FROM --platform=linux/amd64 ${DEBIAN_BASE_IMAGE}:${DEBIAN_TAG} # PORTER_INIT diff --git a/templates/workspace_services/openai/Dockerfile.tmpl b/templates/workspace_services/openai/Dockerfile.tmpl index abc241c3a1..8cf4c593a6 100644 --- a/templates/workspace_services/openai/Dockerfile.tmpl +++ b/templates/workspace_services/openai/Dockerfile.tmpl @@ -1,5 +1,7 @@ # syntax=docker/dockerfile-upstream:1.4.0 -FROM --platform=linux/amd64 debian:bookworm-slim +ARG DEBIAN_TAG=bookworm-slim +ARG DEBIAN_BASE_IMAGE=debian +FROM --platform=linux/amd64 ${DEBIAN_BASE_IMAGE}:${DEBIAN_TAG} # PORTER_INIT diff --git a/templates/workspaces/airlock-import-review/Dockerfile.tmpl b/templates/workspaces/airlock-import-review/Dockerfile.tmpl index 4a9293704a..f5aeccc6af 100644 --- a/templates/workspaces/airlock-import-review/Dockerfile.tmpl +++ b/templates/workspaces/airlock-import-review/Dockerfile.tmpl @@ -1,5 +1,7 @@ # syntax=docker/dockerfile-upstream:1.4.0 -FROM --platform=linux/amd64 debian:bookworm-slim +ARG DEBIAN_TAG=bookworm-slim +ARG DEBIAN_BASE_IMAGE=debian +FROM --platform=linux/amd64 ${DEBIAN_BASE_IMAGE}:${DEBIAN_TAG} # PORTER_INIT diff --git a/templates/workspaces/base/Dockerfile.tmpl b/templates/workspaces/base/Dockerfile.tmpl index 44ffe027c8..14df9b4af3 100644 --- a/templates/workspaces/base/Dockerfile.tmpl +++ b/templates/workspaces/base/Dockerfile.tmpl @@ -1,5 +1,7 @@ # syntax=docker/dockerfile-upstream:1.4.0 -FROM --platform=linux/amd64 debian:bookworm-slim +ARG DEBIAN_TAG=bookworm-slim +ARG DEBIAN_BASE_IMAGE=debian +FROM --platform=linux/amd64 ${DEBIAN_BASE_IMAGE}:${DEBIAN_TAG} # PORTER_INIT diff --git a/templates/workspaces/unrestricted/Dockerfile.tmpl b/templates/workspaces/unrestricted/Dockerfile.tmpl index 1b12132325..0a11c4f2c4 100644 --- a/templates/workspaces/unrestricted/Dockerfile.tmpl +++ b/templates/workspaces/unrestricted/Dockerfile.tmpl @@ -1,5 +1,7 @@ # syntax=docker/dockerfile-upstream:1.4.0 -FROM --platform=linux/amd64 debian:bookworm-slim +ARG DEBIAN_TAG=bookworm-slim +ARG DEBIAN_BASE_IMAGE=debian +FROM --platform=linux/amd64 ${DEBIAN_BASE_IMAGE}:${DEBIAN_TAG} # PORTER_INIT From 1962e382acb3e89b1032f7f7aff6782d9b580bf5 Mon Sep 17 00:00:00 2001 From: Max Martin Date: Fri, 17 Jul 2026 15:15:27 +0100 Subject: [PATCH 10/16] Update version numbers in multiple porter.yaml files and add build args for Docker images --- .github/workflows/build_docker_images.yml | 4 ++++ templates/shared_services/admin-vm/porter.yaml | 2 +- templates/shared_services/airlock_notifier/porter.yaml | 2 +- templates/shared_services/certs/porter.yaml | 2 +- templates/shared_services/cyclecloud/porter.yaml | 2 +- templates/shared_services/databricks-auth/porter.yaml | 2 +- templates/shared_services/firewall/porter.yaml | 2 +- templates/shared_services/gitea/porter.yaml | 2 +- templates/shared_services/sonatype-nexus-vm/porter.yaml | 2 +- templates/workspace_services/azureml/porter.yaml | 2 +- .../azureml/user_resources/aml_compute/porter.yaml | 2 +- templates/workspace_services/azuresql/porter.yaml | 2 +- templates/workspace_services/databricks/porter.yaml | 2 +- templates/workspace_services/gitea/porter.yaml | 2 +- templates/workspace_services/guacamole/porter.yaml | 2 +- .../guacamole-azure-export-reviewvm/porter.yaml | 2 +- .../guacamole-azure-import-reviewvm/porter.yaml | 2 +- .../user_resources/guacamole-azure-linuxvm/porter.yaml | 2 +- .../user_resources/guacamole-azure-windowsvm/porter.yaml | 2 +- templates/workspace_services/health-services/porter.yaml | 2 +- templates/workspace_services/mysql/porter.yaml | 2 +- templates/workspace_services/ohdsi/porter.yaml | 2 +- templates/workspace_services/openai/porter.yaml | 2 +- templates/workspaces/airlock-import-review/porter.yaml | 2 +- templates/workspaces/base/porter.yaml | 2 +- templates/workspaces/unrestricted/porter.yaml | 2 +- 26 files changed, 29 insertions(+), 25 deletions(-) diff --git a/.github/workflows/build_docker_images.yml b/.github/workflows/build_docker_images.yml index e1f1e4e976..c3b52d5dbb 100644 --- a/.github/workflows/build_docker_images.yml +++ b/.github/workflows/build_docker_images.yml @@ -258,6 +258,8 @@ jobs: with: context: ./airlock_processor/ file: ./airlock_processor/Dockerfile + build-args: | + PYTHON_BASE_IMAGE=${{ env.PYTHON_BASE_IMAGE }} outputs: type=local,dest=test-results target: test-results cache-from: type=gha @@ -278,6 +280,8 @@ jobs: with: context: ./airlock_processor/ file: ./airlock_processor/Dockerfile + build-args: | + PYTHON_BASE_IMAGE=${{ env.PYTHON_BASE_IMAGE }} cache-from: type=gha cache-to: type=gha,mode=max diff --git a/templates/shared_services/admin-vm/porter.yaml b/templates/shared_services/admin-vm/porter.yaml index 9cbdf3eaa0..63353d5bc5 100644 --- a/templates/shared_services/admin-vm/porter.yaml +++ b/templates/shared_services/admin-vm/porter.yaml @@ -1,7 +1,7 @@ --- schemaVersion: 1.0.0 name: tre-shared-service-admin-vm -version: 0.5.4 +version: 0.5.5 description: "An admin vm shared service" dockerfile: Dockerfile.tmpl registry: azuretre diff --git a/templates/shared_services/airlock_notifier/porter.yaml b/templates/shared_services/airlock_notifier/porter.yaml index 700821b6cd..9a60dba981 100644 --- a/templates/shared_services/airlock_notifier/porter.yaml +++ b/templates/shared_services/airlock_notifier/porter.yaml @@ -1,7 +1,7 @@ --- schemaVersion: 1.0.0 name: tre-shared-service-airlock-notifier -version: 1.0.10 +version: 1.0.11 description: "A shared service notifying on Airlock Operations" registry: azuretre dockerfile: Dockerfile.tmpl diff --git a/templates/shared_services/certs/porter.yaml b/templates/shared_services/certs/porter.yaml index 7d01fd7630..bb61f19c01 100755 --- a/templates/shared_services/certs/porter.yaml +++ b/templates/shared_services/certs/porter.yaml @@ -1,7 +1,7 @@ --- schemaVersion: 1.0.0 name: tre-shared-service-certs -version: 0.7.10 +version: 0.7.11 description: "An Azure TRE shared service to generate certificates for a specified internal domain using Letsencrypt" registry: azuretre dockerfile: Dockerfile.tmpl diff --git a/templates/shared_services/cyclecloud/porter.yaml b/templates/shared_services/cyclecloud/porter.yaml index df454e012a..48e3f40ab9 100644 --- a/templates/shared_services/cyclecloud/porter.yaml +++ b/templates/shared_services/cyclecloud/porter.yaml @@ -1,7 +1,7 @@ --- schemaVersion: 1.0.0 name: tre-shared-service-cyclecloud -version: 0.7.5 +version: 0.7.6 description: "An Azure TRE Shared Service Template for Azure Cyclecloud" registry: azuretre dockerfile: Dockerfile.tmpl diff --git a/templates/shared_services/databricks-auth/porter.yaml b/templates/shared_services/databricks-auth/porter.yaml index f7d34be8cc..37c92151b6 100644 --- a/templates/shared_services/databricks-auth/porter.yaml +++ b/templates/shared_services/databricks-auth/porter.yaml @@ -1,7 +1,7 @@ --- schemaVersion: 1.0.0 name: tre-shared-service-databricks-private-auth -version: 0.1.14 +version: 0.1.15 description: "An Azure TRE shared service for Azure Databricks authentication." registry: azuretre dockerfile: Dockerfile.tmpl diff --git a/templates/shared_services/firewall/porter.yaml b/templates/shared_services/firewall/porter.yaml index e8399e844b..45174e8ae1 100644 --- a/templates/shared_services/firewall/porter.yaml +++ b/templates/shared_services/firewall/porter.yaml @@ -1,7 +1,7 @@ --- schemaVersion: 1.0.0 name: tre-shared-service-firewall -version: 1.6.1 +version: 1.6.2 description: "An Azure TRE Firewall shared service" dockerfile: Dockerfile.tmpl registry: azuretre diff --git a/templates/shared_services/gitea/porter.yaml b/templates/shared_services/gitea/porter.yaml index f9a76a7565..700be2a7f6 100644 --- a/templates/shared_services/gitea/porter.yaml +++ b/templates/shared_services/gitea/porter.yaml @@ -1,7 +1,7 @@ --- schemaVersion: 1.0.0 name: tre-shared-service-gitea -version: 1.2.2 +version: 1.2.3 description: "A Gitea shared service" dockerfile: Dockerfile.tmpl registry: azuretre diff --git a/templates/shared_services/sonatype-nexus-vm/porter.yaml b/templates/shared_services/sonatype-nexus-vm/porter.yaml index b9e11dd85f..d43add938a 100644 --- a/templates/shared_services/sonatype-nexus-vm/porter.yaml +++ b/templates/shared_services/sonatype-nexus-vm/porter.yaml @@ -1,7 +1,7 @@ --- schemaVersion: 1.0.0 name: tre-shared-service-sonatype-nexus -version: 3.7.9 +version: 3.7.10 description: "A Sonatype Nexus shared service" dockerfile: Dockerfile.tmpl registry: azuretre diff --git a/templates/workspace_services/azureml/porter.yaml b/templates/workspace_services/azureml/porter.yaml index d6d4593ad4..723713cf35 100644 --- a/templates/workspace_services/azureml/porter.yaml +++ b/templates/workspace_services/azureml/porter.yaml @@ -1,7 +1,7 @@ --- schemaVersion: 1.0.0 name: tre-service-azureml -version: 1.1.4 +version: 1.1.5 description: "An Azure TRE service for Azure Machine Learning" registry: azuretre dockerfile: Dockerfile.tmpl diff --git a/templates/workspace_services/azureml/user_resources/aml_compute/porter.yaml b/templates/workspace_services/azureml/user_resources/aml_compute/porter.yaml index 34d3ee7844..b3c529c996 100644 --- a/templates/workspace_services/azureml/user_resources/aml_compute/porter.yaml +++ b/templates/workspace_services/azureml/user_resources/aml_compute/porter.yaml @@ -1,7 +1,7 @@ --- schemaVersion: 1.0.0 name: tre-user-resource-aml-compute-instance -version: 0.5.12 +version: 0.5.13 description: "Azure Machine Learning Compute Instance" registry: azuretre dockerfile: Dockerfile.tmpl diff --git a/templates/workspace_services/azuresql/porter.yaml b/templates/workspace_services/azuresql/porter.yaml index 7e72065bba..48e969cb9b 100644 --- a/templates/workspace_services/azuresql/porter.yaml +++ b/templates/workspace_services/azuresql/porter.yaml @@ -1,7 +1,7 @@ --- schemaVersion: 1.0.0 name: tre-workspace-service-azuresql -version: 1.0.17 +version: 1.0.18 description: "An Azure SQL workspace service" registry: azuretre dockerfile: Dockerfile.tmpl diff --git a/templates/workspace_services/databricks/porter.yaml b/templates/workspace_services/databricks/porter.yaml index abfdd18a83..4e913a4e09 100644 --- a/templates/workspace_services/databricks/porter.yaml +++ b/templates/workspace_services/databricks/porter.yaml @@ -1,7 +1,7 @@ --- schemaVersion: 1.0.0 name: tre-service-databricks -version: 1.0.16 +version: 1.0.17 description: "An Azure TRE service for Azure Databricks." registry: azuretre dockerfile: Dockerfile.tmpl diff --git a/templates/workspace_services/gitea/porter.yaml b/templates/workspace_services/gitea/porter.yaml index f9044eb34e..39621ab355 100644 --- a/templates/workspace_services/gitea/porter.yaml +++ b/templates/workspace_services/gitea/porter.yaml @@ -1,7 +1,7 @@ --- schemaVersion: 1.0.0 name: tre-workspace-service-gitea -version: 1.3.3 +version: 1.3.4 description: "A Gitea workspace service" dockerfile: Dockerfile.tmpl registry: azuretre diff --git a/templates/workspace_services/guacamole/porter.yaml b/templates/workspace_services/guacamole/porter.yaml index b2ce9174b4..8f172fe986 100644 --- a/templates/workspace_services/guacamole/porter.yaml +++ b/templates/workspace_services/guacamole/porter.yaml @@ -1,7 +1,7 @@ --- schemaVersion: 1.0.0 name: tre-service-guacamole -version: 0.14.2 +version: 0.14.3 description: "An Azure TRE service for Guacamole" dockerfile: Dockerfile.tmpl registry: azuretre diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-export-reviewvm/porter.yaml b/templates/workspace_services/guacamole/user_resources/guacamole-azure-export-reviewvm/porter.yaml index 83b05768ce..975cf77416 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-export-reviewvm/porter.yaml +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-export-reviewvm/porter.yaml @@ -1,7 +1,7 @@ --- schemaVersion: 1.0.0 name: tre-service-guacamole-export-reviewvm -version: 0.3.7 +version: 0.3.8 description: "An Azure TRE User Resource Template for reviewing Airlock export requests" dockerfile: Dockerfile.tmpl registry: azuretre diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-import-reviewvm/porter.yaml b/templates/workspace_services/guacamole/user_resources/guacamole-azure-import-reviewvm/porter.yaml index a2fbed781e..fe445ece10 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-import-reviewvm/porter.yaml +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-import-reviewvm/porter.yaml @@ -1,7 +1,7 @@ --- schemaVersion: 1.0.0 name: tre-service-guacamole-import-reviewvm -version: 0.4.6 +version: 0.4.7 description: "An Azure TRE User Resource Template for reviewing Airlock import requests" dockerfile: Dockerfile.tmpl registry: azuretre diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/porter.yaml b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/porter.yaml index 186da0d571..f95113432c 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/porter.yaml +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/porter.yaml @@ -1,7 +1,7 @@ --- schemaVersion: 1.0.0 name: tre-service-guacamole-linuxvm -version: 1.4.3 +version: 1.4.4 description: "An Azure TRE User Resource Template for Guacamole (Linux)" dockerfile: Dockerfile.tmpl registry: azuretre diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/porter.yaml b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/porter.yaml index f7e7bd963d..ea5de7a2e4 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/porter.yaml +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/porter.yaml @@ -1,7 +1,7 @@ --- schemaVersion: 1.0.0 name: tre-service-guacamole-windowsvm -version: 1.4.6 +version: 1.4.7 description: "An Azure TRE User Resource Template for Guacamole (Windows 11 or Windows Server 2025)" dockerfile: Dockerfile.tmpl registry: azuretre diff --git a/templates/workspace_services/health-services/porter.yaml b/templates/workspace_services/health-services/porter.yaml index d7dd92c469..c59b50f62d 100644 --- a/templates/workspace_services/health-services/porter.yaml +++ b/templates/workspace_services/health-services/porter.yaml @@ -1,7 +1,7 @@ --- schemaVersion: 1.0.0 name: tre-workspace-service-health -version: 0.3.5 +version: 0.3.6 description: "An Azure Data Health Services workspace service" registry: azuretre dockerfile: Dockerfile.tmpl diff --git a/templates/workspace_services/mysql/porter.yaml b/templates/workspace_services/mysql/porter.yaml index 80ce54d0a8..fb18c7bf97 100644 --- a/templates/workspace_services/mysql/porter.yaml +++ b/templates/workspace_services/mysql/porter.yaml @@ -1,7 +1,7 @@ --- schemaVersion: 1.0.0 name: tre-workspace-service-mysql -version: 1.0.12 +version: 1.0.13 description: "A MySQL workspace service" registry: azuretre dockerfile: Dockerfile.tmpl diff --git a/templates/workspace_services/ohdsi/porter.yaml b/templates/workspace_services/ohdsi/porter.yaml index ca5e7ef556..7c9aa6caae 100644 --- a/templates/workspace_services/ohdsi/porter.yaml +++ b/templates/workspace_services/ohdsi/porter.yaml @@ -1,7 +1,7 @@ --- schemaVersion: 1.0.0 name: tre-workspace-service-ohdsi -version: 0.3.7 +version: 0.3.8 description: "An OHDSI workspace service" registry: azuretre dockerfile: Dockerfile.tmpl diff --git a/templates/workspace_services/openai/porter.yaml b/templates/workspace_services/openai/porter.yaml index 4ad4efc6b9..f5d2a8383d 100644 --- a/templates/workspace_services/openai/porter.yaml +++ b/templates/workspace_services/openai/porter.yaml @@ -1,7 +1,7 @@ --- schemaVersion: 1.0.0 name: tre-workspace-service-openai -version: 1.0.8 +version: 1.0.9 description: "An OpenAI workspace service" registry: azuretre dockerfile: Dockerfile.tmpl diff --git a/templates/workspaces/airlock-import-review/porter.yaml b/templates/workspaces/airlock-import-review/porter.yaml index 464a41d4f7..3e56028346 100644 --- a/templates/workspaces/airlock-import-review/porter.yaml +++ b/templates/workspaces/airlock-import-review/porter.yaml @@ -1,7 +1,7 @@ --- schemaVersion: 1.0.0 name: tre-workspace-airlock-import-review -version: 0.15.0 +version: 0.15.1 description: "A workspace to do Airlock Data Import Reviews for Azure TRE" dockerfile: Dockerfile.tmpl registry: azuretre diff --git a/templates/workspaces/base/porter.yaml b/templates/workspaces/base/porter.yaml index 22cb6cdfc3..456e99b854 100644 --- a/templates/workspaces/base/porter.yaml +++ b/templates/workspaces/base/porter.yaml @@ -1,7 +1,7 @@ --- schemaVersion: 1.0.0 name: tre-workspace-base -version: 2.8.4 +version: 2.8.5 description: "A base Azure TRE workspace" dockerfile: Dockerfile.tmpl registry: azuretre diff --git a/templates/workspaces/unrestricted/porter.yaml b/templates/workspaces/unrestricted/porter.yaml index bd4373b587..ede4b755dc 100644 --- a/templates/workspaces/unrestricted/porter.yaml +++ b/templates/workspaces/unrestricted/porter.yaml @@ -1,7 +1,7 @@ --- schemaVersion: 1.0.0 name: tre-workspace-unrestricted -version: 0.13.7 +version: 0.13.8 description: "A base Azure TRE workspace" dockerfile: Dockerfile.tmpl registry: azuretre From c8fee2df884951e6db27eab8b653f65a4687c68e Mon Sep 17 00:00:00 2001 From: Max Martin Date: Fri, 17 Jul 2026 15:21:11 +0100 Subject: [PATCH 11/16] Bump airlock processor version --- airlock_processor/_version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/airlock_processor/_version.py b/airlock_processor/_version.py index 1d16920cdb..cb4382b891 100644 --- a/airlock_processor/_version.py +++ b/airlock_processor/_version.py @@ -1 +1 @@ -__version__ = "0.8.11" +__version__ = "0.8.12" From 5bcc4d88d03977ccfee922fbd130be48b383c320 Mon Sep 17 00:00:00 2001 From: Max Martin Date: Fri, 17 Jul 2026 16:11:17 +0100 Subject: [PATCH 12/16] Update Docker build workflows to utilize ACR for base images and tags --- .github/workflows/build_docker_images.yml | 35 +++++++++++++++++----- .github/workflows/sync_acr_base_images.yml | 1 + 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build_docker_images.yml b/.github/workflows/build_docker_images.yml index c3b52d5dbb..d258cd5f07 100644 --- a/.github/workflows/build_docker_images.yml +++ b/.github/workflows/build_docker_images.yml @@ -24,20 +24,29 @@ jobs: env: PYTHON_BASE_IMAGE: >- ${{ vars.ACR_BASE_IMAGE_PREFIX != '' && - format('{0}/mirror/library/python:3.12-slim-bookworm', vars.ACR_BASE_IMAGE_PREFIX) - || 'python:3.12-slim-bookworm' }} + format('{0}/mirror/library/python', vars.ACR_BASE_IMAGE_PREFIX) + || 'python' }} + PYTHON_TAG: 3.12-slim-bookworm + AIRLOCK_PYTHON_BASE_IMAGE: >- + ${{ vars.ACR_BASE_IMAGE_PREFIX != '' && + format('{0}/mirror/mcr/azure-functions/python', vars.ACR_BASE_IMAGE_PREFIX) + || 'mcr.microsoft.com/azure-functions/python' }} + AIRLOCK_PYTHON_TAG: 4-python3.12 MAVEN_BASE_IMAGE: >- ${{ vars.ACR_BASE_IMAGE_PREFIX != '' && - format('{0}/mirror/library/maven:3.9-eclipse-temurin-17-alpine', vars.ACR_BASE_IMAGE_PREFIX) - || 'maven:3.9-eclipse-temurin-17-alpine' }} + format('{0}/mirror/library/maven', vars.ACR_BASE_IMAGE_PREFIX) + || 'maven' }} + MAVEN_TAG: 3.9-eclipse-temurin-17-alpine GUACD_BASE_IMAGE: >- ${{ vars.ACR_BASE_IMAGE_PREFIX != '' && - format('{0}/mirror/guacamole/guacd:1.6.0', vars.ACR_BASE_IMAGE_PREFIX) - || 'guacamole/guacd:1.6.0' }} + format('{0}/mirror/guacamole/guacd', vars.ACR_BASE_IMAGE_PREFIX) + || 'guacamole/guacd' }} + GUACD_TAG: 1.6.0 GITEA_BASE_IMAGE_REPO: >- ${{ vars.ACR_BASE_IMAGE_PREFIX != '' && format('{0}/mirror/gitea/gitea', vars.ACR_BASE_IMAGE_PREFIX) || 'gitea/gitea' }} + GITEA_TAG: 1.15 permissions: contents: read actions: write # For uploading artifacts @@ -156,6 +165,7 @@ jobs: file: ./api_app/Dockerfile build-args: | PYTHON_BASE_IMAGE=${{ env.PYTHON_BASE_IMAGE }} + PYTHON_TAG=${{ env.PYTHON_TAG }} outputs: type=local,dest=test-results target: test-results cache-from: type=gha @@ -178,6 +188,7 @@ jobs: file: ./api_app/Dockerfile build-args: | PYTHON_BASE_IMAGE=${{ env.PYTHON_BASE_IMAGE }} + PYTHON_TAG=${{ env.PYTHON_TAG }} cache-from: type=gha cache-to: type=gha,mode=max @@ -191,6 +202,7 @@ jobs: file: ./resource_processor/vmss_porter/Dockerfile build-args: | PYTHON_BASE_IMAGE=${{ env.PYTHON_BASE_IMAGE }} + PYTHON_TAG=${{ env.PYTHON_TAG }} cache-from: type=gha cache-to: type=gha,mode=max @@ -204,7 +216,9 @@ jobs: file: ./templates/workspace_services/guacamole/guacamole-server/docker/Dockerfile build-args: | MAVEN_BASE_IMAGE=${{ env.MAVEN_BASE_IMAGE }} + MAVEN_TAG=${{ env.MAVEN_TAG }} GUACD_BASE_IMAGE=${{ env.GUACD_BASE_IMAGE }} + GUACD_TAG=${{ env.GUACD_TAG }} outputs: type=local,dest=test-results target: test-results cache-from: type=gha @@ -227,7 +241,9 @@ jobs: file: ./templates/workspace_services/guacamole/guacamole-server/docker/Dockerfile build-args: | MAVEN_BASE_IMAGE=${{ env.MAVEN_BASE_IMAGE }} + MAVEN_TAG=${{ env.MAVEN_TAG }} GUACD_BASE_IMAGE=${{ env.GUACD_BASE_IMAGE }} + GUACD_TAG=${{ env.GUACD_TAG }} cache-from: type=gha cache-to: type=gha,mode=max @@ -241,6 +257,7 @@ jobs: file: ./templates/shared_services/gitea/docker/Dockerfile build-args: | GITEA_BASE_IMAGE_REPO=${{ env.GITEA_BASE_IMAGE_REPO }} + GITEA_TAG=${{ env.GITEA_TAG }} cache-from: type=gha cache-to: type=gha,mode=max @@ -259,7 +276,8 @@ jobs: context: ./airlock_processor/ file: ./airlock_processor/Dockerfile build-args: | - PYTHON_BASE_IMAGE=${{ env.PYTHON_BASE_IMAGE }} + PYTHON_BASE_IMAGE=${{ env.AIRLOCK_PYTHON_BASE_IMAGE }} + PYTHON_TAG=${{ env.AIRLOCK_PYTHON_TAG }} outputs: type=local,dest=test-results target: test-results cache-from: type=gha @@ -281,7 +299,8 @@ jobs: context: ./airlock_processor/ file: ./airlock_processor/Dockerfile build-args: | - PYTHON_BASE_IMAGE=${{ env.PYTHON_BASE_IMAGE }} + PYTHON_BASE_IMAGE=${{ env.AIRLOCK_PYTHON_BASE_IMAGE }} + PYTHON_TAG=${{ env.AIRLOCK_PYTHON_TAG }} cache-from: type=gha cache-to: type=gha,mode=max diff --git a/.github/workflows/sync_acr_base_images.yml b/.github/workflows/sync_acr_base_images.yml index 2e2c78114e..3efd1a982a 100644 --- a/.github/workflows/sync_acr_base_images.yml +++ b/.github/workflows/sync_acr_base_images.yml @@ -65,6 +65,7 @@ jobs: "docker.io/guacamole/guacd|mirror/guacamole/guacd|1.6.0" "docker.io/gitea/gitea|mirror/gitea/gitea|1.15" "docker.io/gitea/gitea|mirror/gitea/gitea|1.17.3" + "mcr.microsoft.com/azure-functions/python|mirror/mcr/azure-functions/python|4-python3.12" "docker.io/library/debian|mirror/library/debian|bookworm-slim" "docker.io/library/debian|mirror/library/debian|bullseye-slim" ) From fb6537aa00633f0ead7366a26648e6696a4a6e83 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 20 Jul 2026 10:32:18 +0000 Subject: [PATCH 13/16] Fix ACR mirror review feedback --- .github/workflows/build_docker_images.yml | 83 +++++++++++++++----- CHANGELOG.md | 1 + devops/scripts/bundle_runtime_image_build.sh | 20 ++++- 3 files changed, 81 insertions(+), 23 deletions(-) diff --git a/.github/workflows/build_docker_images.yml b/.github/workflows/build_docker_images.yml index d258cd5f07..1ea63e3098 100644 --- a/.github/workflows/build_docker_images.yml +++ b/.github/workflows/build_docker_images.yml @@ -22,34 +22,15 @@ jobs: name: Build images runs-on: ubuntu-latest env: - PYTHON_BASE_IMAGE: >- - ${{ vars.ACR_BASE_IMAGE_PREFIX != '' && - format('{0}/mirror/library/python', vars.ACR_BASE_IMAGE_PREFIX) - || 'python' }} PYTHON_TAG: 3.12-slim-bookworm - AIRLOCK_PYTHON_BASE_IMAGE: >- - ${{ vars.ACR_BASE_IMAGE_PREFIX != '' && - format('{0}/mirror/mcr/azure-functions/python', vars.ACR_BASE_IMAGE_PREFIX) - || 'mcr.microsoft.com/azure-functions/python' }} AIRLOCK_PYTHON_TAG: 4-python3.12 - MAVEN_BASE_IMAGE: >- - ${{ vars.ACR_BASE_IMAGE_PREFIX != '' && - format('{0}/mirror/library/maven', vars.ACR_BASE_IMAGE_PREFIX) - || 'maven' }} MAVEN_TAG: 3.9-eclipse-temurin-17-alpine - GUACD_BASE_IMAGE: >- - ${{ vars.ACR_BASE_IMAGE_PREFIX != '' && - format('{0}/mirror/guacamole/guacd', vars.ACR_BASE_IMAGE_PREFIX) - || 'guacamole/guacd' }} GUACD_TAG: 1.6.0 - GITEA_BASE_IMAGE_REPO: >- - ${{ vars.ACR_BASE_IMAGE_PREFIX != '' && - format('{0}/mirror/gitea/gitea', vars.ACR_BASE_IMAGE_PREFIX) - || 'gitea/gitea' }} GITEA_TAG: 1.15 permissions: contents: read actions: write # For uploading artifacts + id-token: write # For Azure OIDC login when using ACR mirrors pull-requests: read # For path filter steps: - name: Upload Event File @@ -64,6 +45,68 @@ jobs: with: persist-credentials: false + - name: Determine ACR mirror availability + id: acr_mirror + env: + ACR_BASE_IMAGE_PREFIX: ${{ vars.ACR_BASE_IMAGE_PREFIX }} + ACR_NAME: ${{ secrets.ACR_NAME }} + AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }} + AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }} + AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }} + run: | + use_acr_mirrors=false + + if [[ -n "${ACR_BASE_IMAGE_PREFIX}" && + -n "${ACR_NAME}" && + -n "${AZURE_CLIENT_ID}" && + -n "${AZURE_TENANT_ID}" && + -n "${AZURE_SUBSCRIPTION_ID}" ]]; then + use_acr_mirrors=true + fi + + echo "use_acr_mirrors=${use_acr_mirrors}" >> "${GITHUB_OUTPUT}" + + - name: Azure Login for ACR mirror + if: ${{ steps.acr_mirror.outputs.use_acr_mirrors == 'true' }} + uses: azure/login@532459ea530d8321f2fb9bb10d1e0bcf23869a43 # v3.0.0 + with: + client-id: ${{ secrets.AZURE_CLIENT_ID }} + tenant-id: ${{ secrets.AZURE_TENANT_ID }} + subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} + environment: ${{ (vars.AZURE_ENVIRONMENT != '' && vars.AZURE_ENVIRONMENT) || 'AzureCloud' }} + + - name: Login to ACR mirror + if: ${{ steps.acr_mirror.outputs.use_acr_mirrors == 'true' }} + run: az acr login --name "${{ secrets.ACR_NAME }}" + + - name: Select Docker base image sources + env: + ACR_BASE_IMAGE_PREFIX: ${{ vars.ACR_BASE_IMAGE_PREFIX }} + run: | + prefix="${ACR_BASE_IMAGE_PREFIX}" + + python_base_image="python" + airlock_python_base_image="mcr.microsoft.com/azure-functions/python" + maven_base_image="maven" + guacd_base_image="guacamole/guacd" + gitea_base_image_repo="gitea/gitea" + + if [[ "${{ steps.acr_mirror.outputs.use_acr_mirrors }}" == 'true' ]]; then + python_base_image="${prefix}/mirror/library/python" + airlock_python_base_image="${prefix}/mirror/mcr/azure-functions/python" + maven_base_image="${prefix}/mirror/library/maven" + guacd_base_image="${prefix}/mirror/guacamole/guacd" + gitea_base_image_repo="${prefix}/mirror/gitea/gitea" + fi + + { + echo "PYTHON_BASE_IMAGE=${python_base_image}" + echo "AIRLOCK_PYTHON_BASE_IMAGE=${airlock_python_base_image}" + echo "MAVEN_BASE_IMAGE=${maven_base_image}" + echo "GUACD_BASE_IMAGE=${guacd_base_image}" + echo "GITEA_BASE_IMAGE_REPO=${gitea_base_image_repo}" + } >> "${GITHUB_ENV}" + - name: Filter changes uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # v4.0.1 id: filter diff --git a/CHANGELOG.md b/CHANGELOG.md index 6caf13e16a..467d0be0d8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ ENHANCEMENTS: * Updated the version of `super-linter` used in the `build_validation_develop` workflow ([#4957](https://github.com/microsoft/AzureTRE/issues/4957)) BUG FIXES: +* Fix Docker image workflows to authenticate before using private ACR mirrors and skip redundant runtime-image imports when the target tag is already present. ([#4952](https://github.com/microsoft/AzureTRE/pull/4952)) * Fix UI TypeScript deprecation warning by updating `moduleResolution` to `bundler` in `tsconfig.json`. ([#4968](https://github.com/microsoft/AzureTRE/issues/4968)) * Fix API timeout and name collision failures on workspace creation by checking storage account name availability and improved logging. ([#4946](https://github.com/microsoft/AzureTRE/pull/4946)) * Fix error handling in airlock processor ([#4929](https://github.com/microsoft/AzureTRE/pull/4929)) diff --git a/devops/scripts/bundle_runtime_image_build.sh b/devops/scripts/bundle_runtime_image_build.sh index f527245b37..38625a62c4 100755 --- a/devops/scripts/bundle_runtime_image_build.sh +++ b/devops/scripts/bundle_runtime_image_build.sh @@ -10,11 +10,26 @@ if [ "$(yq eval ".custom.runtime_image.import" porter.yaml)" != "null" ]; then image_name=$(yq eval ".custom.runtime_image.name" porter.yaml) source_image=$(yq eval ".custom.runtime_image.import.source" porter.yaml) version=$(yq eval ".custom.runtime_image.import.tag" porter.yaml) + target_image="${image_name}:${version}" - echo "Importing ${source_image}:${version} to ACR as ${image_name}:${version}..." + existing_digest=$(az acr repository show --name "${ACR_NAME}" \ + --image "${target_image}" \ + --query digest \ + --output tsv 2>/dev/null || true) + + if [ "${existing_digest}" = "null" ]; then + existing_digest="" + fi + + if [ -n "${existing_digest}" ]; then + echo "Image ${target_image} already exists in ACR with digest ${existing_digest}. Skipping import." + exit 0 + fi + + echo "Importing ${source_image}:${version} to ACR as ${target_image}..." az acr import --name "${ACR_NAME}" \ --source "${source_image}:${version}" \ - --image "${image_name}:${version}" \ + --image "${target_image}" \ --force echo "Image imported successfully" exit 0 @@ -58,4 +73,3 @@ fi ${DOCKER_BUILD_COMMAND} --build-arg BUILDKIT_INLINE_CACHE=1 \ -t "${FULL_IMAGE_NAME_PREFIX}/${image_name}:${version}" \ "${docker_cache[@]}" -f "${docker_file}" "${docker_context}" - From ae5b1015cce55bc7978c49c04efa9f248cc0338b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 20 Jul 2026 16:26:22 +0000 Subject: [PATCH 14/16] fix: use VARIANT directly in FROM tag, drop DEVCONTAINER_TAG ARG --- .devcontainer/Dockerfile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 13ee2d17aa..3c8807cd36 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -2,10 +2,9 @@ # [Choice] Python version: 3.11 3.12, 3.13 ARG VARIANT="3.12" -ARG DEVCONTAINER_TAG=dev-${VARIANT}-bookworm ARG DEVCONTAINER_BASE_IMAGE=mcr.microsoft.com/vscode/devcontainers/python ARG TARGETPLATFORM="linux/amd64" -FROM --platform="${TARGETPLATFORM}" ${DEVCONTAINER_BASE_IMAGE}:${DEVCONTAINER_TAG} +FROM --platform="${TARGETPLATFORM}" ${DEVCONTAINER_BASE_IMAGE}:dev-${VARIANT}-bookworm # This will be set to true when running in VSCode ARG INTERACTIVE="false" From d7b2a0fbce5b5676eda5c0a1152d6ae67d6e1c49 Mon Sep 17 00:00:00 2001 From: Max Martin Date: Thu, 23 Jul 2026 10:29:28 +0100 Subject: [PATCH 15/16] Bump api version --- api_app/_version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api_app/_version.py b/api_app/_version.py index 605b3cd20e..5a30a412a8 100644 --- a/api_app/_version.py +++ b/api_app/_version.py @@ -1 +1 @@ -__version__ = "0.25.29" +__version__ = "0.25.30" From 5f25c64ffb962c52e9d9fd9046cd5998e7656bce Mon Sep 17 00:00:00 2001 From: maxmartin-cgi Date: Thu, 23 Jul 2026 14:06:54 +0100 Subject: [PATCH 16/16] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- devops/scripts/bundle_runtime_image_build.sh | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/devops/scripts/bundle_runtime_image_build.sh b/devops/scripts/bundle_runtime_image_build.sh index 38625a62c4..5dee9698b8 100755 --- a/devops/scripts/bundle_runtime_image_build.sh +++ b/devops/scripts/bundle_runtime_image_build.sh @@ -12,16 +12,11 @@ if [ "$(yq eval ".custom.runtime_image.import" porter.yaml)" != "null" ]; then version=$(yq eval ".custom.runtime_image.import.tag" porter.yaml) target_image="${image_name}:${version}" - existing_digest=$(az acr repository show --name "${ACR_NAME}" \ - --image "${target_image}" \ + existing_digest=$(az acr manifest show-metadata -r "${ACR_NAME}" -n "${target_image}" \ --query digest \ --output tsv 2>/dev/null || true) - if [ "${existing_digest}" = "null" ]; then - existing_digest="" - fi - - if [ -n "${existing_digest}" ]; then + if [ -n "${existing_digest}" ] && [ "${existing_digest}" != "null" ]; then echo "Image ${target_image} already exists in ACR with digest ${existing_digest}. Skipping import." exit 0 fi