MOKEA STUDIO배포 체크리스트 ↗
FIELD GUIDE / CLOUDFLARE + TRAEFIK

Cloudflare DNS or Tunnel
in front of Traefik?

Both can put a Docker app on a hostname. Choose based on how the origin server should be reached, then verify each layer before handing it over.

Docker 앱을 도메인에 연결할 때 DNS 프록시와 Tunnel 중 무엇을 고를지, Traefik의 역할과 함께 정리했습니다. 먼저 서버의 인바운드 연결을 열 수 있는지, 기존 앱이 정상 실행되는지 확인하세요.

Choose by origin reachability

Cloudflare proxied DNS

Use when the VPS can accept public web traffic on the agreed ports. The DNS record points to the origin, and Cloudflare proxies supported web traffic before Traefik routes it to a container.

Check first: the origin address, firewall, ports 80/443, current DNS records, and the TLS mode between Cloudflare and the origin.

Cloudflare Tunnel

Use when you prefer not to open inbound web ports on the origin. cloudflared creates an outbound connection and sends requests for a public hostname to the chosen local service, such as Traefik on a private Docker network.

Check first: tunnel health, the public hostname route, the exact origin URL, and whether the app itself enforces user authentication.

A Tunnel is a network path, not application authorization. Public hostnames remain public unless you add an access policy or the application has its own authentication. Don't publish admin panels or databases as a side effect of routing.

Keep Traefik's routing explicit

Traefik terminates or forwards HTTP(S) and maps host rules to the app's internal Docker address and port. Keep the dashboard private. If using the Docker provider, explicitly opt in only the containers that should be routed.

# Example intent for the Docker provider providers: docker: exposedByDefault: false # A service must be explicitly enabled with labels labels: - "traefik.enable=true" - "traefik.http.routers.app.rule=Host(`app.example.com`)" - "traefik.http.services.app.loadbalancer.server.port=8080"

The Docker socket exposes a powerful control API. Mounting it read-only does not make the API read-only. Use a restricted socket proxy or a file-based provider where appropriate, and keep the Docker API off the public network.

Use a narrow Cloudflare token

If Traefik needs Cloudflare DNS access for ACME DNS-01 certificates, create a token scoped to the required zone with DNS edit and zone read permissions. Keep it in a secret store or protected environment file, not in source control, screenshots, email, or container labels. Avoid using the account-wide Global API Key for routine deployment.

For Tunnel, keep its connector token private too. Give deployment access only for the agreed hostname and revoke temporary access after handoff.

Read the error before changing DNS

First identify which layer generated the response. Cloudflare adds cf-error-type and cf-error-origin on Cloudflare-generated error pages; these headers are absent from errors simply forwarded from your server. Redact cookies, authorization headers, and private hostnames before sharing command output.

Cloudflare 521–523Origin refused, timed out, or could not be reached. Check that the current origin address is correct, the service is listening, and the firewall permits the selected path.
Cloudflare 524The edge connected, but the origin did not return an HTTP response before the timeout. Check the application and its upstream dependencies before changing DNS.
Cloudflare 525–526The TLS handshake to the origin failed or the origin certificate is invalid. Review the chosen Cloudflare SSL mode, hostname coverage, certificate chain, and origin TLS configuration.
Cloudflare 1033Cloudflare cannot find a healthy cloudflared connector. Check the Tunnel status and connector process before changing Traefik or DNS.
Tunnel 502The connector is online but cannot reach its configured local service. Check the Tunnel origin URL, shared Docker network, Traefik service name, and internal port.
Traefik 404The request reached Traefik but no HTTP router matched it. Compare the Host rule, entrypoint, and TLS settings with the request hostname.
Traefik 503A router matched, but Traefik has no ready server for its service. Check the container's network, internal port, health, and provider labels.

These codes narrow the next check; they do not prove a single root cause. A 404 or 503 can also come from the application, so identify the response source before editing a live route.

# Public DNS and response headers; replace the example hostname dig +short app.example.com curl -sS -D - -o /dev/null https://app.example.com # On the VPS, use the actual Compose project and service names docker compose ps docker compose logs --tail=80 traefik cloudflared app

The commands above are read-only. A response header dump can contain sensitive data; share only the status, relevant Cloudflare error headers, and redacted hostnames.

Acceptance checks for every hostname

DNSResolve the agreed hostname and confirm the record or Tunnel route points to the intended path.
TLSRequest the public URL and confirm the certificate is valid for the hostname.
HTTPCheck the agreed status code and expected redirect behavior.
ApplicationCheck the app's agreed health endpoint or a safe public page; don't expose internal health details.
HandoffRecord changed files, verification results, how to redeploy, and how to roll back.

Record DNS propagation delays and third-party outages separately from configuration defects. A passing check confirms the agreed route at that time; it is not a promise of future uptime.

Official references

Want a second set of eyes?

$99 written diagnosis for one app and hostname. No configuration change; credited toward the $250 repair if booked within 14 days. Send the hostname and visible error code only—never credentials.

Request diagnosis ↗