This an experimental Docker Engine port-mapper that integrates with Cloudflare Zero Trust Tunnels.
Note
This is experimental work based on an unreleased Docker Engine feature. Expect bugs and rough edges.
Create a Cloudflare account, and register (or transfer) a domain to Clouflare.
Then, create an Account API Token:
- Open Cloudflare dashboard, and go to Manage Account > Account API Tokens
- Create a Custom Token with the following permissions: https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/get-started/create-remote-tunnel-api/#create-an-api-token
Create a tunnel through Cloudflare Dashboard, and run a cloudflared container on your server:
$ export CLOUDFLARE_TUNNEL_TOKEN=...
$ docker run -d --restart=always --network host --name cloudflared \
cloudflare/cloudflared:latest \
tunnel --no-autoupdate run --token $CLOUDFLARE_TUNNEL_TOKEN
First, install and configure the portmapper plugin:
$ export CLOUDFLARE_API_TOKEN=...
$ export CLOUDFLARE_ACCOUNT_ID=...
$ docker plugin install --alias cloudflared albinkerouanton006/cloudflared-mapper:latest \
CLOUDFLARE_API_TOKEN=$CLOUDFLARE_API_TOKEN \
CLOUDFLARE_ACCOUNT_ID=$CLOUDFLARE_ACCOUNT_ID
Then, edit your /etc/docker/daemon.json to set the Engine's default-port-mapper:
{
"default-port-mapper": "cloudflared:latest"
}Restart your Engine for that settings to take effect.
You're now fully set up!
HTTP Service Example:
Start a container exposing a webserver:
$ docker run --rm -d -p 80/tcp \
--label "com.cloudflare.portmapper.tunnel_name=docker-cloudflared-mapper - test" \
--label "com.cloudflare.portmapper.hostname=web.aker.dev" \
traefik/whoami
You can access it from anywhere using http://web.aker.dev
Raw TCP Stream Example:
Let's try with a raw TCP port:
$ docker run --rm -d -p 5432/tcp \
--label "com.cloudflare.portmapper.tunnel_name=docker-cloudflared-mapper - test" \
--label "com.cloudflare.portmapper.hostname=db.aker.dev" \
--label "com.cloudflare.portmapper.proto=tcp" \
-e POSTGRES_PASSWORD=mysecretpassword \
-e POSTGRES_USER=admin \
-e POSTGRES_DB=myapp \
postgres:15
You can connect to that PostgreSQL database from anywhere:
# Connect via psql using a container (no local psql required)
$ docker run -it --rm postgres:15 psql -h db.aker.dev -p 5432 -U admin -d myapp
# Password: mysecretpassword- Improve the output of
docker ps - Do not barf out on
MapPortswhen CNAMEs already exist - Fix raw TCP support
- Let the plugin create tunnels and run cloudflared process