< Back to Blog

How to Expose Your Docker Apps to the Internet with Cloudflare Tunnels

The complete guide to running production Docker apps on a local machine with Cloudflare Tunnels — no open ports, no static IP, no VPS needed.

How to Expose Your Docker Apps to the Internet with Cloudflare Tunnels

I run 14 production apps on a Mac mini in my office.

Not on AWS. Not on Render. Not on DigitalOcean.

On a used Mac mini. Accessible from anywhere, with HTTPS, on custom subdomains. All for the price of a domain renewal.

The thing making this possible: Cloudflare tunnels.

If you're self-hosting Docker containers, this is the cleanest way to get them onto the internet — without opening firewall ports, configuring a static IP, or paying for a VPS just to run a reverse proxy. Here's the exact setup I use.

What Is a Cloudflare Tunnel?

A Cloudflare tunnel creates an outbound-only connection from your machine to Cloudflare's edge network. Your apps don't need an inbound port open. Your IP doesn't need to be static. Cloudflare handles routing, HTTPS, and DNS automatically.

The process: install a small daemon (cloudflared) on your machine, create a tunnel in the Cloudflare dashboard, and map subdomains to your localhost ports. That's it.

What You Need

  • A domain on Cloudflare (DNS management is free — you can transfer any existing domain)
  • Cloudflare Zero Trust account (free tier covers this completely)
  • Docker and Docker Compose on your machine
  • About 20 minutes

Step 1: Create a Cloudflare Zero Trust Account

Go to one.dash.cloudflare.com, sign in, and navigate to Zero Trust. Create a new organization if prompted — the free tier works fine for self-hosting.

Step 2: Create the Tunnel

In the Zero Trust dashboard: Networks > Tunnels > Create a tunnel. Name it whatever you want (I use "homelab"), select "Cloudflared" as the connector type. Cloudflare generates a token — copy it.

Step 3: Add cloudflared to Your Docker Compose

The cleanest approach is running cloudflared as a container alongside your other apps. Add this service to your docker-compose.yml:

Add your token to .env: