Secure Docker services with Caddy on a VPS
Deploying containerized web services on a virtual private server requires a reliable reverse proxy that handles automatic TLS certificates without complex maintenance. This tutorial assumes you already have Docker installed on your VPS, and you already have a domain configured.
Setting up the core network and Caddy
To allow multiple separate Docker Compose stacks to communicate securely through a single reverse proxy, create an external Docker network named ingress by running this command:
mkdir -p /srv/core-and-shared/caddy
cd /srv/core-and-shared/caddy
Next, create the directory structure for Caddy and place this code in /srv/core-and-shared/caddy/compose.yaml:
services:
caddy:
image: caddy:2-alpine
container_name: caddy
restart: unless-stopped
ports:
- "80:80"
- "443:443"
- "443:443/udp"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- caddy-data:/data
- caddy-config:/config
networks:
- caddy
volumes:
caddy-data:
caddy-config:
networks:
caddy:
name: caddy
Configuring the Caddyfile and cloudflare tunnel
Put this code in /srv/core-and-shared/caddy/Caddyfile, replacing the example domain with your own. The test configuration uses test.lulzcasz.dev, and you will need to point your domain to your VPS:
<domain> {
respond "Hello World!"
}
If you prefer running your proxy behind a secure tunnel rather than opening direct inbound firewall ports, you can integrate a Cloudflare tunnel by creating /srv/core-and-shared/cloudflared/compose.yaml:
docker compose up -d
Testing the deployment
Once your containers are running, verify that everything responds correctly over HTTPS by running:
curl https://<domain>
For alternative architectures, you can review how to configure Caddy on a local server.
Use Caddy as a reverse proxy on a local server
Learn how to configure Caddy as a local reverse proxy using Docker and Docker Compose, complete with automatic routing and Cloudflare Tunnel integration.
To scale containerized workloads into full-stack deployments, check out our guide on production hosting.
Deploy Django in production with Docker