Deployments
GOV.UK applications can be deployed to one of three environments: Integration, Staging, and Production.
Overview
Deployments are performed through a CI/CD pipeline powered by GitHub Actions, Argo CD, and Argo Workflows. Most apps use continuous deployment (CD), but manual deployment is also supported.
We use Helm charts to define and manage Kubernetes resources for each app. These are stored in the govuk-helm-charts
repo. The source of truth is the image tag configuration for each app in the app-config
Helm chart.
The Release app shows the currently deployed versions of each app in each environment, including deployment status, deployment notes, and whether a deployment freeze is in effect.
Types of deployment
Continuous deployment
- A PR is merged into the main branch and passes CI.
- GitHub Actions builds a new image and pushes it to GitHub Container Registry.
- The
release.yml
shared workflow runs automatically in GitHub Actions and adds a Git tag for the release. Release tags are of the formv
followed by a sequential number. - The deploy-image Argo Workflow is triggered.
- The image tag in
govuk-helm-charts
is updated and merged intomain
. - Argo CD detects the change, syncs the app, and deploys it to Integration.
- Post-deployment smoke tests run in Integration.
- If tests pass and promotion is enabled, the app is automatically promoted to Staging and then Production, each followed by smoke tests.
See the overview of the deployment process for a detailed walkthrough.
Manual deployment
You can manually deploy an app to any environment by triggering the “Deploy” workflow in GitHub Actions. Manual deployments are never automatically promoted to other environments, even on “continuously deployed” applications.
GitHub Web Interface
- Go to the app’s repo → “Actions”
- Select the “Deploy” workflow
- Click “Run workflow”
- Enter
gitRef
andenvironment
.gitRef
can refer to a branch name, release tag, or commit sha. - Click “Run workflow”
GitHub CLI
gh workflow run -R "alphagov/${REPO}" deploy.yml -F environment=${ENVIRONMENT} -F gitRef=${GIT_REF}
After triggering a manual deployment:
- Open the Argo CD dashboard for your app/environment.
- Click “Details” to verify the
ANNOTATIONS
include your commit SHA. - Nudge Argo to sync the changes more quickly
- Confirm the Deployment pod is up-to-date (green tick).
Deployment rules
- Deploy between 9:30am–5pm (4pm on Fridays).
- If your code includes undeployed changes by other developers, ask them first before deploying their changes.
- Check for deploy notes in Release or an active code freeze.
- Announce risky deploys in
#govuk-technical-on-call
.
Deployment freezes
Code freezes block automatic deployment and are applied via changes to govuk-helm-charts
, by setting automatic_deploys_enabled: false
on the corresponding app.
Manual deploys are still possible during a freeze, however. To deter accidental manual deployments, you should:
- Check “Freeze deployments?” in Release to add a visual label.
- Notify on Slack
#govuk-developers
with@channel
, and email govuk-tech-members@digital.cabinet-office.gov.uk. - Avoid merging PRs during a freeze unless urgent.
Troubleshooting
What if my deployment doesn’t reach Production?
- Check updates in
#govuk-deploy-alerts
. - In Argo Workflows, click “View workflow”. (If you hit a login error, log out/in and retry.)
- In the Argo Workflow UI, click the failed step → “LOGS.”
- If it’s a flaky test, hit RESUBMIT to retry the workflow.
Check the Argo CD logs
Integration
- Go to Argo CD Integration
- GitHub account must be in the GOV.UK team
Staging / Production
Nudge Argo to Sync Faster
Argo periodically polls for changes to image tags. To force a sync:
- Visit app-config in Argo
- Click Refresh — this syncs all apps with updated tags.
- Then navigate to the relevant app in Argo and click “Sync”.
- Wait for all of the Kubernetes resources to have finished promoting.
Overview of the Deployment Process
This is what happens when a new app version is deployed:
A new commit is pushed to
main
GitHub Actions CI is triggered automatically on successful merge.GitHub Actions builds and pushes a new Docker image
- The container is tagged with the Git commit SHA
- It’s published to the GitHub Container Registry (GHCR)
- The container is tagged with the Git commit SHA
The deploy workflow is triggered
This may happen automatically (continuous deployment) or manually (e.g., via GitHub CLI).A webhook triggers Argo Workflows
This runs thedeploy-image
workflow.The
deploy-image
workflow does the following:- Updates the app’s image tag YAML file in
app-config/image-tags
- Creates a branch and automatically merges it into
main
(no PR raised) - Notifies the Release app of the new deployment
- Updates the app’s image tag YAML file in
Argo CD detects the change and begins a sync:
- Uses the App of Apps pattern via the
app-config
chart - Re-renders Helm charts for the app and applies the new image tag
- Triggers a rolling update in Kubernetes (zero-downtime if possible)
- Uses the App of Apps pattern via the
During sync, Argo CD runs hooks:
- PreSync hook (if configured): builds frontend assets and uploads to S3 via a Kubernetes Job
- Sync hook: runs database migrations (if defined) using a Job template
> ⚠️ Migrations are not guaranteed to complete before new containers start — ensure they are backward-compatible
After sync, the post-sync workflow runs:
- Executes end-to-end smoke tests
- If tests pass and
promote_deployment: true
is set:- Triggers the
deploy-image
workflow for the next environment - This continues environment-by-environment (Integration → Staging → Production)
- Triggers the