Raspberry Pi with Cloudflare Tunnel
This example runs dpl on a Raspberry Pi at home and publishes a static site through a Cloudflare Tunnel. The router forwards no ports and the Pi needs no public address. Cloudflare terminates TLS and reaches nginx through the connector container.
Four units: tunnel (cloudflare-tunnel), nginx (http-server), site-domain (domain), and site (a static app).
Prerequisites
Section titled “Prerequisites”- A 64-bit Raspberry Pi (3 or newer) with Raspberry Pi OS Lite 64-bit. The current release is based on Debian 13 (trixie) and ships Podman 5.4, which meets dpl’s Podman 4.8+ requirement.
- A domain whose DNS is hosted on Cloudflare. The free plan is enough.
Install Podman and dpl as root:
sudo -iapt install podmancurl -fsSL https://dpl.cesbo.com/install.sh | shCloudflare Tunnel
Section titled “Cloudflare Tunnel”In the Zero Trust dashboard open Networks, then Tunnels. Create a tunnel with the Cloudflared connector and copy its token. Store the token as a secret:
dpl secret create cf-tunnel-tokenCreate /opt/dpl/conf/tunnel.yaml:
type: cloudflare-tunnelsecret: cf-tunnel-tokenDeploy it:
dpl deploy tunnelThe dashboard shows the connector as healthy once it connects. In the tunnel settings add a Public Hostname: pi.example.com with service http://dpl--nginx:80. nginx is the name of the http-server unit below. Cloudflare creates the DNS record.
HTTP server
Section titled “HTTP server”Create /opt/dpl/conf/nginx.yaml:
type: http-serverhttp_port: falseNothing is published on the Pi. nginx is reachable only on the dpl network, where the connector finds it as dpl--nginx.
Domain
Section titled “Domain”Create /opt/dpl/conf/site-domain.yaml:
type: domainserver: nginxhosts: ["pi.example.com"]proxy: type: cloudflare-tunnelroutes: - kind: serve_files location: / root: ${site:export}proxy.type: cloudflare-tunnel makes nginx trust the connector and log the visitor’s IP from CF-Connecting-IP. It requires http_port: false on the http-server. The domain deploy refuses otherwise.
Any folder with an index.html will do. Create /opt/dpl/conf/site.yaml:
type: appimage: docker.io/library/alpine:3builds: - files: ["*"]exports: - source: /app path: /There is no build script and no runtime. dpl copies the archive into the image and exports it for nginx. For a generated site see Static site.
Deploy:
tar -czf /tmp/site.tar.gz -C path/to/site .dpl deploy site /tmp/site.tar.gzThe app deploy also deploys the domain and starts nginx. Open https://pi.example.com.
dpl inspect tunneldpl inspect nginxtail /opt/dpl/state/tunnel/log/runtime.logThe tunnel log shows Registered tunnel connection lines once the connector is online. If the dashboard reports the tunnel as down, that log is the place to look.