Developing a Gatsby Site with Docker

Getting Gatsby (also GatsbyJS) installed and running can be a challenge. With older versions of Ubuntu I have fought extensively with Node package versions. Docker seems to be a natural solution. This post shows how to build and run a simple Docker image for serving a development Gatsby site.

Infrastructure

A Makefile will provide for quicker and easier experimentation.

build:
	docker build -t gatsby-develop .

develop:
	docker run -it -p 8000:8000 -v ${PWD}:/site gatsby-develop

There are two targets which can be run as follows:

# Build the Docker image.
make build
# Run the Docker image.
make develop

Helper Script

We’ll use a short BASH script to install dependencies and launch the site.

#!/bin/bash

# Install dependencies.
yarn install
# Serve site.
gatsby develop -H 0.0.0.0

When first run the yarn command might take some time to gather all of the dependencies. However, they will be installed into a node_modules folder in a shared volume, so this delay will only be incurred the first time that a site is served.

Ubuntu Base Image

I’ve got Ubuntu 23.04 running on my desktop. Installing Gatsby was painless, so the ubuntu:23.04 base image seemed a natural place to start.

FROM ubuntu:23.04

WORKDIR /site

COPY setup.sh /usr/bin

RUN apt-get update -y && \
    apt-get install -y npm && \
    npm install -g yarn gatsby-cli && \
    chmod u+x /usr/bin/setup.sh

ENTRYPOINT /usr/bin/setup.sh

Nothing very fancy happening there:

  1. make a folder on which to mount the site content;
  2. copy the setup script;
  3. update the APT package list;
  4. install NPM;
  5. install Yarn and the Gatsby CLI; and
  6. make the setup script executable and run it.

Node Base Image

But perhaps a full Ubuntu system is excessive? How about a Node base image? The version of Node on my desktop is 18.13.0, so the node:18.13.0 image is a likely candidate. I also tried node:18.13.0-slim as a lightweight alternative.

FROM node:18.13.0-slim

WORKDIR /site

COPY setup.sh /usr/bin

RUN npm install -g gatsby-cli && \
    chmod u+x /usr/bin/setup.sh

ENTRYPOINT /usr/bin/setup.sh

Essentially the same things happening, except there’s no need to mess around with APT or install NPM and Yarn.

Image Sizes

How do the image sizes compare?

  • ubuntu:23.04 — 964.5 MB
  • node:18.13.0 — 1078.3 MB
  • node:18.13.0-slim — 327.8 MB

Somewhat surprisingly the full Node image is larger than the Ubuntu image. But the slimmed down Node image is substantially smaller than either of those.

Test Site

Let’s test this out using a sample Gatsby site.

git clone git@github.com:gatsbyjs/gatsby-starter-default.git
cd gatsby-starter-default

Now launch the Docker image to serve the site.

docker run -it -p 8000:8000 -v ${PWD}:/site --name gatsby datawookie/gatsby:latest

The -it options are not strictly required, but I find them useful because it means that I can stop the process with Ctrl-c. You also don’t need to provide a --name argument, but a named container is easier to reference (see below).

I’m using a pre-built version of the image from here. You can grab the underlying code here.

Visiting http://127.0.0.1:8000/ yields the test site (screenshot below).

Landing page of Gatsby test site.

If you want to build a production version of the site, then pass the build command.

docker run -v ${PWD}:/site datawookie/gatsby:latest build

The site files will be dumped to a public directory. You can then serve the site (you’ll find it at http://127.0.0.1:9000/).

docker run -p 9000:9000 -v ${PWD}:/site --name gatsby datawookie/gatsby:latest serve

Debugging

First launch a container with a BASH shell.

docker run -it -v ${PWD}:/site --entrypoint /bin/bash datawookie/gatsby:latest

That will launch a BASH shell in the container with root user.

Compiling Typescript

Running the Typescript compiler will allow you to see any warnings and errors.

yarn tsc

Running Tests

If there are any tests then these can also be run.

yarn test