# alphagov/whitehall: the Rails application behind GOV.UK publishing

> Whitehall is the Ruby on Rails application that UK government publishers use to create and manage GOV.UK content. It ships with an edition model, an audit trail, and a Docker-first workflow built on the GOV.UK Docker environment.

**alphagov/whitehall** — Publishes government content on GOV.UK

- Repository: https://github.com/alphagov/whitehall
- Website: https://docs.publishing.service.gov.uk/apps/whitehall.html
- Stars: 1,038 · Forks: 200
- Language: Ruby
- License: MIT
- Published: 2026-10-19 · Updated: 2026-10-19 · Language: en
- Canonical page: https://hysenlabs.com/projects/alphagov-whitehall

## An admin and publisher app behind GOV.UK

Whitehall is described in one line as publishing government content on GOV.UK, and the README spells out the division of labour. It is used by publishers to create and manage content. The README also notes the aliases, Whitehall Admin and Whitehall Publisher, which is a useful clue about how the codebase has grown.

That publishing focus is the central architectural fact. Anyone considering adoption inherits not a CMS core but an application whose content model was shaped by the needs of UK government publishing. That means things like a formal audit trail, edition history and workflow states exist because a publisher needed to know who changed what, and when, on a site where the content is official policy.

For a team building a similar high-accountability site, that history is a design document you can read. For a team that just wants structured content with a simple admin, it is a great deal of machinery to understand before writing a line.

## The edition model and edition workflow as the core abstraction

Two documents sit at the centre of the repository's docs directory, and they are the ones to read first: docs/edition_model.md and docs/edition_workflow.md. The pairing tells you the shape of the system. An edition is a versioned unit of content, and the workflow document describes how an edition moves through states.

This is a very different approach from a typical blog-oriented CMS where the current row is the truth and history is a side table. Here, content that has been published and then withdrawn still exists as an edition. Every time a publisher saves a change, the model has to answer questions about supersession, publication and rollback, and the audit trail exists to answer them with a record.

The docs directory also carries guides for the parts of the system that are not obvious from a controller: docs/auditing.md for the Content Audit Trail, docs/internationalisation_guide.md, docs/timestamps.md, docs/css.md, docs/javascript.md, and docs/troubleshooting.md. There is a separate guide for data migrations at db/data_migration/README.md, which is a signal that the database is treated as something with history worth writing down.

No section here is filler. Each of these documents describes a mechanism that a publishing system needs when the content is official.

## GOV.UK Docker is the required runtime, not an option

The README is unambiguous about the workflow: use GOV.UK Docker to run any commands that follow. That instruction sits above the test instructions rather than inside a troubleshooting note, which tells you the Docker environment is the sanctioned path for development, testing and administration.

The GOV.UK Docker environment is described as providing the application and its tests with all the necessary dependencies, and the test commands explicitly assume it is running with its binaries on your PATH.

```bash
# run all the test suites
govuk-docker-run bundle exec rake
```

```bash
# run all the JavaScript tests
govuk-docker-run bundle exec rake jasmine
```

The second command runs the Jasmine suites separately from the main rake run, which reflects a codebase where the front end carries its own test surface.

This is a real adoption cost, and it deserves a plain statement. Whitehall is not a gem you add to an existing Rails app, and it is not an application you can boot with a bare bundle install. The dependency environment is delivered as containers, so your local setup, your CI and your production image are all expected to speak the same Docker tooling.

## A two stage Docker image on the GOV.UK Ruby base

The repository's own Dockerfile shows how the application is built, and the two stage pattern is worth reading carefully. The builder stage starts from a builder image for the target Ruby version, sets the working directory, copies the Gemfile, Gemfile.lock and .ruby-version, and runs bundle install. It then copies package.json and yarn.lock and runs yarn install with a production, frozen lockfile, non-interactive link of duplicates.

The second stage starts from the runtime base image, installs the system packages imagemagick, unzip and zip, copies the bundle path, the bootsnap cache and the application itself, switches to the app user, and runs puma as the command.

```dockerfile
ARG ruby_version=3.3
ARG base_image=ghcr.io/alphagov/govuk-ruby-base:$ruby_version
ARG builder_image=ghcr.io/alphagov/govuk-ruby-builder:$ruby_version
```

