Varnish HTTP Cache Stack
High-performance HTTP cache with Varnish and monitoring.
Overview
Varnish is a high-performance HTTP accelerator and reverse proxy cache originally developed at the Norwegian newspaper Verdens Gang to handle their massive web traffic. Unlike traditional caches that store data on disk, Varnish stores cached content directly in RAM, delivering microsecond response times and handling thousands of requests per second. Its VCL (Varnish Configuration Language) provides granular control over caching policies, allowing developers to define complex rules for what gets cached, for how long, and under what conditions.
This stack combines Varnish's caching prowess with NGINX as the backend web server, creating a two-tier architecture where Varnish handles cache hits at lightning speed while NGINX serves the origin content. Prometheus collects detailed metrics from both Varnish and the custom varnish-exporter, tracking cache hit ratios, backend response times, and memory usage patterns. Grafana transforms this telemetry into visual dashboards that reveal cache performance bottlenecks and optimization opportunities.
Content delivery networks, high-traffic publishing platforms, and e-commerce sites benefit most from this configuration. The stack excels when serving content with predictable caching patterns - news articles, product catalogs, API responses, and static assets. With Varnish's ability to serve cached content even when backends fail, combined with comprehensive monitoring, this setup provides both performance gains and operational visibility that traditional web servers alone cannot match.
Key Features
- VCL-based cache policies with custom purging rules and conditional caching logic
- RAM-based storage delivering sub-millisecond response times for cached content
- Grace mode serves stale content when NGINX backend becomes unavailable
- Prometheus varnish-exporter provides cache hit ratios and backend health metrics
- NGINX backend handles dynamic content generation and SSL termination
- Grafana dashboards visualize cache efficiency and identify optimization opportunities
- ESI (Edge Side Includes) support for dynamic content assembly at the cache layer
- Built-in load balancing across multiple NGINX backends with health checks
Common Use Cases
- 1High-traffic news websites caching article pages and reducing database load
- 2E-commerce platforms accelerating product catalog and search result delivery
- 3API gateways caching frequently requested endpoints and reducing backend calls
- 4WordPress and CMS hosting providers improving site performance for multiple clients
- 5CDN edge nodes serving regional content with detailed performance monitoring
- 6Development environments testing cache invalidation strategies before production
- 7Content aggregation platforms serving millions of article views with minimal infrastructure
Prerequisites
- Minimum 1GB RAM (Varnish cache: 256MB + Prometheus: 256MB + Grafana: 512MB)
- Ports 80, 3000, 9090, and 9131 available on the host system
- Understanding of HTTP caching headers (Cache-Control, ETag, Vary)
- Basic VCL syntax knowledge for customizing Varnish cache behavior
- Familiarity with Prometheus query language (PromQL) for custom metrics
- Docker Compose 3.8+ with volume and network support
For development & testing. Review security settings, change default credentials, and test thoroughly before production use. See Terms
docker-compose.yml
docker-compose.yml
1services: 2 nginx: 3 image: nginx:alpine4 volumes: 5 - ./html:/usr/share/nginx/html:ro6 - ./nginx.conf:/etc/nginx/nginx.conf:ro7 networks: 8 - varnish_net910 varnish: 11 image: varnish:stable12 ports: 13 - "80:80"14 environment: 15 - VARNISH_SIZE=256M16 volumes: 17 - ./default.vcl:/etc/varnish/default.vcl:ro18 command: -a :80 -f /etc/varnish/default.vcl -s malloc,256M19 depends_on: 20 - nginx21 networks: 22 - varnish_net2324 varnish-exporter: 25 image: jonnenauha/prometheus_varnish_exporter:latest26 ports: 27 - "9131:9131"28 command: 29 - -varnish.health-url=http://varnish/health30 depends_on: 31 - varnish32 networks: 33 - varnish_net3435 prometheus: 36 image: prom/prometheus:latest37 ports: 38 - "9090:9090"39 volumes: 40 - ./prometheus.yml:/etc/prometheus/prometheus.yml41 - prometheus_data:/prometheus42 networks: 43 - varnish_net4445 grafana: 46 image: grafana/grafana:latest47 ports: 48 - "3000:3000"49 environment: 50 - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD}51 volumes: 52 - grafana_data:/var/lib/grafana53 networks: 54 - varnish_net5556volumes: 57 prometheus_data: 58 grafana_data: 5960networks: 61 varnish_net: .env Template
.env
1# Varnish Cache2GRAFANA_PASSWORD=secure_grafana_password34# Varnish at http://localhost5# Grafana at http://localhost:3000Usage Notes
- 1Varnish at http://localhost
- 2Configure VCL for cache rules
- 3Monitor with Grafana
- 4Varnish stats via varnishstat
- 5Great for static content caching
Individual Services(5 services)
Copy individual services to mix and match with your existing compose files.
nginx
nginx:
image: nginx:alpine
volumes:
- ./html:/usr/share/nginx/html:ro
- ./nginx.conf:/etc/nginx/nginx.conf:ro
networks:
- varnish_net
varnish
varnish:
image: varnish:stable
ports:
- "80:80"
environment:
- VARNISH_SIZE=256M
volumes:
- ./default.vcl:/etc/varnish/default.vcl:ro
command: "-a :80 -f /etc/varnish/default.vcl -s malloc,256M"
depends_on:
- nginx
networks:
- varnish_net
varnish-exporter
varnish-exporter:
image: jonnenauha/prometheus_varnish_exporter:latest
ports:
- "9131:9131"
command:
- "-varnish.health-url=http://varnish/health"
depends_on:
- varnish
networks:
- varnish_net
prometheus
prometheus:
image: prom/prometheus:latest
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus_data:/prometheus
networks:
- varnish_net
grafana
grafana:
image: grafana/grafana:latest
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD}
volumes:
- grafana_data:/var/lib/grafana
networks:
- varnish_net
Quick Start
terminal
1# 1. Create the compose file2cat > docker-compose.yml << 'EOF'3services:4 nginx:5 image: nginx:alpine6 volumes:7 - ./html:/usr/share/nginx/html:ro8 - ./nginx.conf:/etc/nginx/nginx.conf:ro9 networks:10 - varnish_net1112 varnish:13 image: varnish:stable14 ports:15 - "80:80"16 environment:17 - VARNISH_SIZE=256M18 volumes:19 - ./default.vcl:/etc/varnish/default.vcl:ro20 command: -a :80 -f /etc/varnish/default.vcl -s malloc,256M21 depends_on:22 - nginx23 networks:24 - varnish_net2526 varnish-exporter:27 image: jonnenauha/prometheus_varnish_exporter:latest28 ports:29 - "9131:9131"30 command:31 - -varnish.health-url=http://varnish/health32 depends_on:33 - varnish34 networks:35 - varnish_net3637 prometheus:38 image: prom/prometheus:latest39 ports:40 - "9090:9090"41 volumes:42 - ./prometheus.yml:/etc/prometheus/prometheus.yml43 - prometheus_data:/prometheus44 networks:45 - varnish_net4647 grafana:48 image: grafana/grafana:latest49 ports:50 - "3000:3000"51 environment:52 - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD}53 volumes:54 - grafana_data:/var/lib/grafana55 networks:56 - varnish_net5758volumes:59 prometheus_data:60 grafana_data:6162networks:63 varnish_net:64EOF6566# 2. Create the .env file67cat > .env << 'EOF'68# Varnish Cache69GRAFANA_PASSWORD=secure_grafana_password7071# Varnish at http://localhost72# Grafana at http://localhost:300073EOF7475# 3. Start the services76docker compose up -d7778# 4. View logs79docker compose logs -fOne-Liner
Run this command to download and set up the recipe in one step:
terminal
1curl -fsSL https://docker.recipes/api/recipes/varnish-cache-complete/run | bashTroubleshooting
- Varnish returns 503 Backend fetch failed: Check NGINX container health and verify network connectivity between varnish and nginx services
- Cache hit ratio remains low despite configuration: Review VCL rules in default.vcl and ensure backend responses include proper Cache-Control headers
- Grafana dashboard shows no Varnish metrics: Verify varnish-exporter container is running and accessible at port 9131, check prometheus.yml scrape configuration
- Memory usage grows continuously in Varnish: Reduce VARNISH_SIZE environment variable or implement cache object TTL limits in VCL configuration
- Prometheus target appears down for varnish-exporter: Update varnish-exporter health URL to match actual Varnish service name and port in Docker network
- NGINX backend connection refused: Ensure nginx service starts before Varnish and verify nginx.conf backend server configuration matches service names
Community Notes
Loading...
Loading notes...
Download Recipe Kit
Get all files in a ready-to-deploy package
Includes docker-compose.yml, .env template, README, and license
Components
varnishnginxprometheusgrafana
Tags
#varnish#cache#http#cdn#performance
Category
Web Servers & Reverse ProxiesAd Space
Shortcuts: C CopyF FavoriteD Download