Using Caddy to replace Traefik and Nginx
In my pevious post I explained how to use Traefik2 to get a site up and running. There is an alternative with much less configuration called Caddy that allows for the same features as Treafik2 with its caddy_docker_proxy plugin.
Setup the caddy reverse proxy
Similar to Traefik, the external Network has to be defined with: docker network create caddy
To get the Docker Reverse Proxy (think Traefik) up and running I have prepared following docker-compose
file:
docker-compose caddy-docker-proxy
version: "3.7"
services:
caddy:
image: lucaslorentz/caddy-docker-proxy:ci-alpine
ports:
- 8080:80 # change to 80 in Production
- 8443:443 #change to 443 in Production
environment:
- CADDY_INGRESS_NETWORKS=caddy
networks:
- caddy
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- caddy_data:/data
- /var/static_files/:/srv/static/ # Drop all your Static files here to be served by Caddy
restart: unless-stopped
networks:
caddy:
external: true
volumes:
caddy_data: {}
From here it is just docker-compose up -d
and you are good. You might have noticed the /var_static_files/
path at the volumes
directive. Here, all Files to be served by Caddy have to be stored. You can change the paths to your convenience.
Configure the service
Like Traefik2 the configuration is done via flags at the container level:
docker-compose example-for-django
version: '3'
services:
postgres:
image: docker.io/postgres:14
environment:
POSTGRES_USER: django_db
POSTGRES_PASSWORD: ${django_db_pw}
volumes:
- database:/var/lib/postgresql/data
networks:
- internal
web:
build: .
container_name: django_webserver
volumes:
- /var/static_files/django_webserver/static:/static-files # check that you use a diffrent folder for each of your projects
- /var/static_files/django_webserver/media:/media-volume
labels:
caddy: localhost
caddy.handle_path_0: /static/*
caddy.handle_path_0.0_root: "* /srv/static/django_webserver/static/" # These have to correspond with the caddy file
caddy.handle_path_0.1_file_server: ""
caddy.handle_path_1: /media/*
caddy.handle_path_1.0_root: "* /srv/static/django_webserver/media/"
caddy.handle_path_1.1_file_server: ""
caddy.reverse_proxy: "{{ upstreams 8000 }}"
depends_on:
- postgres
networks:
- caddy
- internal
networks:
caddy:
external: True
internal:
external: False
volumes:
database:
The flags will be handed over to caddy and a config will be generated from them. The numbers represent the ordering of the directives. To check the resulting Caddyfile you can docker exec <caddy_container_name> cat /config/caddy/Caddyfile.autosave
:
localhost {
handle_path /media/* {
root * /srv/static/django_webserver/static/
file_server
}
handle_path /static/* {
root * /srv/static/django_webserver/media/
file_server
}
reverse_proxy 172.19.0.3:8000
}
Conclusion
With this configuration, we get static file serving. Previously we needed nginx for that. We get HTTPS Redirect by default. We get a Lets Encrypt Certificate (for localhost caddy will provide a certificate). But with much less configuration than needed for Traefik2. Configuration via labels feels a bit weird at time, but much easier than Traefik2. The static file handling feels a bit nasty too, since they are leaving the compose context; in the end they are all stored on the same machine, or storage, or something — the CloudAge… — so I guess it’s not a problem.
If you have suggestions or spotted an error, email me via bithive@bithive.space