Running Cloudflared as a self-hosted service using Docker
Cloudflared can be easily spun up as a service by self-hosting using Docker. By running Cloudflared as a service, users eliminate the need to manually start up and monitor their Cloudflare tunnels.
Establish the Docker network
In order for Cloudflared to properly assign any self-hosted application that also runs in Docker to an existing tunnel, both Cloudflared and the application must exist in the same Docker network. For example, if we want to self-host Portainer on a subdomain e.g. portainer.mydomain.com via a Cloudflare tunnel, then the Docker compose file should contain a declared network:
services:
portainer:
image: portainer/portainer-ce:latest
container_name: homelab-portainer
restart: always
ports:
- 8000:8000
- 3000:9000
volumes:
- portainer_data:/data
- /var/run/docker.sock:/var/run/docker.sock
networks:
- homelab-net # declare the network to be used for all applications
volumes:
portainer_data:
networks:
homelab-net:
driver: bridge
name: homelab-net # define the network
In the Docker Compose file for the Cloudflared service, we would have the same set up for the Docker network:
services:
cloudflared:
image: cloudflare/cloudflared:latest
container_name: homelab-cloudflared
restart: unless-stopped
volumes:
- ${CLOUDFLARED_PATH}:/etc/cloudflared
command: tunnel --config /etc/cloudflared/config.yaml run
networks:
- homelab-net # declare the network to be used for all applications
networks:
homelab-net:
driver: bridge
name: homelab-net # define the network
This is mandatory to enable the Cloudflared container to communicate and reach any application to assign it to a tunnel.
Docker Compose configuration
Below is the Docker Compose file for running Cloudflared:
services:
cloudflared:
image: cloudflare/cloudflared:latest
container_name: homelab-cloudflared
restart: unless-stopped
volumes:
- ${CLOUDFLARED_PATH}:/etc/cloudflared
command: tunnel --config /etc/cloudflared/config.yaml run
networks:
- homelab-net
networks:
homelab-net:
driver: bridge
name: homelab-net
The path of the .cloudflared directory on the server (host machine) should be declared in the .env file under CLOUDFLARED_PATH.
Updating the tunnel config
Initially the user learns to run Cloudflare tunnels manually where all references to the Cloudflared directory path and the service refer to what’s true for the server. Therefore the configuration must be updated to look for the paths and services that run inside the Docker container. When mounting the CLOUDFLARED_PATH as a volume inside the container, the following files should be present: <tunnel-ID>.json, config.yaml, and cert.pem:
<tunnel-ID>.jsonis the credentials file for the tunnel itself.config.yamlcontains the configuration for whathostnameand accompanyingservicesare to be exposed to the internet via the tunnel.cert.pemis the certificate created after successful authentication for the server’s Cloudflared instance, allowing it to manage tunnels.
An example of the config.yaml can be found in cloudflared-example directory. The certificate and credentials file are auto-generated when authenticating and creating a tunnel respectively.
Starting the Cloudflared container
Once the Cloudflared configuration file has been updated to match the same path and ports as what’s described in the Docker Compose file, the container can be started:
docker compose -f compose.cloudflared.yaml up -d
or using the start script provided in this repository:
./start cfd