Skip to content

ci: Derive EC2 artifacts from ECS build - #16821

Merged
akash1810 merged 4 commits into
mainfrom
aa/remove-github-container
Oct 5, 2026
Merged

akash1810 merged 4 commits into
mainfrom
aa/remove-github-container

Conversation

@akash1810

@akash1810 akash1810 commented Sep 30, 2026 •

Copy link
Copy Markdown
Member

Note

It might be easiest to review commit by commit.

What does this change?

This change updates the build such that we call webpack once to produce assets. This webpack call is performed within Production.dockerfile (the ECS build). The assets are reused for the EC2 infrastructure1. This change also means the static assets produced in the ECS build are deployed to the CDN, resolving a regression - see also #16808.

As a result of these changes, the GitHub hosted Docker image is no longer used and is therefore removed to simplify the build.

How has this change been tested?

Artifact comparison

Due to the inclusion of hashes in the filenames, the artifacts won't exactly match, so can't declare this a no-op change. However, we can compare the files uploaded to Riff-Raff for this branch to the main branch. The volume of files are the same - 696 total files.

Deploy to CODE

Note

In between these steps, I've purged content in Fastly and also deleted files in S3 via:

aws s3 rm s3://aws-frontend-static/CODE/frontend-static/assets/ --recursive --profile frontend

Before

In CODE, tag-page-rendering is being served entirely by ECS. Therefore, if we visit https://m.code.dev-theguardian.com/tone/minutebyminute when main is deployed, we see requests to load JS from assets-code.guim.co.uk/assets/ fail (reproducing the scenario described in #16808).

Failing to load assets on main (tag-page-rendering from ECS)

image

