Skip to main content
Last updated: 4 Apr 2025

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

  1. A PR is merged into the main branch and passes CI.
  2. GitHub Actions builds a new image and pushes it to GitHub Container Registry.
  3. The release.yml shared workflow runs automatically in GitHub Actions and adds a Git tag for the release. Release tags are of the form v followed by a sequential number.
  4. The deploy-image Argo Workflow is triggered.
  5. The image tag in govuk-helm-charts is updated and merged into main.
  6. Argo CD detects the change, syncs the app, and deploys it to Integration.
  7. Post-deployment smoke tests run in Integration.
  8. 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

  1. Go to the app’s repo → “Actions”
  2. Select the “Deploy” workflow
  3. Click “Run workflow”
  4. Enter gitRef and environment. gitRef can refer to a branch name, release tag, or commit sha.
  5. 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:

  1. Open the Argo CD dashboard for your app/environment.
  2. Click “Details” to verify the ANNOTATIONS include your commit SHA.
  3. Nudge Argo to sync the changes more quickly
  4. 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:

  1. Check “Freeze deployments?” in Release to add a visual label.
  2. Notify on Slack #govuk-developers with @channel, and email govuk-tech-members@digital.cabinet-office.gov.uk.
  3. Avoid merging PRs during a freeze unless urgent.

Troubleshooting

What if my deployment doesn’t reach Production?

  1. Check updates in #govuk-deploy-alerts.
  2. In Argo Workflows, click “View workflow”. (If you hit a login error, log out/in and retry.)
  3. In the Argo Workflow UI, click the failed step → “LOGS.”
  4. If it’s a flaky test, hit RESUBMIT to retry the workflow.

Check the Argo CD logs

Integration

Staging / Production

Nudge Argo to Sync Faster

Argo periodically polls for changes to image tags. To force a sync:

  1. Visit app-config in Argo
  2. Click Refresh — this syncs all apps with updated tags.
  3. Then navigate to the relevant app in Argo and click “Sync”.
  4. 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:

  1. A new commit is pushed to main
    GitHub Actions CI is triggered automatically on successful merge.

  2. GitHub Actions builds and pushes a new Docker image

  3. The deploy workflow is triggered
    This may happen automatically (continuous deployment) or manually (e.g., via GitHub CLI).

  4. A webhook triggers Argo Workflows
    This runs the deploy-image workflow.

  5. 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
  6. 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)
  7. 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
  8. 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)