origin

Project Setup

Install create-react-app

1
npm install -g create-react-app@1.5.2

Creating a new app

1
2
create-react-app docker-app
cd docker-app

Docker

Add a Dockerfile to the project root

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# base image
FROM node:9.6.1

# set working directory
RUN mkdir /usr/src/app
WORKDIR /usr/src/app

# add `/usr/src/app/node_modules/.bin` to $PATH
ENV PATH /usr/src/app/node_modules/.bin:$PATH

# install and cache app dependencies
COPY package.json /usr/src/app/package.json
RUN npm install
RUN npm install react-scripts@1.1.1 -g

# start app
CMP ["npm", "start"]

Add a .dockerignore to speed up the Docker build process as our local dependencies will not be sent to the Docker Daemon

1
node_modules

Build and tag the Docker Image

1
docker build -t docker-app:1.0.0

Then spin up the container once the image is built.

1
docker run -it -v ${PWD}:/usr/src/app -v /usr/src/app/node_modules -p 3000:3000 --rm docker-app:1.0.0

Now you can visit your app http://localhost:3000

Docker Compose

Add a docker-compose.yml to the project root.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
version: '3.3'

services:
docker-app:
container_name: docker-app
build:
context: .
dockerfile: Dockerfile
volumnes:
- '.:/usr/src/app'
- '/usr/src/app/node_modules'
ports:
- '3000:3000'
environment:
- NODE_ENV=development

Take note of the volumes. Without the data volume /usr/src/app/node_modules, the node_modules directory would be overwritten by the mounting of the host directory at runtime that were installed when the container was built.

BUild the image and fire up the container

1
docker-compose up -d --build

Ensure the app is running in the browser.

Bring down the container before moving on

1
docker-compose stop

Production

Let’s create a seperate Dockerfile for use in production called Dockerfile-prod

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# build environment
FROM node:9.6.1 as builder
RUN mkdir /usr/src/app
WORKDIR /usr/src/app
ENV PATH /usr/src/app/node_moudles/.bin:$PATH
COPY package.json /usr/src/app/package.json
RUN npm install
RUN npm install react-scripts@1.1.1 -g
COPY . /usr/src/app
RUN npm run build

# production environment
FROM nginx:1.13.9-alpine
COPY --from=builder /usr/src/app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx","-g",'deamon off;"]

Using the production Dockerfile, build and tag the Docker Image:

1
docker build -f Dockerfile-prod -t docker-app-prod .

Spin up the container

1
docker run -it -p 80:80 --rm docker-app-prod

Add Prod Docker Compose as `docker-compose-prod.yml’

1
2
3
4
5
6
7
8
9
10
version: "3.3"

services:
docker-app-prod:
container_name: docker-app-prod
build:
context: .
dockerfile: Dockerfile-prod
prots:
- "80:80"

Fire up the container

1
docker-compose -f docker-compose-prod.yml up -d --build