Containerized development is hot ๐ฅ What makes these tools so popular? From my experience, containers:
- Make complex local environments quick and easy to spin up
- Allow for specific versioning of languages and packages to coexist locally
- Provide an easy tool to ship code for pipeline integration and deployment
- Help create a consistent work environment across developers
Docker has taken the spotlight for creating development containers. This tutorial will show you how to dockerize a project created with Create React App.
Prerequisites
In order to go through this tutorial, you should have node (LTS version if you're uncertain) and docker installed. The links just listed should work for you, but feel free to use Homebrew or installer you prefer.
Project Startup
If you don't have a CRA project yet, use npm
to create a new one using the npx
command:
npx create-react-app my-project
Move into your project:
cd my-project
Start up and check out your app:
yarn start
It soon should be running at http://localhost:3000. When you've had your fun exploring, turn off the server when with ctrl+c
and get ready to start dockerizing ๐ค
Dockerize!
New docker images are built on a base image and ours will be no different. Docker hub contains a multitude of images. It is probably no surprise that we will be using a node docker image as our base (we'll use 14.15.1
which is LTS at the time of writing).
To specify this docker image and other configuration, create the file Dockerfile
in the root of your project and add the following:
# pull official base image
FROM node:lts-alpine
# set working directory
WORKDIR /app
# add `/app/node_modules/.bin` to $PATH
ENV PATH /app/node_modules/.bin:$PATH
# copies package.json and package-lock.json
COPY package*.json ./
# installs app dependencies
RUN npm install
RUN npm install react-scripts -g
# add app contents to the container
COPY . ./
# start app
CMD ["npm", "start"]
Let's break this down line by line
FROM node:lts-alpine
This line tells docker what base image to use. We want to use the latest stable (LTS stands for long term stable) version of node. Alpine is a distribution of linux that is designed for security, simplicity, and resource efficiency. It is a common choice for docker images because of this.WORKDIR /app
It's good practice to chose a working directory to enter into. If you don't, docker will copy all the contents into the root of the image. If there is namespace clashes, there may be
Also, create a .dockerignore
file in the root of your project with the following content:
node_modules
build
.dockerignore
Dockerfile
Dockerfile.prod
This makes sure not to copy any unnecessary files to our docker image.
Start Up Docker
First, we need to build the docker image:
docker build . -t local-react
The -t local-react
is a tag to easily reference our docker container later. You can change local-react
to whatever name you want, just make sure you change the next script as well!
You should see the steps from the above Dockerfile
run. Then we can start up our docker server with this command:
docker run \
-it \
--rm \
-v ${PWD}:/app \
-v /app/node_modules \
-p 3000:3000 \
local-react
Let's go through what's happening here line by line
docker run
starts up the docker container-it
runs the docker container in interactive mode so that the container remains open after it starts. As of react-scripts v3.4.1 this is now required).-v ${PWD}:/app
creates a volume of your current working directory into the app directory. This way, when changes are made locally, they will be reflected in docker-v /app/node_modules
is a workaround to ensure that we use thenode_modules
in the docker container rather than thenode_modules
locally-p 3000:3000
exposes the docker port 3000 on your localhost so you can view the app runninglocal-react
is the tag of the container we built
Boom ๐ With any luck you should be up and running!