# ============================================================================== # EXAMPLE: Cloudflare IP Restoration (Swarm) # ============================================================================== # # WHAT THIS DEMONSTRATES: # - Restoring original visitor IPs when behind Cloudflare CDN # - Using Docker configs to manage Cloudflare IP lists # - Service discovery in Swarm mode with plugins # - Load balancing across multiple replicas # # REQUIREMENTS (run these first): # ```bash # # Initialize Docker Swarm (if not already initialized) # docker swarm init # # # Create overlay network (idempotent) # docker network ls | grep -q easyhaproxy || docker network create --driver overlay --attachable easyhaproxy # # # Ensure EasyHAProxy is deployed # docker stack deploy -c easyhaproxy.yml easyhaproxy # # # Download Cloudflare IP ranges and create Docker config # curl https://www.cloudflare.com/ips-v4 > cloudflare_ips.lst # echo "" >> cloudflare_ips.lst # curl https://www.cloudflare.com/ips-v6 >> cloudflare_ips.lst # docker config create cloudflare_ips cloudflare_ips.lst # rm cloudflare_ips.lst # # # Add to /etc/hosts for local testing (idempotent) # grep -q "myapp.example.com" /etc/hosts || echo "127.0.0.1 myapp.example.com" | sudo tee -a /etc/hosts # ``` # # HOW TO START: # ```bash # docker stack deploy -c cloudflare.yml webapp # ``` # # HOW TO VERIFY IT'S WORKING: # ```bash # # Check stack is deployed # docker stack ls | grep webapp # # Expected: webapp stack listed # # # Check service is running # docker service ls | grep webapp_webapp # # Expected: webapp_webapp with 4/4 replicas # # # Test the application # curl -H "Host: myapp.example.com" http://localhost/ # # Expected: 200 OK with "App Behind Cloudflare" # # # Check HAProxy config includes Cloudflare IPs # docker exec $(docker ps -q -f name=easyhaproxy_haproxy) cat /etc/haproxy/haproxy.cfg | grep -A 5 "cloudflare" # # Expected: ACL rules for Cloudflare IP ranges # ``` # # CLEAN UP: # ```bash # docker stack rm webapp # # To also remove the Cloudflare IPs config: # # docker config rm cloudflare_ips # ``` # # NOTE: This plugin is most useful when your site is actually behind Cloudflare CDN. # The plugin uses the CF-Connecting-IP header to restore the original visitor IP. # # ============================================================================== version: "3.7" services: haproxy: image: byjg/easy-haproxy:5.0.0 volumes: - /var/run/docker.sock:/var/run/docker.sock configs: - source: cloudflare_ips target: /etc/haproxy/cloudflare_ips.lst deploy: replicas: 1 placement: constraints: - node.role == manager environment: EASYHAPROXY_DISCOVER: swarm HAPROXY_USERNAME: admin HAPROXY_PASSWORD: password HAPROXY_STATS_PORT: 1936 ports: - "80:80/tcp" - "443:443/tcp" - "1936:1936/tcp" networks: - easyhaproxy # Web application behind Cloudflare webapp: image: byjg/static-httpserver environment: TITLE: "App Behind Cloudflare" deploy: replicas: 4 labels: easyhaproxy.http.host: "myapp.example.com" easyhaproxy.http.port: "80" easyhaproxy.http.localport: "8080" # Enable Cloudflare plugin easyhaproxy.http.plugins: "cloudflare" # Optional: Specify custom IP list path # easyhaproxy.http.plugin.cloudflare.ip_list_path: "/etc/haproxy/cloudflare_ips.lst" networks: - easyhaproxy networks: easyhaproxy: external: true configs: cloudflare_ips: external: true