Cloud & Hosting

Cloudflare Tunnel in Docker draaien (Compose-gids 2026)

Cloudflare Tunnel in Docker draaien: voeg de cloudflare/cloudflared-image toe aan docker-compose, geef een TUNNEL_TOKEN mee en stel elke zelf-gehoste app bloot zonder open poorten. Inclusief de valkuil rond containernetwerken en de limieten van het gratis plan.

Waqas Ahmed Waseer
Waqas Ahmed Waseer 8 jul 2026 8 min leestijd
Cloudflare Tunnel in Docker draaien (Compose-gids 2026)

Om Cloudflare Tunnel in Docker te draaien voeg je de officiële cloudflare/cloudflared-image als service toe aan je docker-compose.yml, geef je een tunneltoken uit het Cloudflare-dashboard mee als de TUNNEL_TOKEN-omgevingsvariabele en zet je cloudflared op hetzelfde Docker-netwerk als de app die je wilt blootstellen. Dat is de hele truc: geen poorten open in je firewall, geen reverse proxy om te configureren, en cloudflared bereikt je app via zijn containernaam over het interne netwerk van Docker. Deze gids loopt de exacte Compose-opzet langs, de ene netwerkvalkuil waar bijna iedereen over struikelt, en de limieten die je moet kennen voordat je erop vertrouwt.

Wil je het volledige plaatje van hoe tunnels werken bij elke installatiemethode (systemd, macOS, quick tunnels, plus Cloudflare Access ervoor), lees dan onze complete gids voor het opzetten van een Cloudflare Tunnel. Dit stuk is bewust smaller: het gecontaineriseerde Docker Compose-patroon dat de officiële documentatie grotendeels overslaat.

Waarom cloudflared als container draaien?

De cloudflare/cloudflared Docker-image is de connector-daemon die een uitsluitend uitgaande verbinding opent naar de edge van Cloudflare en verzoeken doorstuurt naar je lokale diensten. Hem als container draaien in plaats van als systeempakket heeft drie echte voordelen voor een zelf-gehoste stack. Hij staat in dezelfde docker-compose.yml als al het andere, dus de hele stack komt omhoog met één docker compose up -d. Hij is vastgezet op een image-tag, dus upgrades zijn een bewuste docker pull, geen automatische update op de achtergrond. En hij kan rechtstreeks met je andere containers praten over een privé-Docker-netwerk, wat betekent dat de app die je blootstelt nooit een gepubliceerde poort nodig heeft.

Het beveiligingsmodel is het deel dat mensen onderschatten. Omdat cloudflared naar buiten belt naar Cloudflare over QUIC/HTTPS, kan je VPS of thuisserver elke inkomende poort dicht houden bij de firewall. Er luistert geen 80/443 op het openbare internet om te scannen of te brute-forcen. Voor een zelf-gehoste machine is dat een betekenisvolle vermindering van het aanvalsoppervlak vergeleken met het openzetten van gaten voor een traditionele reverse proxy.

Vereisten

  • Een domein dat is onboarded bij Cloudflare (met de nameservers van Cloudflare). De officiële setup-documentatie noemt dit als vereiste om een applicatie via een tunnel te publiceren.
  • Docker en Docker Compose geïnstalleerd op de host. Als je vanaf een kale server begint, dekt onze gids voor het veilige eerste uur van een VPS het harden af voordat je iets blootstelt.
  • Een tunneltoken, in één stap aangemaakt in het dashboard (volgende sectie).

Cloudflare Tunnel zelf is gratis met onbeperkte bandbreedte — je hebt alleen het gratis Cloudflare-account en een domein op hun DNS nodig.

Stap 1 — Maak een op afstand beheerde tunnel aan en kopieer het token

Ga in het Cloudflare-dashboard naar Zero Trust → Networks → Tunnels → Create a tunnel, kies Cloudflared, geef hem een naam en sla op. Kies op het scherm "install connector" voor Docker. Cloudflare toont je een docker run-commando met een lang token erin gebakken — je hebt niet het hele commando nodig, alleen de tokenstring na --token. Dat token authenticeert de connector én vertelt hem bij welke tunnel hij hoort.

Dit is het op afstand beheerde model: de routeringsregels van de tunnel (welke hostname naar welke lokale dienst wijst) worden geconfigureerd in het dashboard, niet in een lokaal configuratiebestand. Het is het eenvoudigste pad voor Docker en degene waar Cloudflare nu standaard op inzet. Het alternatief, lokaal beheerd, houdt een config.yml en credentialsbestand binnen de container — draagbaarder en versiebeheerbaar, maar met meer bewegende delen. De tabel hieronder vergelijkt ze.

