This project demonstrates a multi-tier proxy and caching setup using Docker Compose, featuring:
- Python HTTP Server (Origin)
- Varnish Cache (CDN simulation)
- Nginx (Reverse Proxy)
Client -> Nginx (80) -> Varnish Cache -> Python Origin (8080)
- Simple Python HTTP server
- Serves static content from
origin_content/
- Internal service on port 8080
- Uses Python's built-in HTTP server
- Simulates a CDN-like caching layer
- Acts as a reverse proxy and HTTP accelerator
- Caches responses for 60 seconds
- Configurable via
default.vcl
- Internal service
- Cache status indicated via X-Cache headers
- Acts as the entry point for all requests
- Provides load balancing capabilities
- Adds request/response headers
- Handles error pages
- Exposes health check endpoint
- Public-facing on port 80
- Start the environment:
docker compose up -d
- Access the services:
- Main application (through Nginx): http://localhost
- Direct to origin: http://localhost:8080
- Health check: http://localhost/health
- Test caching:
# First request (should show MISS)
curl -I http://localhost
# Second request (should show HIT)
curl -I http://localhost
# Health check
curl http://localhost/health
- Observe headers:
X-Cache
: Shows HIT or MISSX-Cache-Hits
: Number of cache hitsX-Proxy-Path
: Shows request path through services- The web interface also displays these headers in real-time
location / {
proxy_pass http://cache:80;
# Headers for proxying
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
add_header X-Proxy-Path "Nginx -> Varnish -> Origin" always;
}
# TTL for cached content
set beresp.ttl = 60s;
# Cache status headers
set resp.http.X-Cache = "HIT/MISS";
set resp.http.X-Cache-Hits = obj.hits;
# Remove and recreate cache container
docker compose stop cache
docker compose rm -f cache
docker compose up -d cache
# All services
docker compose logs
# Specific service
docker compose logs proxy
docker compose logs cache
docker compose logs origin
- Edit files in
origin_content/
- Changes are immediate (volume mounted)
- Edit
nginx.conf
ordefault.vcl
- Restart the respective service:
# For Nginx changes
docker-compose restart proxy
# For Varnish changes
docker-compose restart cache
- Test each layer:
# Test origin directly
curl -I http://localhost:8080
# Test through Nginx
curl -I http://localhost
- Check service logs:
# Check Nginx logs
docker-compose logs proxy
# Check Varnish logs
docker-compose logs cache
- Verify all services are running:
docker-compose ps
- Check for cache-busting headers in requests
- Verify TTL settings in Varnish configuration
- Check
X-Proxy-Path
header for correct routing
The included UI provides:
- Real-time cache status display
- Complete response header information
- Cache hit counter
- Manual refresh button
- Visual status indicators
- Request arrives at Nginx (port 80)
- Nginx adds headers and forwards to Varnish
- Varnish either:
- Serves cached content (HIT)
- Fetches from origin (MISS)
- Response returns through the chain
- Each layer adds its own headers