Hugo with Docker Compose
Some folks have asked how to properly host a hugo
website using docker stack
and serve it with caddy
. I assume you already have a hugo
site and a domain
name that points to your server IP address.
There are docker containers that make it easy to build a simple development
container, but hugo
as a server is not designed for production use. It’s also
not worth fighting against the development nature of the hugo
server and the
base URL of the site, etc.
Instead we build the site using hugo
and then serve the static files with a
production-ready web server like nginx
. Lastly we securely expose the site to
the internet using caddy
as a reverse proxy.
Setup Caddy#
Caddy is available in the official Ubuntu repositories starting with Ubuntu 24.04 LTS. For most users, installation is as simple as:
sudo apt update
sudo apt install caddy
Enable and start the Caddy service:
sudo systemctl enable --now caddy
Note: For best results, use Ubuntu 24.04 LTS or later. Older versions may require extra steps or a third-party repository.
By default Caddy provides /etc/caddy/Caddyfile
, but it would be cumbersome to
put all your site configurations in one file. Instead, we can create a directory
to hold all our Caddy configurations:
sudo mkdir -p /etc/caddy/Caddyfile.d
Now, edit your main /etc/caddy/Caddyfile
to import all configuration files
from this directory:
import /etc/caddy/Caddyfile.d/*.caddyfile
You can now add individual site or service configs as separate .caddyfile
files in /etc/caddy/Caddyfile.d/
for better organization and modularity.
After adding or changing configs, reload Caddy:
sudo systemctl reload caddy
Using Docker Compose for Hugo and Nginx#
services:
hugo:
image: klakegg/hugo:ext-alpine
container_name: foo-hugo
volumes:
- .:/src
working_dir: /src
nginx:
image: nginx:alpine
container_name: foo-nginx
ports:
- "127.0.0.1:8080:80"
volumes:
- ./public:/usr/share/nginx/html:ro
depends_on:
- hugo
Note that we expose port 80
of the nginx container to port 8080
of the host
machine, but most importantly we limit it to 127.0.0.1
so that when running on
the server it’s not exposed to the outside world, except through Caddy or any
other reverse proxy.
Need an old person to work on your infrastructure? Contact me on
BlueSky or e-mail me at
kris@devrupt.io
.