-
-
Save mattdy/d741344366a4fbb86f5034adfd1ad191 to your computer and use it in GitHub Desktop.
Please see https://mattdyson.org/blog/2024/02/using-traefik-with-cloudflare-tunnels for a detailed write-up of this configuration |
ROOT_DOMAIN=yourdomain.com | |
HTTP_TIMEOUT=60 | |
POLLING_INTERVAL=10 | |
PROPAGATION_TIMEOUT=3600 | |
TTL=300 | |
PROVIDERS_GOOGLE_CLIENT_ID=<GOOGLE CLIENT ID> | |
PROVIDERS_GOOGLE_CLIENT_SECRET=<GOOGLE CLIENT SECRET> | |
SECRET=RandomTextGoesHere | |
WHITELIST=<YOUR GOOGLE ACCOUNT EMAIL> | |
LOG_LEVEL=INFO | |
ZONE_ID=<YOUR CLOUDFLARE ZONE ID> | |
TUNNEL_TOKEN=<YOUR CLOUDFLARE TUNNEL TOKEN> |
version: '3.7' | |
services: | |
whoami: | |
image: traefik/whoami | |
command: | |
- --name=externalapp | |
deploy: | |
labels: | |
- "traefik.enable=true" | |
- "traefik.docker.network=traefik" | |
- "traefik.http.routers.external.rule=Host(`external.yourdomain.com`)" | |
- "traefik.http.routers.external.entrypoints=websecure" | |
- "traefik.http.routers.external.tls=true" | |
- "traefik.http.routers.external.middlewares=forward-auth" | |
- "traefik.http.services.external.loadbalancer.server.port=80" | |
- "traefik.constraint=proxy-public" | |
networks: | |
traefik: | |
external: true |
version: '3.7' | |
services: | |
whoami: | |
image: traefik/whoami | |
command: | |
- --name=internalapp | |
deploy: | |
labels: | |
- "traefik.enable=true" | |
- "traefik.docker.network=traefik" | |
- "traefik.http.routers.internal.rule=Host(`internal.yourdomain.com`)" | |
- "traefik.http.routers.internal.entrypoints=websecure" | |
- "traefik.http.routers.internal.tls=true" | |
- "traefik.http.services.internal.loadbalancer.server.port=80" | |
networks: | |
traefik: | |
external: true |
version: '3.7' | |
services: | |
reverse-proxy: | |
image: traefik:v2.10 | |
command: | |
- "--log" | |
- "--log.level=${LOG_LEVEL:-INFO}" | |
- "--log.format=json" | |
- "--api.insecure=true" | |
- "--providers.docker" | |
- "--providers.docker.swarmMode=true" | |
- "--providers.docker.exposedbydefault=false" | |
- "--providers.file.directory=/config" | |
- "--providers.file.watch=true" | |
- "--serversTransport.insecureSkipVerify=true" # Allow self-signed certificates for target hosts - https://doc.traefik.io/traefik/routing/overview/#insecureskipverify | |
- "--metrics" | |
- "--metrics.prometheus.buckets=0.1,0.3,1.2,5.0" | |
- "--entrypoints.web.address=:80" | |
- "--entrypoints.web.http.redirections.entrypoint.to=websecure" | |
- "--entrypoints.web.http.redirections.entrypoint.scheme=https" | |
- "--entrypoints.websecure.address=:443" | |
- "--entrypoints.websecure.http.tls=true" | |
- "--entrypoints.websecure.http.tls.certresolver=letsencrypt" | |
- "--entrypoints.webinternal.address=:82" | |
- "--certificatesresolvers.letsencrypt.acme.email=<YOUR EMAIL>" | |
- "--certificatesresolvers.letsencrypt.acme.storage=/etc/traefik/acme/letsencrypt.json" | |
- "--certificatesresolvers.letsencrypt.acme.dnschallenge.provider=cloudflare" | |
- "--certificatesresolvers.letsencrypt.acme.dnschallenge.delaybeforecheck=300" | |
- "--certificatesresolvers.letsencrypt.acme.dnschallenge.resolvers=8.8.8.8:53" | |
secrets: | |
- cf_token | |
environment: | |
- CLOUDFLARE_DNS_API_TOKEN_FILE=/run/secrets/cf_token | |
- CLOUDFLARE_HTTP_TIMEOUT=${HTTP_TIMEOUT} | |
- CLOUDFLARE_POLLING_INTERVAL=${POLLING_INTERVAL} | |
- CLOUDFLARE_PROPAGATION_TIMEOUT=${PROPAGATION_TIMEOUT} | |
- CLOUDFLARE_TTL=${TTL} | |
deploy: | |
restart_policy: | |
condition: any | |
delay: 5s | |
max_attempts: 3 | |
window: 120s | |
update_config: # Start new instance before stopping existing one | |
delay: 10s | |
order: start-first | |
parallelism: 1 | |
rollback_config: | |
parallelism: 0 | |
order: stop-first | |
placement: | |
constraints: | |
- node.role == manager | |
labels: | |
- traefik.enable=true | |
- traefik.http.routers.api.rule=Host(`traefik.${ROOT_DOMAIN}`) | |
- traefik.http.routers.api.service=api@internal | |
- traefik.http.routers.api.entrypoints=websecure | |
- traefik.http.routers.api.tls=true | |
- traefik.http.services.api.loadbalancer.server.port=8080 | |
ports: | |
# HTTP | |
- target: 80 | |
published: 80 | |
# HTTPS | |
- target: 443 | |
published: 443 | |
# Web UI (enabled by --api.insecure=true) | |
- target: 8080 | |
published: 8080 | |
networks: | |
- traefik | |
- internal | |
volumes: | |
# So that Traefik can listen to the Docker events | |
- /var/run/docker.sock:/var/run/docker.sock | |
- acme:/etc/traefik/acme | |
- traefik:/config | |
- cloudflare:/cloudflare | |
traefik-forward-auth: | |
image: thomseddon/traefik-forward-auth:2.1.0 | |
networks: | |
- traefik | |
environment: | |
- PROVIDERS_GOOGLE_CLIENT_ID=${PROVIDERS_GOOGLE_CLIENT_ID} | |
- PROVIDERS_GOOGLE_CLIENT_SECRET=${PROVIDERS_GOOGLE_CLIENT_SECRET} | |
- SECRET=${SECRET} | |
- AUTH_HOST=auth.${ROOT_DOMAIN} | |
- COOKIE_DOMAIN=${ROOT_DOMAIN} | |
- WHITELIST=${WHITELIST} | |
deploy: | |
labels: | |
- traefik.enable=true | |
- traefik.docker.network=traefik | |
- traefik.http.routers.auth.rule=Host(`auth.${ROOT_DOMAIN}`) | |
- traefik.http.routers.auth.entrypoints=websecure | |
- traefik.http.routers.auth.tls=true | |
- traefik.http.routers.auth.tls.domains[0].main=${ROOT_DOMAIN} | |
- traefik.http.routers.auth.tls.domains[0].sans=*.${ROOT_DOMAIN} | |
- traefik.http.routers.auth.tls.certresolver=letsencrypt | |
- traefik.http.routers.auth.service=auth@docker | |
- traefik.http.services.auth.loadbalancer.server.port=4181 | |
- traefik.http.middlewares.forward-auth.forwardauth.address=http://traefik-forward-auth:4181 | |
- traefik.http.middlewares.forward-auth.forwardauth.trustForwardHeader=true | |
- traefik.http.middlewares.forward-auth.forwardauth.authResponseHeaders=X-Forwarded-User | |
- traefik.http.routers.auth.middlewares=forward-auth | |
- traefik.constraint=proxy-public | |
tunnel: | |
container_name: cloudflared-tunnel | |
image: cloudflare/cloudflared | |
restart: unless-stopped | |
command: tunnel run | |
deploy: | |
mode: replicated | |
replicas: 3 | |
update_config: | |
delay: 30s | |
order: start-first | |
monitor: 20s | |
networks: | |
- traefik | |
environment: | |
- TUNNEL_TOKEN=${TUNNEL_TOKEN} | |
error-pages: | |
image: tarampampam/error-pages:2.26.0 | |
environment: | |
TEMPLATE_NAME: l7-dark | |
networks: | |
- traefik | |
deploy: | |
mode: replicated | |
replicas: 2 | |
update_config: | |
delay: 20s | |
order: start-first | |
monitor: 10s | |
labels: | |
- traefik.enable=true | |
- traefik.docker.network=traefik | |
# use as "fallback" for any non-registered services (with priority below normal) | |
- traefik.http.routers.error-pages.rule=HostRegexp(`{host:.+}`) | |
- traefik.http.routers.error-pages.priority=10 | |
# should say that all of your services work on https | |
- traefik.http.routers.error-pages.tls='true' | |
- traefik.http.routers.error-pages.entrypoints=websecure | |
- traefik.http.routers.error-pages.middlewares=error-pages | |
- traefik.http.services.error-pages.loadbalancer.server.port=8080 | |
# "errors" middleware settings | |
- traefik.http.middlewares.error-pages.errors.status=400-599 | |
- traefik.http.middlewares.error-pages.errors.service=error-pages | |
- traefik.http.middlewares.error-pages.errors.query=/{status}.html | |
cloudflare-companion: | |
image: ghcr.io/tiredofit/docker-traefik-cloudflare-companion:latest | |
volumes: | |
- /var/run/docker.sock:/var/run/docker.sock | |
deploy: | |
placement: | |
constraints: | |
- node.role == manager | |
environment: | |
- TIMEZONE=Europe/London | |
- LOG_TYPE=CONSOLE | |
- LOG_LEVEL=INFO | |
- TRAEFIK_VERSION=2 | |
- RC_TYPE=CNAME | |
- TARGET_DOMAIN=${ROOT_DOMAIN} | |
- REFRESH_ENTRIES=TRUE | |
- DOCKER_SWARM_MODE=TRUE | |
- ENABLE_TRAEFIK_POLL=TRUE | |
- TRAEFIK_POLL_URL=https://traefik.${ROOT_DOMAIN}/api | |
- TRAEFIK_FILTER_LABEL=traefik.constraint | |
- TRAEFIK_FILTER=proxy-public | |
- DOMAIN1=${ROOT_DOMAIN} | |
- DOMAIN1_ZONE_ID=${ZONE_ID} | |
- DOMAIN1_PROXIED=TRUE | |
restart: always | |
networks: | |
- internal | |
secrets: | |
- cf_token | |
networks: | |
traefik: | |
external: true | |
internal: | |
volumes: | |
acme: | |
traefik: | |
cloudflare: | |
secrets: | |
cf_token: | |
external: true |
Hey @mattdy
I know its been a while since you made this, but I've run into a couple problems. I've gotten to the point DNS records are being made. But when I go to that site, I get a 1033 tunnel error. Googling it most people just say the tunnel itself isn't running. Though mine says healthy and running. I am running all this off Unraid (Linux distro) so I'm not able to follow everything 100% with the compose, as they use fields instead of compose files.
My thought is my tunnel's public hostname is incorrect. I had the service type as HTTPS and the URL originally as the private IP for the container running it, then switched it to be "traefik" the name of the container.
external.mydomain.com and traefik.mydomain.com were both made as cnames. Both giving 1033 argo tunnel errors. If you have any advice I'd be very appreciative!
Both giving 1033 argo tunnel errors. If you have any advice I'd be very appreciative!
Hi @NEP1192
When you view the tunnel (Network / Tunnels) within Cloudflare, does it show as 'healthy'? If not, then there's a problem with the configuration of the tunnel on your system. If it is showing 'healthy', then perhaps you've not put the correct Tunnel ID into your CNAMEs?
If it is showing 'healthy', then perhaps you've not put the correct Tunnel ID into your CNAMEs?
Yep put in the connector ID not the tunnel ID, thank you!
Also figured out the 404 error I was having is because I needed to add the reverse proxy inside traefik's fileConfig.yml as well.
Hi @mattdy
My docker setup is pretty simple, and I have a healthy green tunnel, however when I start the companion container the logs are scrolling these errors and I can't figure out if this is because my public hostname for my tunnel is incorrect or if I have something else set incorrectly in my configuration?
2024-12-21T21:41:06-0600 INFO | Found Service ID: b5d138964e2a84dea9803750fa791d9946aeef27b837090a773961f57a4c8c07 with Hostname my.domain.com
Traceback (most recent call last):
File "/usr/lib/python3.12/site-packages/requests/models.py", line 974, in json
return complexjson.loads(self.text, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.12/json/__init__.py", line 346, in loads
return _default_decoder.decode(s)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.12/json/decoder.py", line 338, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.12/json/decoder.py", line 356, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/sbin/cloudflare-companion", line 551, in <module>
sync_mappings(get_initial_mappings(traefik_included_hosts, traefik_excluded_hosts), doms)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/sbin/cloudflare-companion", line 432, in get_initial_mappings
add_to_mappings(mappings, check_traefik(included_hosts, excluded_hosts))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/sbin/cloudflare-companion", line 358, in check_traefik
for router in r.json():
^^^^^^^^
File "/usr/lib/python3.12/site-packages/requests/models.py", line 978, in json
raise RequestsJSONDecodeError(e.msg, e.doc, e.pos)
requests.exceptions.JSONDecodeError: Expecting value: line 1 column 1 (char 0)```
My docker setup is pretty simple, and I have a healthy green tunnel, however when I start the companion container the logs are scrolling these errors and I can't figure out if this is because my public hostname for my tunnel is incorrect or if I have something else set incorrectly in my configuration?
Hi @frntman
It's a bit difficult to know what's happening there without seeing the rest of the setup.
Have you definitely got a Traefik Router set up for your Service? From a quick look at the code, you might get an error here if the Service is found, but there's no Router specified? Try enabling debug logging and see what that says.
Hi, @mattdy
having trouble with API.
With api token set to
Zone : Zone Settings : Read, Zone : Zone : Read and Zone : DNS : Edit
I'm gettin
Traceback (most recent call last): File "/usr/sbin/cloudflare-companion", line 551, in <module> sync_mappings(get_initial_mappings(traefik_included_hosts, traefik_excluded_hosts), doms) File "/usr/sbin/cloudflare-companion", line 405, in sync_mappings if point_domain(k, domain_infos): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/sbin/cloudflare-companion", line 177, in point_domain records = cf.zones.dns_records.get(domain_info['zone_id'], params={u'name': name}) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/CloudFlare/cloudflare.py", line 747, in get raise CloudFlareAPIError(e=e) from None CloudFlare.exceptions.CloudFlareAPIError: Unable to authenticate request
But with full global Api key everything working. Whats missing from permissions?
Oh, found solution!
You need to remove the CF_EMAIL in companion;s compose!
And no need in *. in origin server name(or add No TLS Verify option)!
Thx for awesome guide!
Hi @frntman
It's a bit difficult to know what's happening there without seeing the rest of the setup.
Have you definitely got a Traefik Router set up for your Service? From a quick look at the code, you might get an error here if the Service is found, but there's no Router specified? Try enabling debug logging and see what that says.
Hi @mattdy,
Just wondering if this is dependent on "TRAEFIK_VERSION" as the options are 1 or 2 and I'm actually running 3 ???
Just wondering if this is dependent on "TRAEFIK_VERSION" as the options are 1 or 2 and I'm actually running 3 ???
I'm successfully running traefik v3 with TRAEFIK_VERSION
set to 2, so this shouldn't be a problem
Thanks for the writeup. I've been struggling with acme timeout/ cloudflare propagation issues and it looks like you've got a fix in here. I'm just adapting / integrating your (wow, comprehensive) solution into what I've got but noticed one small item [TUNNEL_TOKEN] is missing from your env file.
noticed one small item [TUNNEL_TOKEN] is missing from your env file.
Good spot @jstimmer, thanks very much - I've updated the environment file to include that. Unfortunately cloudflared
can't accept a file name containing the token yet - it looks like this functionality is in development though: cloudflare/cloudflared#645
Glad you found the writeup useful!
@mattdy Thank you for the writeup!! trying to set it up but not using docker swarm. Below is my whole config and it throws error for companion app:
`version: '3.7'
services:
reverse-proxy:
image: traefik:v2.10
container_name: traefik1
command:
- "--log"
- "--log.level=${LOG_LEVEL:-INFO}"
- "--log.format=json"
- "--api.insecure=true"
- "--providers.docker"
- "--providers.docker.exposedbydefault=false"
- "--providers.file.directory=/config"
- "--providers.file.watch=true"
- "--serversTransport.insecureSkipVerify=true"
- "--metrics"
- "--metrics.prometheus.buckets=0.1,0.3,1.2,5.0"
- "--entrypoints.web.address=:80"
- "--entrypoints.web.http.redirections.entrypoint.to=websecure"
- "--entrypoints.web.http.redirections.entrypoint.scheme=https"
- "--entrypoints.websecure.address=:443"
- "--entrypoints.websecure.http.tls=true"
- "--entrypoints.websecure.http.tls.certresolver=letsencrypt"
- "--entrypoints.webinternal.address=:82"
- "--certificatesresolvers.letsencrypt.acme.email=EMAIL"
- "--certificatesresolvers.letsencrypt.acme.storage=/etc/traefik/acme/letsencrypt.json"
- "--certificatesresolvers.letsencrypt.acme.dnschallenge.provider=cloudflare"
- "--certificatesresolvers.letsencrypt.acme.dnschallenge.delaybeforecheck=300"
- "--certificatesresolvers.letsencrypt.acme.dnschallenge.resolvers=1.1.1.1:53"
environment:
- CF_DNS_API_TOKEN=${CF_TOKEN}
- CLOUDFLARE_HTTP_TIMEOUT=${HTTP_TIMEOUT}
- CLOUDFLARE_POLLING_INTERVAL=${POLLING_INTERVAL}
- CLOUDFLARE_PROPAGATION_TIMEOUT=${PROPAGATION_TIMEOUT}
- CLOUDFLARE_TTL=${TTL}
restart: always
ports:
- "80:80"
- "443:443"
- "8080:8080"
networks:
- traefik
- internal
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./acme:/etc/traefik/acme
- ./traefik:/config
- ./cloudflare:/cloudflare
labels:
- traefik.enable=true
- traefik.http.routers.api.rule=Host(traefik.${ROOT_DOMAIN}
)
- traefik.http.routers.api.service=api@internal
- traefik.http.routers.api.entrypoints=websecure
- traefik.http.routers.api.tls=true
- traefik.http.services.api.loadbalancer.server.port=8080
tunnel:
container_name: cloudflared-tunnel1
image: cloudflare/cloudflared
restart: unless-stopped
command: tunnel run
networks:
- traefik
environment:
- TUNNEL_TOKEN=${TUNNEL_TOKEN}
error-pages:
image: tarampampam/error-pages:2.26.0
container_name: error-pages1
environment:
TEMPLATE_NAME: l7-dark
networks:
- traefik
restart: always
labels:
- traefik.enable=true
- traefik.docker.network=traefik
- traefik.http.routers.error-pages.rule=HostRegexp({host:.+}
)
- traefik.http.routers.error-pages.priority=10
- traefik.http.routers.error-pages.tls='true'
- traefik.http.routers.error-pages.entrypoints=websecure
- traefik.http.routers.error-pages.middlewares=error-pages
- traefik.http.services.error-pages.loadbalancer.server.port=8080
- traefik.http.middlewares.error-pages.errors.status=400-599
- traefik.http.middlewares.error-pages.errors.service=error-pages
- traefik.http.middlewares.error-pages.errors.query=/{status}.html
cloudflare-companion:
image: ghcr.io/tiredofit/docker-traefik-cloudflare-companion:latest
container_name: cloudflare-companion1
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./cf_token:/run/secrets/cf_token:ro
environment:
- TIMEZONE=Asia/Kolkata
- LOG_TYPE=CONSOLE
- LOG_LEVEL=INFO
- TRAEFIK_VERSION=2
- RC_TYPE=CNAME
- TARGET_DOMAIN=${ROOT_DOMAIN}
- REFRESH_ENTRIES=TRUE
- ENABLE_TRAEFIK_POLL=TRUE
- CF_EMAIL=${YOUR_EMAIL}
- CF_TOKEN=${CF_TOKEN}
- TRAEFIK_POLL_URL=https://traefik.${ROOT_DOMAIN}/api
- TRAEFIK_FILTER_LABEL=traefik.constraint
- TRAEFIK_FILTER=proxy-public
- DOMAIN1=${ROOT_DOMAIN}
- DOMAIN1_ZONE_ID=${ZONE_ID}
- DOMAIN1_PROXIED=TRUE
restart: always
networks:
- internal
networks:
traefik:
name: traefik
external: true
internal:
name: internal
volumes:
acme:
traefik:
cloudflare:`
The error I am getting is:
cloudflare-companion1 | Traceback (most recent call last):
cloudflare-companion1 | File "/usr/lib/python3.12/site-packages/urllib3/connectionpool.py", line 716, in urlopen
cloudflare-companion1 | httplib_response = self._make_request(
cloudflare-companion1 | ^^^^^^^^^^^^^^^^^^^
cloudflare-companion1 | File "/usr/lib/python3.12/site-packages/urllib3/connectionpool.py", line 404, in _make_request
cloudflare-companion1 | self._validate_conn(conn)
cloudflare-companion1 | File "/usr/lib/python3.12/site-packages/urllib3/connectionpool.py", line 1061, in validate_conn
cloudflare-companion1 | conn.connect()
cloudflare-companion1 | File "/usr/lib/python3.12/site-packages/urllib3/connection.py", line 419, in connect
cloudflare-companion1 | self.sock = ssl_wrap_socket(
cloudflare-companion1 | ^^^^^^^^^^^^^^^^
cloudflare-companion1 | File "/usr/lib/python3.12/site-packages/urllib3/util/ssl.py", line 458, in ssl_wrap_socket
cloudflare-companion1 | ssl_sock = ssl_wrap_socket_impl(
cloudflare-companion1 | ^^^^^^^^^^^^^^^^^^^^^^
cloudflare-companion1 | File "/usr/lib/python3.12/site-packages/urllib3/util/ssl.py", line 502, in _ssl_wrap_socket_impl
cloudflare-companion1 | return ssl_context.wrap_socket(sock, server_hostname=server_hostname)
cloudflare-companion1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
cloudflare-companion1 | File "/usr/lib/python3.12/ssl.py", line 455, in wrap_socket
cloudflare-companion1 | return self.sslsocket_class._create(
cloudflare-companion1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
cloudflare-companion1 | File "/usr/lib/python3.12/ssl.py", line 1041, in _create
cloudflare-companion1 | self.do_handshake()
cloudflare-companion1 | File "/usr/lib/python3.12/ssl.py", line 1319, in do_handshake
cloudflare-companion1 | self._sslobj.do_handshake()
cloudflare-companion1 | ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate (_ssl.c:1000)
cloudflare-companion1 |
cloudflare-companion1 | During handling of the above exception, another exception occurred:
cloudflare-companion1 |
cloudflare-companion1 | Traceback (most recent call last):
cloudflare-companion1 | File "/usr/lib/python3.12/site-packages/requests/adapters.py", line 667, in send
cloudflare-companion1 | resp = conn.urlopen(
cloudflare-companion1 | ^^^^^^^^^^^^^
cloudflare-companion1 | File "/usr/lib/python3.12/site-packages/urllib3/connectionpool.py", line 802, in urlopen
cloudflare-companion1 | retries = retries.increment(
cloudflare-companion1 | ^^^^^^^^^^^^^^^^^^
cloudflare-companion1 | File "/usr/lib/python3.12/site-packages/urllib3/util/retry.py", line 594, in increment
cloudflare-companion1 | raise MaxRetryError(_pool, url, error or ResponseError(cause))
cloudflare-companion1 | urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='traefik.domain.com', port=443): Max retries exceeded with url: /api/api/http/routers (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate (_ssl.c:1000)')))
cloudflare-companion1 |
cloudflare-companion1 | During handling of the above exception, another exception occurred:
cloudflare-companion1 |
cloudflare-companion1 | Traceback (most recent call last):
cloudflare-companion1 | File "/usr/sbin/cloudflare-companion", line 551, in
cloudflare-companion1 | sync_mappings(get_initial_mappings(traefik_included_hosts, traefik_excluded_hosts), doms)
cloudflare-companion1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
cloudflare-companion1 | File "/usr/sbin/cloudflare-companion", line 432, in get_initial_mappings
cloudflare-companion1 | add_to_mappings(mappings, check_traefik(included_hosts, excluded_hosts))
cloudflare-companion1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
cloudflare-companion1 | File "/usr/sbin/cloudflare-companion", line 356, in check_traefik
cloudflare-companion1 | r = requests.get("{}/api/http/routers".format(TRAEFIK_POLL_URL))
cloudflare-companion1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
cloudflare-companion1 | File "/usr/lib/python3.12/site-packages/requests/api.py", line 73, in get
cloudflare-companion1 | return request("get", url, params=params, **kwargs)
cloudflare-companion1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
cloudflare-companion1 | File "/usr/lib/python3.12/site-packages/requests/api.py", line 59, in request
cloudflare-companion1 | return session.request(method=method, url=url, **kwargs)
cloudflare-companion1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
cloudflare-companion1 | File "/usr/lib/python3.12/site-packages/requests/sessions.py", line 589, in request
cloudflare-companion1 | resp = self.send(prep, **send_kwargs)
cloudflare-companion1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
cloudflare-companion1 | File "/usr/lib/python3.12/site-packages/requests/sessions.py", line 703, in send
cloudflare-companion1 | r = adapter.send(request, **kwargs)
cloudflare-companion1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
cloudflare-companion1 | File "/usr/lib/python3.12/site-packages/requests/adapters.py", line 698, in send
cloudflare-companion1 | raise SSLError(e, request=request)
cloudflare-companion1 | requests.exceptions.SSLError: HTTPSConnectionPool(host='traefik.domain.com', port=443): Max retries exceeded with url: /api/api/http/routers (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate (_ssl.c:1000)')))
@kazesaurav - Unless you've obfuscated the logs, it looks like you haven't set the ROOT_DOMAIN correctly - it's trying to connect to "traefik.domain.com"
@kazesaurav - Unless you've obfuscated the logs, it looks like you haven't set the ROOT_DOMAIN correctly - it's trying to connect to "traefik.domain.com"
It's obfuscated.
It's obfuscated.
In that case, it looks like there's an issue with verifying your SSL certificate for that domain, I'd check that the certificate is being provisioned properly by Traefik
@mattdy got the SSL working, but companion is failing to authenticate with cloudflare:
2025-03-06.01:00:14 [STARTING] ** [traefik-cloudflare-companion] [6] Starting Traefik Cloudflare Companion
2025-03-06T01:00:14+0530 INFO | Found Service ID: {obfuscate} with Hostname webtop.{obfuscate}
Traceback (most recent call last):
File "/usr/sbin/cloudflare-companion", line 551, in
sync_mappings(get_initial_mappings(traefik_included_hosts, traefik_excluded_hosts), doms)
File "/usr/sbin/cloudflare-companion", line 405, in sync_mappings
if point_domain(k, domain_infos):
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/sbin/cloudflare-companion", line 177, in point_domain
records = cf.zones.dns_records.get(domain_info['zone_id'], params={u'name': name})
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.12/site-packages/CloudFlare/cloudflare.py", line 747, in get
raise CloudFlareAPIError(e=e) from None
CloudFlare.exceptions.CloudFlareAPIError: Unable to authenticate request
2025-03-06.01:00:16 [STARTING] ** [traefik-cloudflare-companion] [7] Starting Traefik Cloudflare Companion
2025-03-06T01:00:16+0530 INFO | Found Service ID: {obfuscate} with Hostname webtop.{obfuscate}
Traceback (most recent call last):
File "/usr/sbin/cloudflare-companion", line 551, in
sync_mappings(get_initial_mappings(traefik_included_hosts, traefik_excluded_hosts), doms)
File "/usr/sbin/cloudflare-companion", line 405, in sync_mappings
if point_domain(k, domain_infos):
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/sbin/cloudflare-companion", line 177, in point_domain
records = cf.zones.dns_records.get(domain_info['zone_id'], params={u'name': name})
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.12/site-packages/CloudFlare/cloudflare.py", line 747, in get
raise CloudFlareAPIError(e=e) from None
CloudFlare.exceptions.CloudFlareAPIError: Unable to authenticate request
My config for companion app:
cloudflare-companion:
image: ghcr.io/tiredofit/docker-traefik-cloudflare-companion:latest
container_name: cloudflare-companion2
volumes:
- /var/run/docker.sock:/var/run/docker.sock
# - ./cf-token:/run/secrets/cf-token:ro
environment:
- TIMEZONE=Asia/Kolkata
- LOG_TYPE=CONSOLE
- LOG_LEVEL=INFO
- TRAEFIK_VERSION=2
- CF_EMAIL={obfuscate}
- CF_TOKEN={obfuscate}
- RC_TYPE=CNAME
- CF_DNS_API_TOKEN={obfuscate}
- TARGET_DOMAIN=htb.in.net
- REFRESH_ENTRIES=TRUE
- DOCKER_SWARM_MODE=FALSE
- ENABLE_TRAEFIK_POLL=TRUE
- TRAEFIK_POLL_URL=https://traefik.${ROOT_DOMAIN}/api
- TRAEFIK_FILTER_LABEL=traefik.constraint
- TRAEFIK_FILTER=proxy-public
- DOMAIN1={obfuscate}
- DOMAIN1_ZONE_ID={obfuscate}
- DOMAIN1_PROXIED=TRUE
restart: always
networks:
- internal
@mattdy okay I see it authenticated now but seeing below error:
Max retries exceeded with url: /api/api/http/routers (Caused by SSLError(SSLError(1, '[SSL: TLSV1_UNRECOGNIZED_NAME] tlsv1 unrecognized name (_ssl.c:1000)')))
@mattdy okay I see it authenticated now but seeing below error:
Max retries exceeded with url: /api/api/http/routers (Caused by SSLError(SSLError(1, '[SSL: TLSV1_UNRECOGNIZED_NAME] tlsv1 unrecognized name (_ssl.c:1000)')))
I had so many issues with acme that I just disabled it and only manage DNS (direct CNAME) records via cloudflare-companion and left SSL to be sorted out by Cloudflare but allowing https through the tunnel (using no TLSVerify and 443 on CF tunnel path | CF SSL/TLS: Full (strict) and edge certificates: 'always use HTTPS' & 'automatic HTTPS rewrites' set to true.)
@mattdy okay I see it authenticated now but seeing below error:
Max retries exceeded with url: /api/api/http/routers (Caused by SSLError(SSLError(1, '[SSL: TLSV1_UNRECOGNIZED_NAME] tlsv1 unrecognized name (_ssl.c:1000)')))I had so many issues with acme that I just disabled it and only manage DNS (direct CNAME) records via cloudflare-companion and left SSL to be sorted out by Cloudflare but allowing https through the tunnel (using no TLSVerify and 443 on CF tunnel path | CF SSL/TLS: Full (strict) and edge certificates: 'always use HTTPS' & 'automatic HTTPS rewrites' set to true.)
Did you do this config only on Cloudflare portal or something on docker compose as well, if you can help on that.
@mattdy okay I see it authenticated now but seeing below error:
Max retries exceeded with url: /api/api/http/routers (Caused by SSLError(SSLError(1, '[SSL: TLSV1_UNRECOGNIZED_NAME] tlsv1 unrecognized name (_ssl.c:1000)')))
Maybe try without /api
at the end of TRAEFIK_POLL_URL? Other than that, I'm afraid I don't know!
Thanks @mattdy for your clarification. I managed to make it work, not exactly as your scenario, but I figured out some stuff, at least I was able to publish a nginx and expose it by traefik. On cloudflare tunnel I had to put the IP address of my host where Docker Swarm is running. When I put the stack name (service name) does not work. And I had to set also TRAEFIK_POLL_URL to HTTP not HTTPS and for the host IP. Now I need to figure out how to change everything to make work with multiple domains :-)