Deployment
Overview
Deployments use DeployHQ with a zero-downtime rolling strategy. Each web node is taken out of the Varnish load balancer during deployment, updated, then returned to rotation.
Deployment Flow
Pre-Deployment Checklist
- [ ] Changes tested on staging (
staging.dezeen.com) - [ ] Cypress E2E tests pass where applicable
- [ ]
npm run productionsucceeds locally in_project/_web/ - [ ] No cache artifacts committed
- [ ] Database migrations applied manually if needed
Deployment Steps
1. Push to Branch
DeployHQ watches the configured branch (typically master).
bash
git checkout master
git merge develop
git push origin master2. DeployHQ Pipeline
DeployHQ automatically:
- Runs
npm run productionin_project/_web/(asset compilation) - For each target node:
- Runs
enable-maintenance.sh(pre-deploy) - Syncs files to web node
- Runs
disable-maintenance.sh(post-deploy)
- Runs
3. Maintenance Scripts
Located in setup/production/deployhq/:
| Script | Purpose |
|---|---|
enable-maintenance.sh | Creates _project/_web/maintenance/ with 503 response |
disable-maintenance.sh | Removes maintenance directory |
enable-maintenance-varnish.sh | Varnish-specific maintenance |
disable-maintenance-varnish.sh | Varnish-specific restore |
test-maintenance.sh | Test the maintenance setup |
How Maintenance Mode Works
- Pre-deploy creates
_project/_web/maintenance/directory withindex.phpreturning HTTP 503 - Varnish health probe hits
/maintenance/every 5 seconds - On 503 response, Varnish marks the backend as sick and stops routing traffic
- After deployment, directory is removed
- Varnish probe gets 404, marks backend as healthy, traffic resumes
Post-Deployment Checklist
- [ ] Site loads correctly (homepage, article, category, search)
- [ ] Varnish is serving fresh content
- [ ] Cloudflare cache purged if static assets changed
- [ ] No errors in
wp-content/debug.log - [ ] Algolia re-index if search schema changed
- [ ] Verify key integrations (search, comments, newsletter form)
Branching Strategy
| Branch | Purpose |
|---|---|
develop | Main development branch |
master | Production-ready code; triggers deployment |
feature/* | Feature branches, merged to develop |
hotfix/* | Emergency fixes, merged to both master and develop |
Build Commands
bash
# From _project/_web/
npm run dev # Development build (with source maps)
npm run watch # Watch mode for development
npm run production # Production build (minified, no source maps)Files Excluded from Deploy
From .deployignore:
_project/_data/*
_project/_email/*
_project/_cookiebot/*
_project/_web/node_modules/**
_project/_web/wp-content/themes/2016dezeen/coverage/**CI/CD
CircleCI
The .circleci/config.yml currently only runs a SonarCloud scan (static analysis). The build and test steps are commented out. Deployments are handled entirely by DeployHQ, not CircleCI.
Cypress Tests
bash
# From project root
npm run cypress:open # Interactive mode
npm run cypress:run # Headless modeTests run against production by default. Configure cypress.config.js for other environments.
Rollback Procedure
- In DeployHQ, select the previous successful deployment
- Click "Redeploy" to re-deploy the last known good commit
- Alternatively:
git revertthe problematic commit and push tomaster
Risks and Gotchas
- No database migrations: Schema changes must be applied manually via SQL
- Asset compilation in DeployHQ: If the build fails, the deployment will fail; check DeployHQ logs
- Varnish probe timing: After removing maintenance mode, there is a 5–15 second delay before traffic resumes (probe interval × window)
- Cloudflare cache: May need manual purge via the plugin or Cloudflare dashboard if assets changed
- wp-config.php: Not in version control; changes must be applied manually per node