Op afstand beheerd (token)Lokaal beheerd (config.yml)
Waar de routering leeftCloudflare-dashboardconfig.yml op de host
Wat de container nodig heeftAlleen TUNNEL_TOKENConfigbestand + credentials-JSON ingekoppeld
Best voorDe meeste Docker-opzetten, snelle startGitOps, veel hostnames, reproduceerbare infra
Ingress-bewerkingenKlikken in dashboardBestand bewerken, container herstarten
Te beschermen secretsHet tokenHet credentialsbestand

Stap 2 — Voeg cloudflared toe aan docker-compose.yml

Hier is een minimaal Compose-bestand dat een app-container (noem hem webapp, luisterend op poort 3000) via de tunnel blootstelt:

services:
  webapp:
    image: your/webapp:latest
    restart: unless-stopped
    networks: [internal]
    # note: no "ports:" — nothing is published to the host

  cloudflared:
    image: cloudflare/cloudflared:latest
    restart: unless-stopped
    command: tunnel --no-autoupdate run
    environment:
      - TUNNEL_TOKEN=${TUNNEL_TOKEN}
    networks: [internal]

networks:
  internal:

Zet het token in een .env-bestand naast het Compose-bestand (TUNNEL_TOKEN=ey...) en voeg dat bestand toe aan .gitignore. Commit het token nooit — iedereen die het heeft kan je tunnel draaien. Gebruik voor een gehardende opzet een Docker secret in plaats van een env-variabele. De vlag --no-autoupdate is bewust: de image-tag bepaalt de versie, dus je upgradet door een nieuwe image te pullen, niet door de daemon zichzelf tijdens runtime te laten patchen.

Het equivalente eenmalige commando, als je geen Compose gebruikt, is hetzelfde dat het dashboard afdrukt:

docker run cloudflare/cloudflared:latest tunnel --no-autoupdate run --token <TUNNEL_TOKEN>

Stap 3 — Wijs de tunnel naar je container (de valkuil)

Dit is waar de meeste mensen vastlopen, en het staat overal op de Cloudflare-community-forums. Open in het dashboard je tunnel, ga naar het tabblad Public Hostname en voeg een route toe: kies een subdomein (zeg app.yourdomain.com) en stel de service-URL in.

De fout is http://localhost:3000 invoeren. Binnen de cloudflared-container is localhost de cloudflared-container zelf — niet je app, en niet de Docker-host. Omdat beide containers het internal-netwerk delen, kan cloudflared de app opzoeken via zijn Compose-servicenaam. De juiste service-waarde is dus:

http://webapp:3000

De ingebouwde DNS van Docker koppelt webapp aan het IP van de app-container op het gedeelde netwerk. Als je app ergens anders draait dan een zustercontainer — zeg rechtstreeks op de host — gebruik je in plaats daarvan http://host.docker.internal:3000 (met de juiste extra_hosts-vermelding op Linux). Deze URL goed krijgen is 90% van een werkende tunnel; een 502 aan de edge betekent vrijwel altijd dat cloudflared het adres dat je hier hebt getypt niet kan bereiken.

Stap 4 — Breng het omhoog en verifieer

docker compose up -d
docker compose logs -f cloudflared

Zoek in de logs naar regels die geregistreerde verbindingen met de edge van Cloudflare bevestigen (meestal vier, naar verschillende datacenters). Zodra die er zijn, laad je https://app.yourdomain.com — TLS wordt automatisch afgehandeld aan de edge van Cloudflare, dus je krijgt HTTPS zonder ooit een certificaat op je machine te installeren. Als het niet resolvet, controleer dan of het DNS-record van de Public Hostname is aangemaakt (Cloudflare voegt een geproxyde CNAME voor je toe) en of de service-URL overeenkomt met je containernaam en poort.

Limieten die je moet kennen voordat je ervan afhankelijk wordt

Tunnels zijn solide, maar de gratis proxy heeft harde randen:

  • 100 MB uploadlimiet. De Free- en Pro-plannen van Cloudflare hanteren een maximale request-body-grootte van 100 MB. Upload een groter bestand via de tunnel en de edge geeft HTTP 413 terug voordat het ooit je container bereikt. Dit treft apps voor bestandsuploads, back-ups en grote mediaposts.
  • Niet voor zware mediastreaming. De proxy van Cloudflare is niet bedoeld om grote hoeveelheden niet-HTML-content zoals videobibliotheken te serveren; een zelf-gehoste Plex of Jellyfin achter een tunnel kan tegen throttling aanlopen. Gebruik het voor apps en dashboards, niet als CDN voor een filmcollectie.
  • Quick tunnels zijn alleen voor testen. De wegwerp-trycloudflare.com-tunnels hebben een limiet van 200 gelijktijdige verzoeken en ondersteunen geen Server-Sent Events. Prima voor een demo, verkeerd voor productie — gebruik in plaats daarvan een benoemde tunnel met je eigen domein.
  • Je vertrouwt op de edge van Cloudflare. Al het verkeer gaat door hun netwerk. Voor de meeste zelf-hosters is dat een acceptabele afweging voor gesloten inkomende poorten; is het dat niet voor jouw dreigingsmodel, dan is een zelf-gehoste WireGuard of reverse proxy het alternatief.

