wunderio
drupal-project
PHP

Wunder's template for Drupal projects designed to work automatically with DDEV, Cursor, CircleCI and Helm.

Last updated Jun 11, 2026
36
Stars
6
Forks
22
Issues
0
Stars/day
Attention Score
45
Language breakdown
Shell 46.7%
PHP 34.9%
TypeScript 12.3%
VCL 5.5%
Dockerfile 0.7%
Files click to expand
README

Wunder template for Drupal projects

This project is a tailored fork of the popular drupal-composer template. It is designed for deploying to Kubernetes clusters via CircleCI.

Getting started

  • Create a new project repository
Click "Use this template" to generate a new project: - Select the correct owner. - Name the project as client-COUNTRYCODE-CLIENT-PROJECT. - Set the repository to private (unless the project is public).
  • Clone and customize the repository
Clone the new project locally and update its details: - Update README.md with the project details - Update composer.json with the project name - In real client projects, remove /composer.lock from .gitignore so the lockfile is committed and reproducible - Modify the silta/silta* files values - Adjust grumphp.yml tasks, including updating the project name in the gitcommitmessage regex - Configure local development environment: - For DDEV: Update project settings in .ddev/config.yaml - For database synchronization, see ddev-wunderio-drupal - Adjust web/sites/default/settings.php settings (stagefileproxy etc) - Adjust config_split settings for silta (default), production, main, local environments
  • Set up CircleCI
- Log in to CircleCI using your GitHub account. - Add the new project to CircleCI using the existing configuration.
  • Configure encryption keys and secrets
- Define encryption keys for siltadev and siltafinland contexts in the CircleCI project settings and backup the keys in LastPass. Use the following naming convention: SEC{PROJECTNAME}{CONTEXT} where CONTEXT is the environment, such as siltadev or silta_finland. - Update the .circleci/config.yml file with the corresponding secretkeyenv values. - Define the secret environment variables in the silta/silta*.secrets YAML files for the siltadev and siltafinland contexts. - Encrypt the silta/silta*.secrets files using the encryption keys and commit the encrypted files to the repository. - See the relevant Silta's documentation for details.
  • Enable JIRA integration
- Configure automatic autolinks for the project's JIRA environment to link ticket IDs to JIRA issues seamlessly.

For additional instructions, please refer to the Silta documentation.

Production environment

  • URL:
  • Drush alias: drush @production st
  • SSH: ssh www-admin@production-shell.drupal-project -J www-admin@ssh.finland.wdr.io

Environment variables for silta_finland context

The following secret variables are defined in the silta/silta-prod.secrets file for the silta_finland context:

  • TESTKEYPROD - Secret key for testing purposes.

Main environment

  • URL:
  • Drush alias: drush @main st
  • SSH: ssh www-admin@main-shell.drupal-project -J www-admin@ssh.dev.wdr.io
The Drush alias for the current Silta feature branch deployment is drush @current st.

Environment variables for silta_dev context

The following secret variables are defined in the silta/silta.secrets file for the silta_dev context:

  • TEST_KEY - Secret key for testing purposes.

Local development

This project uses DDEV for local development.

DDEV environment

DDEV provides a containerized development environment with all necessary services preconfigured.

DDEV setup instructions

  • Install DDEV
  • Ensure Docker is running on your system
  • Start the environment and set up your project:
# Start the DDEV environment
  ddev start

# Authenticate SSH for database syncing ddev auth ssh

# Synchronize local database with a remote environment # Synchronization is provided by ddev-wunderio-drupal # drush deploy and drush uli are part of ddev syncdb command. ddev syncdb

Note: All commands in the DDEV section should be run within the DDEV environment using ddev prefix (e.g., ddev drush uli), or by using ddev ssh to access the container shell first.

DDEV services and access points

The project can be accessed at

For a complete list of all available services, URLs, and ports, use:

ddev describe

