Host a generated static site with docker or disco
Netlify have stuffed us with their new pricing structure and I need to move all my Jekyll and 11ty sites off there. My new VPS, set up with
Whatever static site generator (SSG) you use (Jekyll, 11ty, Hugo, Gatsby, or another) this guide should be adaptable for you.
I forgot that Disco has first class support for hosting a Static Site Generator (d’oh) so first, a little tangent into a universal solution with pure docker…
Two-stage dockerfile to build and host an SSG site
If you ask an assistant about this, it may suggest a wasteful strat where you host the production blog with eleventy --serve or npx serve ./_site. These are bad ideas.
You want to compile the site into static output and then host that as cost-effectively as possible, using something simple, dumb, and made for the job, like nginx or Caddy.
You can have a node build stage and then an nginx host stage:
# Build stage
FROM node:20-alpine AS build
WORKDIR /app
COPY ./package.json .
COPY ./package-lock.json .
RUN npm ci
COPY . .
RUN npm run build
# Host stage
FROM nginx:alpine
COPY --from=build /app/build /usr/share/nginx/html
EXPOSE 80
A few things to note:
- My 11ty config outputs to
buildbut yours might go to_siteordist. - The “new” default hosting directory for nginx at time of writing is
/usr/share/nginx/htmlas above. You can change this with nginx config. Other versions might use a different default.
This general approach should work everywhere that can run a dockerfile.
On disco you don’t need to do that
Check out the disco docs for static site generators. Create a disco.json file like this one:
{
"version": "1.0",
"services": {
"web": {
"type": "generator",
"publicPath": "build"
}
}
}
Then you only need the first half (the build stage) from the dockerfile.
# Build stage
FROM node:20-alpine AS build
WORKDIR /app
COPY ./package.json .
COPY ./package-lock.json .
RUN npm ci
COPY . .
RUN npm run build
# Disco will host the `build` folder
It builds using the dockerfile, and hosts the static output for you:

Disco uses Caddy under the hood, so the output is now being hosted by an efficient, dumb webserver.
So simple! 🐵🔧