Skip to content

Varnish configuration for staging and dev ​

This runbook owns the Varnish VCL deployed to Menzzo Magento staging and developer environments. The repository contains one ready-to-install file per environment because the backend health probe must send that environment's storefront host.

Do not copy a staging or dev file to production. Production keeps its existing backend, probe, purge sources and Varnish version. The separate production bfcache procedure changes only the response cache policy and includes its own backup and rollback.

Managed files ​

EnvironmentVCLRuntime pathCompose file
staging-02download/srv/devbox/runtime/staging-02/default.vcl/srv/devbox/runtime/staging-02/docker-compose.yml
ax-dev-01download/srv/devbox/runtime/ax-dev-01/default.vcl/srv/devbox/workspaces/ax-dev-01/docker-compose.yml
ax-dev-02download/srv/devbox/runtime/ax-dev-02/default.vcl/srv/devbox/workspaces/ax-dev-02/docker-compose.yml
ax-dev-03download/srv/devbox/runtime/ax-dev-03/default.vcl/srv/devbox/workspaces/ax-dev-03/docker-compose.yml
ax-dev-04download/srv/devbox/runtime/ax-dev-04/default.vcl/srv/devbox/runtime/ax-dev-04/docker-compose.yml

All five files use nginx:80 as the Docker backend. Their probe requests GET /health_check.php with the matching menzzo-<environment>.trydev.ovh host. The deployed image reported Varnish 4.1.1, so the files declare vcl 4.0.

The VCL permits PURGE requests from localhost, nginx, php85-fpm and shell. These are Docker-network service aliases, not public addresses.

Browser cache behavior ​

For non-static responses, Varnish applies one of two policies:

  • A backend response marked public becomes no-cache, must-revalidate, max-age=0. Omitting no-store allows a browser to keep the page in its back/forward cache while still requiring normal revalidation.
  • Every other response keeps no-store, no-cache, must-revalidate, max-age=0.

This VCL change only makes public pages eligible for bfcache. Magento must still mark cacheable pages public; Varnish must also produce a HIT before storefront cache behavior is considered complete. Do not remove no-store from private responses.

Compile before activation ​

Copy the candidate into the running Varnish container and compile it with the same binary that will load it:

bash
ENV=staging-02
CONTAINER="env-${ENV}-varnish"
docker cp "/tmp/menzzo-default-${ENV}.vcl" "${CONTAINER}:/tmp/menzzo-default.vcl"
docker exec "${CONTAINER}" sh -lc \
  'varnishd -C -f /tmp/menzzo-default.vcl >/dev/null 2>&1'

A zero exit status is the activation gate. A local syntax check with another Varnish version is insufficient.

Install and persist ​

Create a timestamped backup, install the environment-specific file, and make sure the Varnish Compose service mounts it read-only:

bash
ENV=staging-02
TARGET="/srv/devbox/runtime/${ENV}/default.vcl"
STAMP="$(date -u +%Y%m%dT%H%M%SZ)"
sudo cp "${TARGET}" "${TARGET}.bak-${STAMP}"
sudo install -m 0644 "/tmp/menzzo-default-${ENV}.vcl" "${TARGET}"

The varnish service must contain this mount:

yaml
volumes:
  - /srv/devbox/runtime/<environment>/default.vcl:/etc/varnish/default.vcl:ro

Validate Compose before recreating only Varnish:

bash
docker compose -f <compose-file> config --quiet
docker compose -f <compose-file> up -d --no-deps --force-recreate varnish

ax-dev-04 requires the devbox environment file for both commands:

bash
docker compose \
  --env-file /home/debian/apps/devbox/.env \
  -f /srv/devbox/runtime/ax-dev-04/docker-compose.yml \
  config --quiet

Runtime validation ​

Confirm the backend becomes healthy and the health route succeeds through Varnish:

bash
ENV=staging-02
HOST="menzzo-${ENV}.trydev.ovh"
docker exec "env-${ENV}-varnish" varnishadm backend.list
docker exec "env-${ENV}-shell" curl -sS -o /dev/null -w '%{http_code}\n' \
  -H "Host: ${HOST}" \
  -H 'X-Forwarded-Proto: https' \
  http://varnish/health_check.php

Expected results are a Healthy backend and HTTP 200. Compare the homepage through Varnish and directly through Nginx. A matching application error on both paths is not a Varnish regression, but it remains an environment issue.

For a cacheable anonymous page, send two requests and inspect Age, X-Magento-Cache-Debug and Cache-Control. Completion requires a Varnish HIT and a public response without no-store. Check a private route such as the cart separately and confirm it still includes no-store.

Deployment record: 2026-10-19 ​

The environment-specific files above were compiled inside every target Varnish 4.1.1 container before activation. After activation:

EnvironmentBackend probeHealth through VarnishHomepage through Varnish / Nginx
staging-02Healthy200200 / 200
ax-dev-01Healthy200500 / 500
ax-dev-02Healthy200200 / 200
ax-dev-03Healthy200200 / 200
ax-dev-04Healthy200200 / 200

The ax-dev-01 homepage failure is reproduced directly against Nginx. The other storefront homepages were reachable. All tested homepages still returned MISS with no-store, which means the Magento full-page-cache settings or response classification must be corrected before bfcache and Varnish HIT acceptance can pass.

Rollback ​

Restore the newest known-good backup, validate the Compose file, then recreate only Varnish:

bash
sudo cp <default.vcl.backup> /srv/devbox/runtime/<environment>/default.vcl
sudo cp <docker-compose.yml.backup> <compose-file> # only if the mount must be reverted
docker compose -f <compose-file> config --quiet
docker compose -f <compose-file> up -d --no-deps --force-recreate varnish

Run the backend-health and HTTP checks again after rollback. Use the --env-file argument shown above for ax-dev-04.

Internal developer documentation for Menzzo systems.