SteGriff

Blog

Next & Previous

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 has been going great, so I'll use that.

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:

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:

The disco deployment logs for sg-11

Disco uses Caddy under the hood, so the output is now being hosted by an efficient, dumb webserver.

So simple! 🐵🔧