Two details stand out. The build sets JWT_AUTH_SECRET to a placeholder value, unused_yet_required, so the image builds without supplying a real secret, which means the secret has to be injected at deploy time rather than baked in. And bootsnap precompile runs against the Gemfile, so the boot cache is warmed during the build instead of on first request.

The base images are pulled from ghcr.io/alphagov, so the runtime environment is a shared GOV.UK asset rather than something this repository builds from scratch.

## A front end with its own lint and test toolchain

The package.json shows a JavaScript layer with a small dependency surface. There are only two runtime dependencies: cropperjs, an image cropping library, and paste-html-to-govspeak, which converts pasted HTML into Govspeak, the markdown dialect GOV.UK uses for structured content. Everything else in the file is development tooling.

That second dependency is a useful hint about the editorial workflow. Govspeak is a restricted markdown with embedded components, and being able to paste HTML from elsewhere and have it converted means the editor is not a plain textarea, and that publishing is as much about structured content as about free text.

The lint setup is layered: eslint with the standard config, stylelint against the app stylesheets using the GOV.UK design system config, and prettier for formatting js and scss files, each with its own npm script and cache location.

```bash
yarn run lint
```

The Jasmine browser tests are driven by jasmine-browser-runner, with a separate prepare step that clobbers and precompiles assets under RAILS_ENV=test, and Playwright is present in the dev dependencies for end to end work. Rails asset precompilation inside a test prepare step is a reminder that the JavaScript and Ruby sides are coupled rather than independently deployable.

## Three releases in a day, a Dependabot merger and MIT terms

The release history gives a striking picture of the delivery rhythm. v3379, v3378 and v3377 were all tagged on 2026-10-15, within about eighty minutes of each other, and the last push was on the same day. These are sequential deploy tags, not numbered feature releases, and the numbering in the thousands is a measure of how often the application is put into production.

The repository also carries .govuk_dependabot_merger.yml, which points to a Dependabot workflow that merges dependency update branches. For an application with a large Gemfile and a yarn lockfile, automated dependency pull requests are how the security and version churn gets absorbed without a human touching each update.

The licence is MIT, with the licence text in LICENCE. For a codebase in active government use, the permissive licence is what allows other public sector teams to reuse and adapt the publishing system, and it also means an adopting team inherits an obligation to keep the licence notice intact.

The remaining top level files show the shape of a mature Rails application: app/, config/, db/, spec/ and test/ for both Ruby and feature tests, lib/, public/, script/, vendor/, and a Procfile alongside Procfile.dev for process definitions in different environments. There are also linting configurations for Ruby and templates, .rubocop.yml, .erb_lint.yml and .prettierrc.js.

## Conclusion

Whitehall suits teams that want a proven publishing system for a government or high-accountability content site and are prepared to work inside Rails conventions, a yarn based front end and a Docker-first local environment. It is a poor fit as a lightweight headless CMS, since the edition model, the audit trail and the publisher workflow are all part of the design rather than optional extras. Before adopting it, read docs/edition_model.md and docs/edition_workflow.md to understand the publishing state machine, and run govuk-docker-run bundle exec rake in the GOV.UK Docker environment to see whether the existing test suite passes against your setup.

## FAQ

### What is Whitehall used for?

Whitehall is the Ruby on Rails application publishers use to create and manage content that is published on GOV.UK. It is also known as Whitehall Admin or Whitehall Publisher.

### How do I run the Whitehall test suite?

You need the GOV.UK Docker environment running with its binaries in your PATH, then run govuk-docker-run bundle exec rake for the Ruby suites and govuk-docker-run bundle exec rake jasmine for the JavaScript tests.

### What is the edition model in Whitehall?

An edition is a versioned unit of content, and the workflow describes how an edition moves between states. The documentation for both is in docs/edition_model.md and docs/edition_workflow.md.

### Does Whitehall keep a record of who changed the content?

Yes. The Content Audit Trail is documented in docs/auditing.md, and the README lists it as the first entry under further documentation.

### What licence is Whitehall released under?

The MIT Licence. The licence text is in the LICENCE file in the repository root.

## Sources

- [alphagov/whitehall on GitHub](https://github.com/alphagov/whitehall)
- [License: MIT](https://github.com/alphagov/whitehall/blob/main/LICENSE)
- [Project website](https://docs.publishing.service.gov.uk/apps/whitehall.html)
- [README](https://github.com/alphagov/whitehall/blob/main/README.md)
- [Releases](https://github.com/alphagov/whitehall/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/alphagov-whitehall