Voor een diepere beveiligingslaag kun je ook Cloudflare Access voor de hostname zetten zodat alleen geauthenticeerde gebruikers de app bereiken — behandeld in de algemene tunnelgids.

Waar dit past in een zelf-gehoste stack

Het Docker-tunnelpatroon komt tot zijn recht wanneer je je apps al in containers draait — en dat is de richting waarin het meeste zelf-hosten is opgeschoven. Combineer het met onze stapsgewijze gids voor het zelf-hosten van je apps op een VPS en cloudflared wordt de enige, draagbare "voordeur"-service die je in elke stack laat vallen. Eén image, één env-variabele, nul open poorten.

Veelgestelde vragen

Kan ik cloudflared in docker-compose draaien?

Ja. Voeg cloudflare/cloudflared:latest toe als service met command: tunnel --no-autoupdate run en een TUNNEL_TOKEN-omgevingsvariabele met een token dat je hebt aangemaakt in het Cloudflare Zero Trust-dashboard. Zet hem op hetzelfde Docker-netwerk als de app die je blootstelt, zodat hij de container op naam kan bereiken.

Hoe bereikt cloudflared een andere container?

Via de interne DNS van Docker. Wanneer beide containers een door de gebruiker gedefinieerd netwerk delen, zoekt cloudflared de andere container op via zijn Compose-servicenaam — dus de service-URL van de tunnel is http://<service-name>:<port> (bijvoorbeeld http://webapp:3000), nooit http://localhost:3000, omdat localhost binnen de container naar cloudflared zelf verwijst.

Moet ik poorten openen voor een Cloudflare Tunnel in Docker?

Nee. cloudflared maakt een uitsluitend uitgaande verbinding naar de edge van Cloudflare, dus er worden geen inkomende poorten gepubliceerd op de container of geopend in de firewall van de host. Die gesloten-poort-houding is het belangrijkste beveiligingsvoordeel ten opzichte van een traditionele reverse proxy.

Is Cloudflare Tunnel gratis?

Ja. Cloudflare Tunnel is gratis met onbeperkte bandbreedte op het gratis plan; je hebt alleen een gratis Cloudflare-account en een domein nodig dat de DNS van Cloudflare gebruikt. Betaalde plannen versoepelen sommige proxylimieten (zoals de request-limiet van 100 MB), maar zijn niet vereist om een tunnel te draaien.

Cloudflare Tunnel of een reverse proxy — welke moet ik in Docker gebruiken?

Gebruik een reverse proxy (Caddy, Traefik, Nginx) wanneer je het prettig vindt om 80/443 te openen en volledige controle wilt over TLS en caching op je eigen machine. Gebruik een Cloudflare Tunnel wanneer je liever elke inkomende poort dicht houdt en Cloudflare de TLS en edge-routering laat afhandelen. Veel stacks draaien beide: een tunnel voor externe toegang, een proxy voor interne routering.

Sources

Waqas Ahmed Waseer

Waqas Ahmed Waseer

Waqas Ahmed Waseer is ontwikkelaar en automation-builder met meer dan 8 jaar ervaring in het bouwen van productiesystemen die door 100.000+ mensen worden gebruikt. Hij bouwt custom multi-tenant SaaS, AI-automatisering (n8n, LLM-workflows, WhatsApp-bots) en hostinginfrastructuur (WHM/cPanel, CloudLinux) — en is de maker van WaSphere, FlowMaticX en het hostingmerk WaseerHost. 100+ projecten opgeleverd voor mkb, bureaus en gefinancierde startups.

Gerelateerd

Meer in Cloud & Hosting

Bekijk alles

Discussie · 0

Wees vriendelijk. Reacties zijn openbaar.

    Nieuwsbrief · Maandageditie

    De maandagbriefing.

    Eén e-mail elke maandagochtend. De week vooruit in AI, startups, hosting en devtools — geen onzin, geen gesponsorde lokkertjes.

    Gratis. Met één klik uitschrijven.