Skip to main content
Start of main content.

Turbo-charging Drupal with GovCMS PaaS

by adam.bramley /

Share this post on social media

Cancer Australia + GovCMS blogpost

PreviousNext and Paper Moose teamed up with Cancer Australia to rebuild their consolidated website on GovCMS PaaS. This was PreviousNext’s first live Drupal 11 website project. 

Learn how we built our most modern website to date with GovCMS.

Tech stack

Combined with our extensive experience in building and hosting Drupal sites, the GovCMS PaaS offering provided us with the flexibility to customise it closely to our standard setup, making maintenance easier for the development team.

Overview

  • Drupal 11.2
  • PHP 8.4
  • OpenSearch
  • Redis
  • Storybook
  • Vite

Local development

GovCMS runs on top of Lagoon, and Lagoon derives its services directly from the Docker Compose file. This meant that for the most part, the local development setup remained the same. We continued to use Pygmy and Docker Compose, while selecting a simplified Makefile in place of Ahoy, for consistency with our other projects.

We also added several new services to the Docker Compose file:

Logs - We needed a logging solution for local environments, which is crucial for debugging issues during development. Lagoon environments use the Lagoon Logs module to send logs over a UDP socket. This can be integrated easily into Docker Compose with the following service definition:

logs:
  hostname: application-logs.lagoon.svc
  image: mendhak/udp-listener
  labels:
    lagoon.type: none
  environment:
    - UDPPORT=5140

You can then run docker compose logs -f logs in the command line to get a live feed of logs from Drupal.

OpenSearch - OpenSearch is our search backend of choice, so we deployed an OpenSearch container very easily using the following service definition.

opensearch:
  image: uselagoon/opensearch-2
  environment:
    - "OPENSEARCH_JAVA_OPTS=-Xms1512m -Xmx1512m"
  labels:
    lagoon.type: opensearch
  ports:
    - "9200:9200"

We then used some Nginx magic to provide a read-only endpoint for our decoupled React applications to talk to. This allowed us to build feature-rich and lightning-fast search experiences that can be embedded anywhere on the site.

GitlabCI

While the local and remote environment setup largely stayed the same, the GitlabCI pipeline received an overhaul.

Our CI pipelines generally follow a 3-stage process:

  1. Build - frontend and backend libraries are installed in separate jobs. These jobs are designed to be fast and efficient, pulling in cached dependencies from previous runs if lock files haven’t changed, or generating a new cache entry to speed up future pipelines.
  2. Code Quality - This is where linting is run for both frontend and backend. These jobs are dependent on their respective Build step and pull from the same cache entry generated and stored by those steps. We also usually run unit tests during this step since they are extremely fast to run and do not require a running Drupal installation. This ensures that pipelines fail fast if any unit tests fail.
  3. Test - The final step is to run the meatier tasks, such as integration and functional tests, as well as building Storybook assets and running Playwright tests. Again, these pull the frontend and backend assets from the Build step.
     
CA GitLab CI pipeline

This pipeline setup ensures we can confidently verify that there are no regressions before merging a change into the website.

Drupal 11

The Cancer Australia website was our first live production website running on Drupal 11.

Development on the project started in early July 2024 on Drupal 10.3 and launched in February 2025 on Drupal 11.1. The govcms/scaffold-tooling library, which ordinarily provides scripts and tooling for deployments on Lagoon, is currently incompatible with Drupal 11.

However, we overcame this by removing the library from our composer dependencies and manually pulling in the necessary scripts directly from the scaffold-tooling repository for deployment. This is done as part of the Docker image build with simple curl commands.

The following issues will help to overcome these limitations in the future:

Keeping in line with all of our other projects, the Cancer Australia website receives weekly updates across all modules and Drupal core, as well as frequent production releases, and is now running on Drupal 11.2.5. 

Contemporary content architecture

The Cancer Australia website was built from the ground up using our innovative content architecture. 

Content types use Layout builder across the board, utilising block content bundles for reusable components alongside custom block plugins for embedded React apps and other more customised functionality. Drupal core’s media library covers embedded images and videos as well as dynamic graphs using the reCharts library.

Pinto powers the rendering layer, translating our entity types and bundle classes into Theme Objects, which utilise Twig templates directly from the Storybook design system.

Component output is tested via PHPUnit using the weitzman/drupal-test-traits library and its EntityCrawlerTrait. This allows testing a block’s HTML output in isolation without the overhead of creating a page and visiting it with an HTTP request, resulting in easy-to-write tests that run in a fraction of the time.

<?php

declare(strict_types=1);

namespace CA\Tests\Functional\Block;

use CA\Tests\Enum\TestSelectors;
use Drupal\ca_profile\Entity\BlockContent\Card;
use weitzman\DrupalTestTraits\EntityCrawlerTrait;
use weitzman\DrupalTestTraits\ExistingSiteBase;

final class CardTest extends ExistingSiteBase {

  use EntityCrawlerTrait;

  public function testCardRendering(): void {
    $title = $this->randomMachineName();
    $url = $this->randomUrl();
    $description = $this->randomMachineName();
    // Create an un-saved entity using our bundle class.
    $card = Card::create()
      ->setTitle($title)
      ->setLink($url, $title)
      ->setDescription($description)
      ->setImage($this->createImageMedia());
    
    // Render the entity and make assertions on the output.
    $crawler = $this->getRenderedEntityCrawler($card);
    $this->assertCount(1, $crawler->filter(TestSelectors::Card->value));
    $this->assertCount(1, $crawler->filter($this->selectWithText(TestSelectors::CardTitle->value, $title)));
    $this->assertCount(1, $crawler->filter(\sprintf('[href="%s"]', $url)));
    $this->assertCount(1, $crawler->filter($this->selectWithText(TestSelectors::CardDescription->value, $description)));
  }

}

Frontend architecture

We continue to use our standard frontend setup using Storybook and Vite. Check out Jack’s blog post for a more in-depth overview of the setup.

The Cancer Australia project was our first site built from the ground up using our Pinto setup, where Theme Objects in Drupal use Twig templates directly from our design system. This made it extremely easy to theme components in Drupal and wire them up to entity types and bundles, rapidly accelerating the site-building and theming process.

Storybook is built and tested in GitlabCI using Playwright. Storybook is also built during deployment and served directly alongside the Drupal site, allowing stakeholders to review and QA outside of the Drupal context. This facilitates rapid prototyping of new features and components before the Drupal implementation starts. 

The GovCMS feature branch environments further enhance this process, enabling it to occur before code is merged into the mainline branches.

CA Storybook

Open-source contribution

The Cancer Australia website build is a successful demonstration of how our development flow provides contributions to Drupal Core, contributed modules and GovCMS. 

As part of this work, these are some examples of what our team contributed to:

In summary

The Cancer Australia rebuild demonstrates how GovCMS PaaS can support a modern, maintainable Drupal 11 architecture. By closely aligning the hosting stack and CI/CD pipeline with our standard approach, we retained our usual development workflows while fully leveraging the GovCMS PaaS platform.

The result is a clean, reproducible setup that supports fast iteration, reliable testing, and straightforward maintenance. And it’s a solid foundation for future GovCMS projects running on Drupal 11 and beyond.

Related Articles