DDEV common commands

  • ddev - Display available commands
  • ddev adminer - Launch Adminer database management interface
  • ddev copilot [args] - Run GitHub Copilot CLI inside the agents container
  • ddev grumphp <commands> - Run code quality checks (command provided by ddev-wunderio-drupal)
  • ddev mailpit - Open Mailpit email testing interface
  • ddev npm <commands> - Execute npm commands
  • ddev phpunit <commands> - Run test suites (command provided by ddev-wunderio-drupal)
  • ddev varnishadm <commands> - Manage Varnish cache
  • ddev xdebug <mode> - Configure Xdebug debugging modes
  • ddev syncdb [environment] - Sync database from remote environment (requires VPN and ddev auth ssh (command provided by ddev-wunderio-drupal)
DDEV Elasticsearch configuration

DDEV Elasticsearch configuration

This project includes Elasticsearch service for robust full-text search capabilities. It's automatically set up during DDEV initialization.

Plugins configuration
  • Pre-configured with analysis-icu for Unicode/multilingual text processing
  • Additional plugins can be defined in .ddev/docker-compose.elasticsearch8.yaml
services:
  elasticsearch:
    environment:
      - ELASTICSEARCH_PLUGINS=analysis-icu  # Space-separated plugin list
Useful commands
# Check Elasticsearch status
ddev exec -s elasticsearch "curl -s localhost:9200"

List installed plugins

ddev exec -s elasticsearch "bin/elasticsearch-plugin list"
Web interface

Elasticvue is included for visualization and management at

DDEV WunderIO Drupal

DDEV WunderIO Drupal addon

The Drupal template includes the Wunder-specific ddev-wunderio-drupal addon. This addon provides additional functionality and tools specifically designed for Drupal development, including custom commands, configurations, and automation scripts to enhance your workflow.

For more information about the addon, configuration options, and available custom commands, see:

Automated installation

This addon is installed automatically when you run ddev start.

The automation is configured in .ddev/config.wunderio.yaml using a pre-start host hook:

hooks:
  pre-start:
    - exec-host: 'if [ ! -f "${DDEVGLOBALDIR}/wunderio/core/wdr-core.sh" ]; then ddev add-on get wunderio/ddev-wunderio-drupal; fi'

This means developers only need to clone the project and run ddev start; no manual addon installation step is required.

Common commands provided by the addon include:

  • ddev grumphp
  • ddev phpunit
  • ddev syncdb

Development tips

Code quality tools

Code quality tools

This project includes several tools to maintain code quality and consistency across the codebase.

Markdown Linting

Markdown files can be checked and automatically fixed using the following npm scripts:

# Check markdown files for linting issues
ddev npm run lint:md

Automatically fix markdown linting issues where possible

ddev npm run lint:md:fix

Markdown linting rules are configured in .markdownlint.json at the project root.

JavaScript and CSS Linting

The project also includes linting for JavaScript and CSS files:

# Check JavaScript files
ddev npm run lint:js

Check CSS/SCSS files

ddev npm run lint:css

Run all linting (JS, CSS, and Markdown)

ddev npm run lint

AI Workflow (ddev-agents + Copilot)

AI Workflow (ddev-agents + Copilot)

This project includes the ddev-agents addon for AI-assisted development in the local DDEV environment. It provides MCP tools and a dedicated agents container for running project-aware commands safely.

Quick start

  • Start the project:
ddev start
  • Open the project in the devcontainer.
  • Open VS Code Copilot chat and start the local MCP server (wdrmcp) from MCP server controls.
  • Use project tools through Copilot chat, or run Copilot CLI directly:
ddev copilot

Project AI configuration

  • Tool definitions: .agents/tools-config/
  • Addon metadata: .ddev/addon-metadata/ddev-agents/manifest.yaml
  • Agents runtime config: .ddev/config.agents.yaml
  • Copilot managed restrictions: .ddev/copilot-managed-config.json

Security model

  • Commands run via SSH with ephemeral keys generated at each ddev start.
  • No Docker socket access is required in the agents workflow.
  • Keys are distributed into containers during startup and are not persisted on host by default.
For deeper usage, custom tools, and environment variables, see .agents/README.md.

Drupal core updates

Drupal core updates

Varnish and Purge configuration

Varnish and Purge configuration

This section describes how to set up Varnish caching and Purge functionality in your local development environment.

Note: Drush commands in this section should be run with the appropriate environment prefix (ddev).

Configuration Overview

The project includes ready-to-use Varnish configuration:

  • Configuration Import (Recommended)
- For existing projects, simply import the configuration from config/sync:
drush cim -y

- This applies all Purge and Varnish settings, including processors and purgers

  • Manual Configuration (for new sites)
- If config/sync is not available, follow these steps:

a. Install required modules:

drush en purge purgedrush purgeprocessorlateruntime purgequeuercoretags purgetokens purgeui varnishpurger varnishpurgetags -y

b. Configure Varnish Purger: - Set a value for Browser and proxy cache maximum age in admin/config/development/performance - Navigate to /admin/config/development/performance/purge - Click Add purger and select Varnish Purger: - Name: "Varnish Purger" - Type: "Tags" - Request method: "BAN" (important: use BAN instead of PURGE for compatibility with Silta) - Headers: Cache-Tags: [invalidation:expression] - Save the configuration

c. Configure processors: - Go to /admin/config/development/performance/purge/processors - Ensure these processors are enabled: - drushpurgeinvalidate (for manual invalidation via Drush) - lateruntime (for batching invalidations) - purgeuiblock_processor (for admin UI functionality)

d. Export the configuration:

drush cex -y

e. Update settings.php: - Find the purger ID in varnishpurger.settings.<PURGERID>.yml - Update web/sites/default/settings.php with the correct purger ID:

if (getenv('VARNISHADMINHOST')) {
          $config['varnishpurger.settings.<PURGERID>']['hostname'] = trim(getenv('VARNISHADMINHOST'));
          $config['varnishpurger.settings.<PURGERID>']['port'] = getenv('VARNISHADMINPORT') ? trim(getenv('VARNISHADMINPORT')) : '80';
        }

Environment-Specific Setup

DDEV (Recommended)
  • Varnish Configuration: DDEV comes pre-configured with Varnish in .ddev folder.
  • Testing Configuration:
ddev drush cr
   ddev exec curl -X BAN -H "Cache-Tags: config:system.performance" http://varnish

If working correctly, you should receive a "200 Ban added" response

  • Viewing Varnish logs:
ddev exec -s varnish varnishlog -i BAN -i Cache

Important Notes

  • BAN vs PURGE Method: Always use the "BAN" method in the Varnish purger configuration instead of "PURGE". The Silta Varnish configuration is set up to handle BAN requests but may reject PURGE requests with "405 Method Not Allowed" errors.
  • Processors: The default Purge setup uses the purgeprocessorlateruntime module, which empties the purge queue during page requests. This works well for most sites needing immediate cache clearing. Ensure all required processors are enabled.
  • Cache Tags: The Varnish configuration is set up to handle cache tag invalidation with the Cache-Tags header.

Testing

Testing

PHPUnit (unit & integration tests)

The PHPUnit test framework is predefined in this project. See phpunit.xml for details. A minified web/modules/custom/phpunitexample module from the examples module is included for learning purposes.

Note: Run these commands with the appropriate environment prefix (ddev phpunit).

  • Run one test class: phpunit path/to/your/class/file.php
  • List groups: phpunit --list-groups
  • Run all tests in a particular group: phpunit --group Groupname

Playwright (end-to-end tests)

Playwright is used for end-to-end browser testing. Tests are located in the tests/ directory and configured via playwright.config.ts.

Setup

Install Node dependencies if you haven't already:

ddev npm install

Playwright browsers are automatically installed inside the DDEV container on ddev start.

Running tests

The TESTBASEURL environment variable is preconfigured in DDEV (see .ddev/config.yaml).

To run all tests:

ddev npx playwright test

To view the HTML report after a run:

npx playwright show-report
Test structure
  • tests/helpers/drupal-test.ts — Custom Playwright test base providing a drupal helper (via @drupal/playwright) for actions like drupal.loginAsAdmin()
  • tests/example.spec.ts — Example end-to-end test demonstrating basic page creation

Secrets handling

Silta CLI is a command-line tool to manage secrets and configurations for Silta projects. Use the following commands:

  • Encrypt a file: silta secrets encrypt --file silta/silta.secrets --secret-key=<secretkeyenv>
  • Decrypt a file: silta secrets decrypt --file silta/silta.secrets --secret-key=<secretkeyenv>
  • Display help: silta secrets --help
See the corresponding secretkeyenv values in the .circleci/config.yml file for the siltadev and siltafinland contexts. Refer to the Getting Started section for details.

Contributing

This project is maintained by Wunder. Contributions from the community are welcome.

Commit message validation and ticketing system integration

Commit message validation and ticketing system integration

Commit message validation is enforced by GrumPHP (gitcommitmessage) and requires a ticket ID in the subject. Use one of these formats:

TICKET-123: Capitalized subject
type(TICKET-123): Capitalized subject

Examples:

WNDR-446: Update composer dependencies
fix(WNDR-446): Add Drush 13 PRE_INITIALIZE hook
feat(GH-57): Add release automation command

Rules:

  • Ticket format: PROJECTKEY-123 (for example WNDR-446, GH-57).
  • Subject must start with a capital letter after :.
  • Allowed types in type(...): feat, fix, chore, docs, style, refactor, perf, test, ci, build, revert.
  • Merge commits are excluded from this validation.
Type names follow the Conventional Commits specification.

Recommended (not required by the matcher):

  • Keep body lines as bullet points explaining what and why.
  • Add a Refs: footer with key files.
Ticket IDs can be autolinked in GitHub using custom autolinks.

Git workflow

Refer to the WunderFlow repository for Git workflow details.

Deployments

Deployments are managed with CircleCI. Configurations are in .circleci/config.yml.

  • Feature branches require manual approval for deployment by default.
  • Other branches deploy automatically but can be configured for manual approval.
Manual approvals are managed through the approve-deployment job in the CircleCI UI by clicking the "approve-deployment" job label when marked as "Needs Approval."
🔗 More in this category

© 2026 GitRepoTrend · wunderio/drupal-project · Updated daily from GitHub