Building and serving gatsbyjs with docker
September 26, 2020
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 buildFROM gatsbyjs/gatsbyCOPY --from=build /app/public /pub
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 /appCOPY package.json package-lock.json ./RUN npm ciCOPY . ./RUN npm run buildRUN mv /app/public /usr/share/nginx/html
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 builderWORKDIR /appCOPY package.json package-lock.json ./RUN npm ciCOPY . ./RUN npm run buildFROM nginx:alpineCOPY --from=builder /app/public /usr/share/nginx/html
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.