Repository navigation
ci: Derive EC2 artifacts from ECS build - #16821
Conversation
🚀 Image pushed to AWS ECRImage digest: 🐛 Run the image locallyThe 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 |
287d303 to
ef4a307
Compare
6b08435 to
d46a3a7
Compare
d46a3a7 to
93e968d
Compare
0343ab2 to
5ed2cf5
Compare
| - 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 |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
| @@ -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) | |||
There was a problem hiding this comment.
dotcom-rendering/.github/workflows/container-production.yml
Lines 36 to 38 in a598f34
There was a problem hiding this comment.
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
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.
5ed2cf5 to
76690ed
Compare
| - name: CDK synth | ||
| env: | ||
| IMAGE_DIGEST: ${{ inputs.production-image-digest }} | ||
| working-directory: dotcom-rendering | ||
| run: make cdk-synth |
There was a problem hiding this comment.
Performing CDK synth as a discrete step makes it more explicit where the IMAGE_DIGEST environment variable is used.
There was a problem hiding this comment.
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.
| @pnpm cdk diff --path-metadata false --version-reporting false --profile frontend | ||
|
|
||
| riffraff-bundle: clean-dist build cdk-synth | ||
| riffraff-bundle: |
There was a problem hiding this comment.
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 }} |
There was a problem hiding this comment.
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.
| - name: CDK synth | ||
| env: | ||
| IMAGE_DIGEST: ${{ inputs.production-image-digest }} | ||
| working-directory: dotcom-rendering | ||
| run: make cdk-synth |
There was a problem hiding this comment.
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.
| working-directory: dotcom-rendering | ||
| run: | | ||
| CONTAINER_ID=$(docker create ${{ steps.ecr-pull.outputs.IMAGE }}) | ||
| docker cp $CONTAINER_ID:/app/. dist |
There was a problem hiding this comment.
Copy files into dist as that is build-riffraff-bundle.mjs expects them to be1.
Footnotes
-
build-riffraff-bundle.mjsis called viamake riffraff-bundle. ↩
|
Hello 👋! When you're ready to run Chromatic, please apply the You will need to reapply the label each time you want to run Chromatic. |
AshCorr
left a comment
There was a problem hiding this comment.
Nice work!
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. |
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.
|
To improve readability.
This file was used to build the image published to GitHub Packages. It isn't needed anymore, so can be deleted.
76690ed to
9c4aa43
Compare
|
Seen on PROD (merged by @akash1810 7 minutes and 57 seconds ago) Please check your changes! |
* 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>







Note
It might be easiest to review commit by commit.
What does this change?
This change updates the build such that we call
webpackonce to produce assets. Thiswebpackcall 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:
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
mainis deployed, we see requests to load JS fromassets-code.guim.co.uk/assets/fail (reproducing the scenario described in #16808).Failing to load assets on main (tag-page-rendering from ECS)
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)
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)
Closes #16180.
Closes #16808.
Closes #16455.
Footnotes
This reuse for EC2 isn't new. See also https://github.com/guardian/dotcom-rendering/pull/16821#discussion_r4146596114. ↩