If we then deploy a change to switch tag-page-rendering CODE to be served by EC2 (#16792) and make the same request, assets are successfully loaded:

Success loading assets on main (tag-page-rendering from EC2)

image

After

If we then deploy this branch to CODE and visited https://m.code.dev-theguardian.com/tone/minutebyminute, assets successfully load from assets-code.guim.co.uk/assets/:

Success loading assets on this branch (tag-page-rendering from ECS)

image


Closes #16180.
Closes #16808.
Closes #16455.

Footnotes

  1. This reuse for EC2 isn't new. See also https://github.com/guardian/dotcom-rendering/pull/16821#discussion_r4146596114. ↩

@github-actions

github-actions Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

🚀 Image pushed to AWS ECR

Image digest: sha256:9193922ab7be429e9749be7daa32dc51c5f20527f2e63e24e8b0cf38ef1f794a

🐛 Run the image locally

The following can be used to run the image locally:

# Refer to image using the immutable digest. Find alternatives below.
IMAGE_IDENTIFIER="@sha256:9193922ab7be429e9749be7daa32dc51c5f20527f2e63e24e8b0cf38ef1f794a"

# Refer to image using branch tag
# IMAGE_IDENTIFIER=":branch-aa-remove-github-container"

# Refer to image using build tag
# IMAGE_IDENTIFIER=":build-31884"

# Set environment variables for the AWS CLI
AWS_PROFILE="<A_PROFILE_FROM_JANUS>"
AWS_DEFAULT_REGION="eu-west-1"

IMAGE_ACCOUNT_ID=$(aws ssm get-parameter --name /organisation/accounts/artifacts --query "Parameter.Value" --output text)
REGISTRY="${IMAGE_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com"
IMAGE="${REGISTRY}/guardian/dotcom-rendering${IMAGE_IDENTIFIER}"

# Login to AWS ECR https://docs.aws.amazon.com/AmazonECR/latest/userguide/registry_auth.html
aws ecr get-login-password | docker login --username AWS --password-stdin $REGISTRY

# Pull the image
docker pull $IMAGE

# Run the image. You'll likely need to set additional flags. See https://docs.docker.com/reference/cli/docker/container/run.
docker run $IMAGE

From guardian/actions-publish-image.

@akash1810
akash1810 force-pushed the aa/remove-github-container branch 5 times, most recently from 287d303 to ef4a307 Compare September 30, 2026 13:17
@github-actions

github-actions Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

@akash1810
akash1810 force-pushed the aa/remove-github-container branch 4 times, most recently from 6b08435 to d46a3a7 Compare September 30, 2026 14:58
@akash1810 akash1810 added the maintenance Departmental tracking: maintenance work, not a fix or a feature label Sep 30, 2026
@akash1810
akash1810 force-pushed the aa/remove-github-container branch from d46a3a7 to 93e968d Compare September 30, 2026 14:59
@github-actions

github-actions Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

@akash1810
akash1810 force-pushed the aa/remove-github-container branch from 0343ab2 to 5ed2cf5 Compare September 30, 2026 15:19
- name: Set up Node environment
uses: ./.github/actions/setup-node-env

# TODO abstract this into a reusable GitHub Action e.g. https://github.com/guardian/actions-publish-image

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Along with #16811 and guardian/commercial#2745 we've done this three times, so it's time to refactor! This'll be done in a separate PR.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -1,2 +1,2 @@
// this should get overwritten in CI (see .github/workflows/container.yml)
// this should get overwritten in CI (see .github/workflows/container-production.yml)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

- name: Add commit hash for PRout
working-directory: dotcom-rendering
run: echo 'export const GIT_COMMIT_HASH = "${{ needs.facts.outputs.commitSha }}";' > src/server/prout.ts

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Repository checkout lacks required permissions, and removing the GHCR image breaks a documented external consumer.

Review effort: Balanced
Findings: 1 High severity · 2 Medium severity

Open (3)
What changed in this PR

Consolidates deployment packaging around the production ECR image and removes the separate GHCR container build.

Changes:

  • Extracts deployment artifacts from the production image.
  • Simplifies RiffRaff bundle construction.
  • Removes the legacy GHCR container pipeline.
File Description
.github/​workflows/​cicd.yml Routes publishing through the production image.
.github/​workflows/​publish.yml Pulls ECR artifacts and constructs deployment bundles.
.github/​workflows/​container.yml Removes the legacy GHCR workflow.
dotcom-rendering/​Containerfile Removes the legacy CI container definition.
dotcom-rendering/​makefile Decouples bundle construction from build and synth.
dotcom-rendering/​scripts/​check-node-versions.mjs Removes the deleted Containerfile version check.
dotcom-rendering/​src/​server/​prout.ts Updates the commit-hash workflow reference.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread .github/workflows/publish.yml
Comment thread .github/workflows/cicd.yml
Comment thread dotcom-rendering/scripts/check-node-versions.mjs
Comment on lines +76 to +80
- name: CDK synth
env:
IMAGE_DIGEST: ${{ inputs.production-image-digest }}
working-directory: dotcom-rendering
run: make cdk-synth

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Performing CDK synth as a discrete step makes it more explicit where the IMAGE_DIGEST environment variable is used.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The synthed files were previously in the GitHub hosted Docker image. They do not form part of the ECR hosted image so we synth here. Consequently, this workflow also now clones includes actions/checkout.

Comment thread dotcom-rendering/makefile
@pnpm cdk diff --path-metadata false --version-reporting false --profile frontend

riffraff-bundle: clean-dist build cdk-synth
riffraff-bundle:

@akash1810 akash1810 Sep 30, 2026 •

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This make task now does one thing - shuffle files around into a structure suitable for creating EC2 tarballs.

id: create-container
run: echo "CONTAINER_ID=$(docker create ${{ inputs.container-image }})" >> "$GITHUB_OUTPUT"
- name: Move container files into GHA Workspace
run: docker cp ${{ steps.create-container.outputs.CONTAINER_ID }}:/opt/app/dotcom-rendering/dotcom-rendering/. ${{ github.workspace }}

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the main change. Previously we sourced files from within the GitHub hosted Docker image. Now we source files from the ECR hosted Docker image.

Comment on lines +76 to +80
- name: CDK synth
env:
IMAGE_DIGEST: ${{ inputs.production-image-digest }}
working-directory: dotcom-rendering
run: make cdk-synth

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The synthed files were previously in the GitHub hosted Docker image. They do not form part of the ECR hosted image so we synth here. Consequently, this workflow also now clones includes actions/checkout.

@akash1810 akash1810 changed the title wip ci: Derive EC2 artifacts from ECS build Sep 30, 2026
working-directory: dotcom-rendering
run: |
CONTAINER_ID=$(docker create ${{ steps.ecr-pull.outputs.IMAGE }})
docker cp $CONTAINER_ID:/app/. dist

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy files into dist as that is build-riffraff-bundle.mjs expects them to be1.

Footnotes

  1. build-riffraff-bundle.mjs is called via make riffraff-bundle. ↩

@akash1810 akash1810 added the run_chromatic Runs chromatic when label is applied label Sep 30, 2026
@github-actions github-actions Bot removed the run_chromatic Runs chromatic when label is applied label Sep 30, 2026
@akash1810
akash1810 marked this pull request as ready for review October 1, 2026 07:59
@akash1810
akash1810 requested a review from a team as a code owner October 1, 2026 07:59
@github-actions

github-actions Bot commented Oct 1, 2026

Copy link
Copy Markdown

Hello 👋! When you're ready to run Chromatic, please apply the run_chromatic label to this PR.

You will need to reapply the label each time you want to run Chromatic.

Click here to see the Chromatic project.

@AshCorr AshCorr left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work!

Do we have any statistics on CI build time? As I recall the previous GHCR container build was a bit slow.

@akash1810

akash1810 commented Oct 1, 2026 •

Copy link
Copy Markdown
Member Author

Do we have any statistics on CI build time? As I recall the previous GHCR container build was a bit slow.

Strangely, the difference is marginal at -2s.

Build summary on this branch

image

Build summary on branch dependabot/npm_and_yarn/webpack-8db84ccbe1

PR #16827.

image

@AshCorr

AshCorr commented Oct 1, 2026

Copy link
Copy Markdown
Member

Build summary on branch dependabot/npm_and_yarn/webpack-8db84ccbe1

Ah I think when we used the GHCR image for Playwright it was built in series with the production image, so I guess the speed gains were already realized when you merged your last PR.

@akash1810

Copy link
Copy Markdown
Member Author

Ah I think when we used the GHCR image for Playwright it was built in series with the production image, so I guess the speed gains were already realized when you merged your last PR.

Good point! Looking at the build of #15853 which hasn't been rebased to include the changes in #16811, the build time decreased by ~2.5mins.

image

@akash1810
akash1810 requested a review from a team October 1, 2026 14:17

@arelra arelra left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work 👏

This file was used to build the image published to GitHub Packages.
It isn't needed anymore, so can be deleted.
@akash1810
akash1810 force-pushed the aa/remove-github-container branch from 76690ed to 9c4aa43 Compare October 2, 2026 14:41
@akash1810 akash1810 added the run_chromatic Runs chromatic when label is applied label Oct 5, 2026
@github-actions github-actions Bot removed the run_chromatic Runs chromatic when label is applied label Oct 5, 2026
@akash1810
akash1810 added this pull request to the merge queue Oct 5, 2026
Merged via the queue into main with commit da129cf Oct 5, 2026
36 checks passed
@akash1810
akash1810 deleted the aa/remove-github-container branch October 5, 2026 08:59
@gu-prout

gu-prout Bot commented Oct 5, 2026

Copy link
Copy Markdown

Seen on PROD (merged by @akash1810 7 minutes and 57 seconds ago) Please check your changes!

@akash1810

Copy link
Copy Markdown
Member Author

Fastly metrics don't seem to be negatively impacted by this change, in that the number of 403s hasn't changed much since deployment (highlighted in the screenshot below).

image

@akash1810

Copy link
Copy Markdown
Member Author

Confirming the volume/pattern of 403 responses remains unchanged since this change:

image

akash1810 added a commit that referenced this pull request Oct 9, 2026
This change routes all traffic for tag-page-rendering in PROD to ECS.

Previous attempts at this (#16774) were reverted (#16776)
due to an issue with assets on the CDN (see also #16808).

The root cause of that issue has now been addressed (#16821)
so let's try again!
IgorOffline pushed a commit to IgorOffline/guardian-dotcom-rendering that referenced this pull request Oct 10, 2026
* feat(tag-page-rendering): Serve 100% of PROD traffic from ECS

This change routes all traffic for tag-page-rendering in PROD to ECS.

Previous attempts at this (guardian#16774) were reverted (guardian#16776)
due to an issue with assets on the CDN (see also guardian#16808).

The root cause of that issue has now been addressed (guardian#16821)
so let's try again!

* feat(tag-page-rendering): Increase minimum tasks to 12

At 3 tasks and 100% traffic, ECS latecy averaged 300ms.
This is quite high compared to EC2 which averages around 40ms.

This change over-provisions to 12 tasks in an attempt to mitigate high latency.

Co-authored-by: Connor O'Malley<connoromalleyatwork@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

maintenance Departmental tracking: maintenance work, not a fix or a feature Seen-on-PROD

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Enable ECS to be used in production Could the CI container be smaller?

4 participants