Konnor's Blog

Setting up a Gatsby project with Docker

January 16, 2020

Quick start

First create a new directory (or use an existing directory, this method will NOT create a new git directory for you)

mkdir my-new-gatsby-project
cd my-new-gatsby-project
touch Dockerfile.dev docker-compose.yml package.json yarn.lock

Next step, we must fill in the package.json file.

There are 2 ways to handle this. You can either run yarn init or npm init if you have yarn / npm installed on your computer.

However, if you do not have npm / yarn it is fine. The package.json just needs some values to get Docker to run appropriately. Run the command below to fill in a temporary package.json file.

// ./package.json
{
"name": "docker-with-gatsby",
"description": "An example repo for setting up Gatsby with Docker",
"version": "1.0.0",
"main": "index.js",
"repository": "git@github.com:ParamagicDev/docker-with-gatsby.git",
"author": "paramagicdev <konnor5456@gmail.com>",
"license": "MIT",
"private": true
}

Then, we’ll fill in the Dockerfile.dev with the following values.

# ./Dockerfile.dev
FROM node:12.14.0-slim
RUN apt update && apt upgrade -y && \
apt install gcc g++ make python git libc6-dev build-essential libpng-dev \
libjpeg-dev libvips-dev libvips musl-dev node-gyp pngquant webp -y
RUN yarn global add gatsby-cli
# The port gatsby runs on
EXPOSE 8000
WORKDIR /myapp
COPY ./package.json /myapp
COPY ./yarn.lock /myapp
RUN yarn install && yarn cache clean
COPY . /myapp
CMD ["gatsby", "develop", "-H", "0.0.0.0" ]

After finishing with the Dockerfile, well build a docker-compose.yml to bring everything together. Technically, you could run the whole project without docker-compose but it makes commands a lot more verbose by having to include volumes and ports and various other things. Docker-compose simply streamlines the process.

# ./docker-compose.yml
version: "3"
services:
web:
build:
context: .
dockerfile: Dockerfile.dev
ports:
- "8000:8000"
volumes:
- /myapp/node_modules
- .:/myapp
environment:
- NODE_ENV=development
- GATSBY_WEBPACK_PUBLICPATH=/

Your file structure should at least contain the following when running tree .:

.
├── docker-compose.yml
├── Dockerfile.dev
├── package.json
└── yarn.lock

Reference Repository Commit

After copying the contents of the files above into docker-compose.yml & Dockerfile.dev respectively, then run the following commands:

# Unfortunately, yarn does not have a similar command to npx
docker-compose run --rm web npx degit https://github.com/gatsbyjs/gatsby-starter-default . --force

Your gatsby project is now ready to dev on! Simply run the following:

docker-compose up --build

Navigate to localhost:8000 in your web browser, and your project should be running!

Additional info

The docker-compose up --build command is only needed when rebuilding, IE: Adding packages, removing packages, etc.

If you have only changed files that do not need a full rebuild, you can run subsequent instances of docker-compose with simple docker-compose up

Using yarn

If you are planning on using yarn instead of npm like I have above, make sure to remove the package-lock.json generated by degit when pulling in the gatsby starter

rm package-lock.json

Otherwise, when installing packages yarn will complain about conflicting package managers.

Updating packages

To update packages you can either do a straight upgrade or an interactive upgrade as follows.

# Interactive upgrade
docker-compose run --rm web yarn upgrade-interactive
# Non-interactive
docker-compose run --rm web yarn upgrade

If you’re not currently inside a git repo and would like to use git, make sure to run a git init from the root directory

Bonus content - Adding Docz

Alright, now when I initially tried this I did not realize Docz had released a v2. Make sure you are targetting v2. There are 2 different ways to create a project with Docz.

  1. The first way is similar to create-react-app. If you have node installed, you can run the following command:
npx create-docz-app my-docz-app
# or
yarn create docz-app my-docz-app
  1. The alternative way is if you followed the steps above to create a barebones Gatsby project.

After following the steps above, your project should look like this:

Gatsby Initial Setup

tree .
.
├── docker-compose.yml
├── Dockerfile.dev
├── gatsby-browser.js
├── gatsby-config.js
├── gatsby-node.js
├── gatsby-ssr.js
├── LICENSE
├── node_modules
├── package.json
├── package-lock.json
├── public
├── README.md
├── src
└── yarn.lock

Next, run the following:

yarn add docz

There are many ways to use the new docz but because the project I’m making is specifically for documentation and won’t be using anything else, all my .mdx files will be in the src/pages directory because this is how Gatsby provides routing.

Additionally, you must add the gatsby-theme-doz plugin in both your ./gatsby-config.js and to your ./package.json file like so:

docker-compose run --rm web yarn add gatsby-theme-docz

Then, you must add it to your ./gatsby-config.js file.

module.exports = {
plugins: ["gatsby-theme-docz"],
}

Hope this helped you with Gatsby, Docz, or general Docker setup! Good luck out there!

Issues

When running the docker process, it runs as root. As a result, on Linux the files created by Degit will be owned by the root user. Run the following to fix any permissions errors from the root directory:

sudo chown -R "$USER":"$USER" .

Originally, this tutorial used an Alpine based docker images. Theres a lot of compatibility issues with the image processing library ‘sharp’. As a result, I decided to use a Debian based Docker image for an easier build process.

I also ran into issues with using Node 13.6.0. It kept saying sharp was not self registering. There appears to be many compatibility issues with sharp so I wanted to keep this as close to my host machine as possible.

Links

Gatsby

Gatsby Home


[Gatsby Starter Github page](https://github.com/gatsbyjs/gatsby-starter-default)

Degit

I actually learned about Degit when browsing the Svelte documentation


Degit Source Code


Docz

Docz Homepage


[Docz Getting Started](https://www.docz.site/docs/getting-started)

Written by Konnor Rogers who currently works as a paramedic looking to transition into becoming a full time software developer. You should follow him on Twitter