Tunnel — Public Internet (Docker)
Two services exposed to the public internet via Cloudflare Tunnel, running in Docker. Works on macOS, Linux, and Windows.
Two apps and dynamoip in Docker, exposed to the public internet via Cloudflare Tunnel. Works on macOS, Linux, and Windows — no host networking, no port forwarding, no firewall config.
https://inventory.yourdomain.com [PUBLIC] → localhost:3001
https://dashboard.yourdomain.com [PUBLIC] → localhost:6000How it works
cloudflared (inside the dynamoip container) makes an outbound connection to Cloudflare's edge. All traffic flows through that encrypted tunnel — no inbound ports on the host, no Docker port mappings for public traffic.
Internet → Cloudflare edge → encrypted tunnel → cloudflared (container) → dynamoip proxy → inventory:3001 / dashboard:6000App containers have no exposed ports. Docker's internal network handles service-to-service communication via socat port forwarding inside the dynamoip container.
Prerequisites
- Docker and Docker Compose
- A domain managed by Cloudflare
- A Cloudflare API token with both permissions:
Zone:DNS:EditAccount:Cloudflare Tunnel:Edit
Project structure
tunnel/
├── docker-compose.yml
├── dynamoip.config.json
├── .env.example
├── dynamoip/
│ ├── Dockerfile
│ └── entrypoint.sh
├── inventory/
│ ├── Dockerfile
│ ├── server.js
│ ├── index.html
│ └── package.json
└── dashboard/
├── Dockerfile
├── server.js
├── index.html
└── package.jsonSetup
1. Clone the examples repo
git clone https://github.com/foundanand/dynamoip-examples
cd dynamoip-examples/tunnel2. Copy and fill in .env
cp .env.example .envOpen .env and add your Cloudflare API token:
CF_API_TOKEN=your_cloudflare_api_token_hereNo CF_EMAIL needed — Cloudflare manages the certificate for tunnel mode.
3. Set your domain in config
Open dynamoip.config.json and replace yourdomain.com:
{
"baseDomain": "yourdomain.com",
"tunnel": true,
"domains": {
"inventory": 3001,
"dashboard": 6000
}
}4. Start everything
docker compose up --buildDocker Compose will:
- Build all three images
- Start inventory and dashboard, wait for healthchecks to pass
- Start dynamoip — installs
cloudflared, creates the tunnel, sets CNAME DNS records, and begins proxying
First run takes 20–30 seconds for tunnel creation. Subsequent starts are instant (tunnel credentials cached in the dynamoip-tunnels volume).
5. Open from anywhere
https://inventory.yourdomain.com
https://dashboard.yourdomain.comThese URLs work from any device on any network — phone, laptop, or a colleague across the country.
What you'll see in logs
Mode: Max — Cloudflare Tunnel
✓ cloudflared installed
✓ tunnel created: dynamoip-yourdomain-com
✓ inventory.yourdomain.com [PUBLIC] → localhost:3001
✓ dashboard.yourdomain.com [PUBLIC] → localhost:6000Stopping
docker compose downThe dynamoip-tunnels volume is preserved — tunnel credentials are reused on next start.
To remove the volume and force tunnel recreation:
docker compose down -vNotes
No sudo needed. Max mode doesn't bind to ports 80/443 — cloudflared makes outbound connections only.
Cross-platform. Unlike the LAN example (which uses network_mode: host on Linux), this example works identically on macOS Docker Desktop, Linux, and Windows Docker Desktop.
Security. These services are on the public internet. Ensure they have authentication before sharing the URLs.