DEV Community

Jonathan
Jonathan

Posted on • Originally published at jonathanborg.net

Building and serving gatsbyjs with docker

On a recent project I have been working on, I had to find a way to host a gatsbyjs project in a docker container.
After a quick search for gatsbyjs docker, most of the result pointed me to the fact that gatsbyjs have official docker images,
but when using it like shown in the README

FROM gatsbyjs/gatsby:onbuild as build

FROM gatsbyjs/gatsby
COPY --from=build /app/public /pub
Enter fullscreen mode Exit fullscreen mode

I could not get it to work, after searching through the issues i found out that the docker images needs to be updated but its still open so i decided to take matters into my own hands.

Multistage docker builds

Docker has this awesome feature called multistage build which allows us to basicly structure our dockerfile
in a way to minimize the size of the final image. A traditional dockerfile would look something like this

FROM node:14.11.0
#
# Install and setup nginx to serve static files, removed for brevity.
#
WORKDIR /app

COPY package.json package-lock.json ./
RUN npm ci

COPY . ./
RUN npm run build

RUN mv /app/public /usr/share/nginx/html

Enter fullscreen mode Exit fullscreen mode

this would work, but you see that FROM node:14.11.0 line at the top of the Dockerfile, that means that the final image will have node included, and all the dependencies that the application needs to build.
there is a better way.

Enter multistage

FROM node:14.11.0 AS builder
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
COPY . ./
RUN npm run build

FROM nginx:alpine
COPY --from=builder /app/public /usr/share/nginx/html
Enter fullscreen mode Exit fullscreen mode

As you can see it starts of similarly,we have one stage that uses the node:14.11.0 image, it sets everything up and builds the public folder with the generated gatsby site,
but at the end of the file we have a new FROM nginx:alpine and we then copy in only the public folder, This means that our final docker image will only contain our finished built site, and the bare minimun nginx to serve those files.

Top comments (0)