The most boring thing about setting up a web server on a new cloud server for me is the initial configuration. From installing and configuring nginx to setting up Let's Encrypt with certbot1. There are so many steps involved and so much boilerplate code in the config2.
This has changed now that Caddy exists. It is an open source web server written in Go that has built-in Let's Encrypt support. And it has the simplest config file format I've ever seen for a web server:
Built with Go, it is available as a standalone binary. Packages for popular package managers are available. And there is also a ready-to-use Docker image.
Docker Compose
Usage withHere's a basic docker-compose file that runs Caddy:
# ingress/docker-compose.yml
version: '3.7'
services:
caddy:
image: caddy
restart: unless-stopped
ports:
- '80:80'
- '443:443'
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- ./public:/var/www/html
- caddy_data:/data
- caddy_config:/config
volumes:
caddy_data:
caddy_config:
Now when I run docker-compose up -d
, Caddy starts up and:
- Listens to port 80 and 443.
- Obtains a Let's Encrypt certificate for domain
vps.dt.in.th
. - Sets up HTTP to HTTPS redirection on port 80.
- Serves files from
public
folder (mounted to/var/www/html
inside container). - Proxies requests to
/api/
to theapi
hostname.
Configuring Docker networks for reverse proxy
Now, other projects I run on this VPS have their own docker-compose
file. We need to make the container join Caddy's Docker network for Caddy to be able to look it up via hostname.
This can be done by joining an external network and setting a network alias for that network.
# api/docker-compose.yml
version: '3.8'
services:
server:
restart: unless-stopped
build: .
networks:
default:
ingress:
aliases:
- api
networks:
ingress:
external: true
name: ingress_default
Footnotes
A commenter recommended me try out acme.sh should I need to use nginx again. ↩
Boilerplate include but not limited to:
- Creating a file in
sites-available
. - Setting up a server block.
- Setting up redirect from HTTP to HTTPS.
- Setting up the path to the SSL certificate file.
- Setting up HTTP headers for the reverse proxy, such as
Host
,X-Real-IP
,X-Forwarded-For
. - Setting up WebSocket support.
- Symlinking the file to
sites-enabled
.
- Creating a file in