Install Caddy reverse proxy via Docker
Why caddy?
- Easy to configure: Caddy’s configuration language is simple and easy to use.
- Automatic HTTPS: Caddy is designed to make HTTPS as easy as possible. Caddy will automatically obtain and renew SSL certificates for your sites using Let’s Encrypt no config or work is needed.
- Lightweight: Caddy is extremely lightweight and fast. Caddy can handle a lot of traffic while using minimal resources. yes even less than Nginx in some instances, and I say that as a lifelong Nginx fan.
- Security: Caddy is designed with security in mind. It uses secure defaults like HTTPS and hsts etc by default.
- Extensibility: Caddy has a plugin system that allows you to extend its functionality. There are many plugins available on their site.
- Reverse proxy: Caddy’s built-in reverse proxy functionality is powerful and easy to use. It supports load balancing, URL rewriting, and other advanced features.
These are just some of Caddy’s amazing features!
Install Docker and Docker Compose if you haven’t already. View our docker guide here & our docker rootless guide here.
Scenario: you have a new app you wrote or installed via docker called mycoolapp you want to allow the outside world to connect to this but have a reverse proxy in the middle so you can apply e.g. rate limiting, ssl cert, basic auth etc.
Create a new directory for your Caddy configuration and change to it:
mkdir caddy
cd caddy
I prefer to make these in /opt/docker so for me its:
mkdir -p /opt/docker/caddy
cd /opt/docker/caddy
This is purely personal preference and you are the one to decide on this location.
Create a file called Caddyfile
in this directory with the following contents:
example.com {
reverse_proxy mycoolapp:80
}
If you don’t want to get an SSL cert for this domain automatically for free then use this
example.com:80 {
reverse_proxy mycoolapp:80
}
The above configuration tells Caddy to proxy all requests to example.com
to a web server running on port 80 at the hostname mycoolapp
. Change these values to match your own configuration.
Create a docker-compose.yml
file in the same directory with the following contents:
version: '3'
services:
caddy:
image: caddy
container_name: caddy
ports:
- "80:80"
- "443:443"
environment:
- ACME_AGREE=true
restart: unless-stopped
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- ./caddy_data:/data
- ./caddy_config:/config
networks:
- public
networks:
public:
external: true
This configuration sets up a Docker container running Caddy with the Caddyfile
we created earlier mounted as a volume along with two other folders needed by caddy. the env variable of acme_agree lets you accept the letsencrypt EULA.
You need to create a new network for caddy and for any other containers you want accessible via this reverse proxy.
docker network create public
docker connect public caddy
docker connect mycoolapp
The first command will create a new network named public, the second command will connect your caddy to the public network you just created and the third command will connect your app named mycoolapp to this network also so caddy can access it.
Start the Caddy container via the following command which will start the Caddy container in detached mode, meaning it will run in the background. and it will show you the logs from caddy so you can make sure there were no errors. hit CTRL + C to close the logs.
docker compose up -d && docker compose logs -f
Open a web browser and navigate to http://example.com
. You should see the content served by the web server running on port 80 at the mycoolapp
hostname.