Skip to content

Caddy

Caddy is a free, open-source web server that automatically handles HTTPS certificates and configuration. It’s designed for simplicity and security, making it an excellent choice for both development and production environments.

Preparation

Docker network

First, a Docker network should be created. This means that it is then no longer necessary to publish ports for each individual service. Ports 80 and 443 for the proxy manager are then sufficient, as well as others in certain cases if necessary.

Terminal window
sudo docker network create proxy-network

Directory Structure

Terminal window
mkdir caddy
cd caddy
mkdir data config
touch Caddyfile docker-compose.yml

Caddyfile

.../caddy/Caddyfile
{
acme_ca https://acme.zerossl.com/v2/DV90
email mail@hello.com
}
homepage.domain.com {
reverse_proxy homepage:80
}

Example service

Let’s create a simple web server as an example.

Terminal window
mkdir homepage
cd homepage
mkdir html
touch html/index.html
touch docker-compose.yml
.../homepage/html/index.html
<!DOCTYPE html>
<html>
<head>
<title>Homepage</title>
</head>
<body>
<h1>Homepage</h1>
<p>This is a homepage.</p>
</body>
</html>
.../homepage/docker-compose.yml
networks:
proxy-network:
external: true
### SERVICE ###
services:
homepage:
container_name: homepage
image: nginx:latest
restart: unless-stopped
networks:
- proxy-network
security_opt:
- no-new-privileges:true
volumes:
- /html:/usr/share/nginx/html:ro
Terminal window
sudo docker compose up -d

Installation

The web server is already running, but without Caddy it is not accessible. First you have to change back to the caddy directory.

Terminal window
cd [...]/caddy
.../caddy/docker-compose.yml
networks:
proxy-network:
external: true
services:
caddy:
image: caddy
container_name: caddy
restart: unless-stopped
ports:
- 80:80
- 443:443
volumes:
- ./data:/data
- ./config:/config
- ./Caddyfile:/etc/caddy/Caddyfile:ro
networks:
- proxy-network
Terminal window
sudo docker compose up -d

The previously created homepage should now be accessible under homepage.domain.com erreichbar sein.

Access restriction

An access restriction to certain IP addresses can be done in the Caddyfile.

.../caddy/Caddyfile
{
acme_ca https://acme-v02.api.letsencrypt.org/directory
email mail@domain.com
}
(LAN_only) {
@not_local {
not remote_ip 192.168.0.0/16
}
respond @not_local 403
}
homepage.domain.com {
reverse_proxy homepage:80
import LAN_only
}

So only devices from the IP range 192.168.0.0 - 192.168.255.255 are allowed to access the homepage.

Update

Update Caddy using Docker Compose:

Terminal window
sudo docker compose pull
sudo docker compose down
sudo docker compose up -d