{"id":35145454,"url":"https://github.com/hhftechnology/pangolin-cloudflare-tunnel","last_synced_at":"2026-03-17T08:31:43.728Z","repository":{"id":331134271,"uuid":"960904896","full_name":"hhftechnology/pangolin-cloudflare-tunnel","owner":"hhftechnology","description":"A bridge between Traefik and Cloudflare Zero-Trust tunnels","archived":false,"fork":false,"pushed_at":"2025-12-30T17:43:18.000Z","size":188,"stargazers_count":65,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-01-03T13:47:38.491Z","etag":null,"topics":["cloudflare-tunnels","cloudflared","pangolin","traefik","tunnels"],"latest_commit_sha":null,"homepage":"https://forum.hhf.technology/t/setting-up-cloudflare-tunnels-with-pangolin/","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hhftechnology.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-04-05T10:18:32.000Z","updated_at":"2026-01-02T23:43:15.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/hhftechnology/pangolin-cloudflare-tunnel","commit_stats":null,"previous_names":["hhftechnology/pangolin-cloudflare-tunnel"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/hhftechnology/pangolin-cloudflare-tunnel","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hhftechnology%2Fpangolin-cloudflare-tunnel","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hhftechnology%2Fpangolin-cloudflare-tunnel/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hhftechnology%2Fpangolin-cloudflare-tunnel/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hhftechnology%2Fpangolin-cloudflare-tunnel/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hhftechnology","download_url":"https://codeload.github.com/hhftechnology/pangolin-cloudflare-tunnel/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hhftechnology%2Fpangolin-cloudflare-tunnel/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30619096,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-17T08:10:05.930Z","status":"ssl_error","status_checked_at":"2026-03-17T08:10:04.972Z","response_time":56,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cloudflare-tunnels","cloudflared","pangolin","traefik","tunnels"],"created_at":"2025-12-28T13:47:06.639Z","updated_at":"2026-03-17T08:31:43.722Z","avatar_url":"https://github.com/hhftechnology.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n    \u003ch1\u003ePangolin-Cloudflare-Tunnel\u003c/h1\u003e\n    \u003cp\u003eA bridge between Traefik and Cloudflare Zero-Trust tunnels that enables Pangolin users to leverage Cloudflare's global network.\u003c/p\u003e\n\n[![Docker](https://img.shields.io/docker/pulls/hhftechnology/pangolin-cloudflare-tunnel?style=flat-square)](https://hub.docker.com/r/hhftechnology/pangolin-cloudflare-tunnel)\n![Stars](https://img.shields.io/github/stars/hhftechnology/pangolin-cloudflare-tunnel?style=flat-square)\n[![Discord](https://img.shields.io/discord/994247717368909884?logo=discord\u0026style=flat-square)](https://discord.gg/HDCt9MjyMJ)\n\u003c/div\u003e\n\n## Overview\n\nThis tool synchronizes Traefik routes with Cloudflare Zero-Trust tunnels, providing an alternative or complementary tunneling option for Pangolin deployments. This integration allows you to:\n\n- Expose Pangolin-managed services through Cloudflare's global network\n- Take advantage of Cloudflare's DDoS protection and caching capabilities\n- Provide an alternative remote access method alongside Pangolin's WireGuard tunnels\n- **NEW**: Manage multiple domains across different Cloudflare zones\n- **NEW**: Exclude specific resources from Cloudflare tunneling\n- **NEW**: Automatic cleanup of DNS records for deleted resources\n\n## Features\n\n- **Multi-Domain/Multi-Zone Support**: Configure multiple domains across different Cloudflare zones\n- **Resource Exclusion**: Ignore specific domains or patterns (e.g., Jellyfin for TOS compliance)\n- **Automatic DNS Cleanup**: Automatically remove DNS records when resources are deleted\n- **TLS Route Filtering**: Optionally skip or include TLS-enabled routes\n- **Multiple Entrypoints**: Support for multiple Traefik entrypoints\n- **Automatic Synchronization**: Real-time sync between Traefik and Cloudflare\n- **Robust Error Handling**: Retry logic with exponential backoff\n- **Structured Logging**: Comprehensive logging with configurable verbosity\n\n## Integration with Pangolin\n\nWhen used with Pangolin:\n\n1. Pangolin manages your internal resources\n2. Traefik (used by Pangolin) handles the local routing\n3. This tool synchronizes Traefik routes to Cloudflare tunnels\n4. Cloudflare provides an additional layer of protection and global distribution\n\nThis creates a combination where you can use Pangolin for secure local deployment via Cloudflare tunnels for public-facing services for Unraid/NAS users without opening ports or buying a VPS.\n\n## Configuration\n\n### Required Environment Variables\n\n| Environment Variable     | Type   | Description                                                  |\n| :----------------------- | ------ | ------------------------------------------------------------ |\n| CLOUDFLARED_TOKEN        | String | Token for the `cloudflared` daemon. This is the token provided after [creating a tunnel](https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/install-and-setup/tunnel-guide/#1-create-a-tunnel). |\n| CLOUDFLARE_API_TOKEN     | String | A valid [Cloudflare API token](https://dash.cloudflare.com/profile/api-tokens) |\n| CLOUDFLARE_ACCOUNT_ID    | String | Your account ID. Available in the URL at https://dash.cloudflare.com |\n| CLOUDFLARE_TUNNEL_ID     | String | The ID of your Cloudflare tunnel                             |\n| TRAEFIK_API_ENDPOINT     | String | The HTTP URI to Traefik's API (e.g., http://traefik:8080) |\n| TRAEFIK_SERVICE_ENDPOINT | String | The HTTP URI to Traefik's web entrypoint (e.g., https://traefik:443) |\n\n### Zone Configuration (Choose One)\n\n#### Single Zone (Legacy)\n| Environment Variable     | Type   | Description                                                  |\n| :----------------------- | ------ | ------------------------------------------------------------ |\n| CLOUDFLARE_ZONE_ID       | String | The Cloudflare zone ID of your site                         |\n| DOMAIN_NAME              | String | (Optional) The domain name used for this zone               |\n\n#### Multi-Zone (NEW)\n| Environment Variable     | Type   | Description                                                  |\n| :----------------------- | ------ | ------------------------------------------------------------ |\n| CLOUDFLARE_ZONE_IDS      | String | Comma-separated list of Cloudflare zone IDs (e.g., `zone1,zone2,zone3`) |\n| DOMAIN_NAMES             | String | Comma-separated list of domain names matching the zones (e.g., `example.com,test.com,demo.com`) |\n\n**Note**: The order of zone IDs must match the order of domain names.\n\n### Entrypoint Configuration (Choose One)\n\n| Environment Variable     | Type   | Description                                                  |\n| :----------------------- | ------ | ------------------------------------------------------------ |\n| TRAEFIK_ENTRYPOINTS      | String | Comma-separated list of Traefik entrypoints (e.g., `web,websecure`) |\n| TRAEFIK_ENTRYPOINT       | String | (Legacy) Single Traefik entrypoint (e.g., `web`)           |\n\n### Optional Environment Variables\n\n| Environment Variable | Type    | Default | Description                                                  |\n| :------------------- | ------- | ------- | ------------------------------------------------------------ |\n| SKIP_TLS_ROUTES      | Boolean | `true`  | Skip routes with TLS configured. Set to `false` to include TLS routes |\n| POLL_INTERVAL        | String  | `10s`   | Polling interval (e.g., `10s`, `1m`, `30s`)                 |\n| LOG_LEVEL            | String  | `info`  | Log level (`debug` or `info`)                               |\n| IGNORE_PATTERNS      | String  | (empty) | Comma-separated regex patterns for domains to ignore (e.g., `^jellyfin\\.,^media\\.`) |\n| ENABLE_DNS_CLEANUP   | Boolean | `true`  | Automatically remove DNS records for deleted resources       |\n\n### Cloudflare Permissions\n\nThe `CLOUDFLARE_API_TOKEN` is your API token which can be created at: https://dash.cloudflare.com/profile/api-tokens\n\nEnsure the permissions for your Cloudflare token match the following:\n\n- Account -\u003e Cloudflare Tunnel -\u003e Edit\n- Account -\u003e Zero Trust -\u003e Edit\n- User -\u003e User Details -\u003e Read\n- Zone -\u003e DNS -\u003e Edit\n\n## Example with Pangolin\n\nThis example shows how to integrate Cloudflare tunnels with a Pangolin deployment.\n\n1. First, set up Pangolin according to its [installation guide](https://docs.fossorial.io/Getting%20Started/quick-install)\n\n2. Create an `.env` file with your Cloudflare credentials:\n\n```bash\ncd example\ncp .env.example .env\nvi .env\n```\n\n3. Add this service to your existing Pangolin `docker-compose.yml`:\n\n```yaml\nname: pangolin\nservices:\n  pangolin:\n    image: fosrl/pangolin:1.1.0\n    container_name: pangolin\n    restart: unless-stopped\n    volumes:\n      - ./config:/app/config\n    healthcheck:\n      test: [\"CMD\", \"curl\", \"-f\", \"http://localhost:3001/api/v1/\"]\n      interval: \"3s\"\n      timeout: \"3s\"\n      retries: 5\n    networks:\n      - pangolin_network\n\n  traefik:\n    image: traefik:v3.3.3\n    container_name: traefik\n    restart: unless-stopped\n    ports:\n      - 443:443\n      - 80:80\n      - 8080:8080\n    depends_on:\n      pangolin:\n        condition: service_healthy\n    command:\n      - --configFile=/etc/traefik/traefik_config.yml\n    environment:\n      - CLOUDFLARE_DNS_API_TOKEN=your_dns_api_token_here\n    volumes:\n      - ./config/traefik:/etc/traefik:ro\n      - ./config/letsencrypt:/letsencrypt\n      - ./config/traefik/logs:/var/log/traefik\n    networks:\n      - pangolin_network\n\n  cloudflared:\n    image: cloudflare/cloudflared:2025.4.0\n    container_name: cloudflared\n    restart: unless-stopped\n    command:\n      - tunnel\n      - --no-autoupdate\n      - run\n      - --token=your_cloudflared_token_here\n    networks:\n      - pangolin_network\n    depends_on:\n      - traefik\n\n  traefik-cloudflare-tunnel:\n    image: \"hhftechnology/pangolin-cloudflare-tunnel:latest\"\n    container_name: pangolin-cloudflare-tunnel\n    restart: unless-stopped\n    environment:\n      # Required Configuration\n      - CLOUDFLARE_API_TOKEN=your_api_token_here\n      - CLOUDFLARE_ACCOUNT_ID=your_account_id_here\n      - CLOUDFLARE_TUNNEL_ID=your_tunnel_id_here\n      - TRAEFIK_SERVICE_ENDPOINT=https://traefik:443\n      - TRAEFIK_API_ENDPOINT=http://traefik:8080\n      - TRAEFIK_ENTRYPOINTS=web,websecure\n\n      # Multi-Zone Configuration (NEW)\n      - CLOUDFLARE_ZONE_IDS=zone_id_1,zone_id_2\n      - DOMAIN_NAMES=example.com,test.com\n\n      # Optional Configuration\n      - POLL_INTERVAL=10s\n      - SKIP_TLS_ROUTES=false\n      - LOG_LEVEL=debug\n      - ENABLE_DNS_CLEANUP=true\n\n      # Resource Exclusion (NEW) - Ignore Jellyfin and media services\n      - IGNORE_PATTERNS=^jellyfin\\.,^media\\.\n    networks:\n      - pangolin_network\n    depends_on:\n      - traefik\n      - cloudflared\n\nnetworks:\n  pangolin_network:\n    driver: bridge\n    name: pangolin_network\n```\n\n4. Restart your Pangolin stack:\n\n```bash\nsudo docker compose up -d\n```\n\n5. Create resources in Pangolin as usual. Resources with the specified entrypoint will be automatically exposed through Cloudflare tunnels.\n\n## Use Cases\n\n### Multi-Domain Setup\n\nManage multiple domains across different Cloudflare zones:\n\n```bash\nCLOUDFLARE_ZONE_IDS=zone1,zone2,zone3\nDOMAIN_NAMES=example.com,test.com,demo.com\n```\n\n### Resource Exclusion\n\nExclude specific services that shouldn't use Cloudflare CDN (e.g., Jellyfin for TOS compliance):\n\n```bash\nIGNORE_PATTERNS=^jellyfin\\.,^media\\.,^plex\\.\n```\n\nThis will exclude:\n- `jellyfin.example.com`\n- `media.example.com`\n- `plex.example.com`\n\n### Automatic Cleanup\n\nEnable automatic DNS cleanup to remove records for deleted resources:\n\n```bash\nENABLE_DNS_CLEANUP=true\n```\n\nWhen a resource is deleted from Traefik, its corresponding DNS record will be automatically removed from Cloudflare.\n\n## Architecture\n\nThe application is structured with a clean, modular architecture:\n\n```\n.\n├── main.go                     # Application entry point\n├── internal/\n│   ├── config/                 # Configuration management\n│   ├── traefik/                # Traefik API client and router management\n│   ├── cloudflare/             # Cloudflare API client and operations\n│   ├── sync/                   # Synchronization orchestration\n│   └── errors/                 # Custom error types\n└── pkg/\n    └── retry/                  # Retry utility with exponential backoff\n```\n\n## Advanced Configuration\n\n### Multi-Host Setup with Gerbil\n\nYou can use this tool with multiple Docker hosts on the same hypervisor layer while keeping Gerbil in your setup. This allows connecting multiple LXC containers (each running Docker) to a single centralized Pangolin instance.\n\n### Custom Polling Intervals\n\nAdjust the polling interval based on your needs:\n\n```bash\nPOLL_INTERVAL=30s  # Less frequent polling (lower resource usage)\nPOLL_INTERVAL=5s   # More frequent polling (faster updates)\n```\n\n### Debug Logging\n\nEnable debug logging for troubleshooting:\n\n```bash\nLOG_LEVEL=debug\n```\n\n## Troubleshooting\n\n### DNS Records Not Created\n\n1. Check that your `CLOUDFLARE_API_TOKEN` has the correct permissions\n2. Verify that `CLOUDFLARE_ZONE_IDS` and `DOMAIN_NAMES` match correctly\n3. Enable debug logging to see detailed error messages\n\n### Domain Not Matching Zone\n\nIf you see warnings like \"no matching zone\", ensure:\n- The domain is a subdomain of one of your configured `DOMAIN_NAMES`\n- The order of `CLOUDFLARE_ZONE_IDS` matches `DOMAIN_NAMES`\n\n### Resources Not Excluded\n\nIf the `IGNORE_PATTERNS` aren't working:\n- Check that your regex patterns are correct\n- Test patterns at https://regex101.com\n- Remember to escape special characters (e.g., `\\.` for literal dots)\n\n## For More Information\n\n- [Pangolin Documentation](https://docs.fossorial.io/Pangolin/)\n- [Cloudflare Tunnel Documentation](https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/)\n- [Traefik Documentation](https://doc.traefik.io/traefik/)\n\n## Contributing\n\nContributions are welcome! Please feel free to submit issues or pull requests.\n\n## License\n\nThis project follows the MIT license.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhhftechnology%2Fpangolin-cloudflare-tunnel","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhhftechnology%2Fpangolin-cloudflare-tunnel","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhhftechnology%2Fpangolin-cloudflare-tunnel/lists"}