Skip to content

Latest commit

 

History

History
135 lines (112 loc) · 5.99 KB

File metadata and controls

135 lines (112 loc) · 5.99 KB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview

This is a Docker-based reverse proxy setup using jwilder/nginx-proxy for automatic service discovery and routing. The proxy monitors Docker containers and automatically generates nginx configurations based on environment variables.

Architecture

Core Components:

  • docker-compose.yml: Defines the reverse-proxy service with Docker socket binding for automatic container discovery
  • nginx/conf.d/00-proxy.conf: Global nginx proxy settings including:
    • Client limits and timeouts (20s client timeout, 120s proxy timeout)
    • Rate limiting (10 requests/second per IP, burst of 20)
    • Connection limiting (max 10 concurrent connections per IP)
    • Gzip compression for text and JSON content
    • Unlimited client body size
    • Default server blocks (HTTP and HTTPS) that serve a fallback page when no VIRTUAL_HOST matches
  • nginx/vhost.d/default: Security headers and CORS configuration including:
    • Security headers (X-Frame-Options, X-Content-Type-Options, X-XSS-Protection, Referrer-Policy)
    • CORS for cross-origin requests with credentials
    • Blocks access to hidden files (.env, .git, etc.)
  • nginx/html/index.html: Custom default page with instructions shown when accessing unconfigured domains
  • nginx/certs/default.crt and nginx/certs/default.key: Self-signed fallback SSL certificate (10-year validity) used by the default HTTPS server block. This ensures the SSL handshake succeeds even when no VIRTUAL_HOST is configured, preventing Cloudflare error 525. These files are versioned in git.

Network Configuration: The setup uses an external Docker network named reverse-proxy. Services that need to be proxied must:

  1. Connect to the reverse-proxy network
  2. Set the VIRTUAL_HOST environment variable to their domain name
  3. Optionally set VIRTUAL_PORT if the service doesn't use port 80

SSL/HTTPS Configuration: By default, SSL/HTTPS is handled by Cloudflare. The reverse proxy listens on ports 80 and 443. A self-signed fallback certificate (nginx/certs/default.crt and default.key) is included in the project to ensure the default HTTPS server block can complete the SSL handshake when no VIRTUAL_HOST is configured.

For production domains, use Cloudflare Origin Certificates:

  1. Generate an Origin Certificate in Cloudflare dashboard (SSL/TLS > Origin Server)
  2. Save the certificate and key in nginx/certs/ as <domain>.crt and <domain>.key
  3. Uncomment the ./nginx/certs volume mount in docker-compose.yml
  4. The nginx-proxy will automatically use the certificate matching the VIRTUAL_HOST domain
  5. Set Cloudflare SSL mode to "Full (strict)"

Optional Let's Encrypt (commented out by default): The acme-companion service is included but commented out in docker-compose.yml. To use Let's Encrypt instead of Cloudflare:

  1. Uncomment the acme-companion service in docker-compose.yml
  2. Uncomment the ./nginx/certs volume mount in the reverse-proxy service
  3. Update DEFAULT_EMAIL with your email address
  4. Ensure ports 80 and 443 are publicly accessible (not proxied through Cloudflare)
  5. Certificates will be stored in nginx/certs/ and ACME files in nginx/acme/ (both directories are gitignored)

Key Settings:

  • TRUST_DOWNSTREAM_PROXY=true: Enables proper client IP forwarding through proxy chains
  • Server tokens hidden for security (nginx version not exposed)
  • CORS enabled for cross-origin requests with credentials support
  • Rate limiting: 10 req/s per IP with burst of 20 (prevents DDoS)
  • Connection limiting: Max 10 concurrent connections per IP
  • Timeouts configured to prevent slow clients from holding resources
  • Gzip compression enabled for better performance

Common Commands

Start the reverse proxy:

docker compose up -d

Stop the reverse proxy:

docker compose down

View logs:

docker compose logs -f reverse-proxy

Restart to apply configuration changes:

docker compose restart reverse-proxy

Create the external network (if not exists):

docker network create reverse-proxy

Configuration Changes

Directory Structure: All nginx-related files are organized under the nginx/ directory:

  • conf.d/ - Nginx configuration files
  • vhost.d/ - Virtual host specific configurations
  • html/ - Default web page files
  • certs/ - SSL certificates (default.crt and default.key are versioned; domain-specific certs are gitignored)
  • acme/ - ACME challenge files (created when using Let's Encrypt, gitignored)

Modifying nginx settings:

  • Global proxy settings: Edit nginx/conf.d/00-proxy.conf
    • Adjust client_max_body_size if you need larger uploads
    • Modify rate limiting (limit_req_zone) based on your traffic patterns
    • Change timeouts if your applications need more time to respond
  • CORS and vhost-specific settings: Edit nginx/vhost.d/default
    • Uncomment HSTS header if using Let's Encrypt (not needed with Cloudflare)
    • Modify CORS origins if you want to whitelist specific domains
    • Adjust security headers based on your requirements
  • Default page: Edit nginx/html/index.html to customize the fallback page
  • After changes, restart the container to apply

Adding new proxied services: Services should be added in separate docker-compose files with:

services:
  your-service:
    environment:
      - VIRTUAL_HOST=yourdomain.com
      - VIRTUAL_PORT=8080  # if not using port 80
    networks:
      - reverse-proxy

networks:
  reverse-proxy:
    external: true

If using Let's Encrypt (acme-companion enabled): Add these additional environment variables to your services:

environment:
  - LETSENCRYPT_HOST=yourdomain.com
  - LETSENCRYPT_EMAIL=your-email@example.com  # optional, overrides DEFAULT_EMAIL

Important notes:

  • When using Cloudflare, configure SSL mode to "Full" or "Full (strict)" in Cloudflare dashboard
  • If using Let's Encrypt directly, ports 80 and 443 must be publicly accessible without Cloudflare proxy