Docker: Dockerized NodeJS-React development

This post is going to cover how to quickly setup a NodeJS development environment with docker containers.

You’ll need to install the following:

Our dockerized development environment will have the following containers:

Our development folder will contain the folders /server and /client.

We’ll start with creating individual Dockerfiles in both our server and client folders.

In our /server folder we’ll create the file - Dockerfile using the node8 image

FROM node:8

Running following will build our image

docker build .

dockerbuild

Next we need to expand this to include installing the node modules our app requires.

FROM node:8

WORKDIR /usr/src

ENV PATH /usr/src/node_modules/.bin:$PATH

RUN npm install --global nodemon

ADD package.json /usr/src/package.json
RUN npm install

CMD ["nodemon","--legacy-watch"]

So, in the above we are setting our work directory within the container to be /usr/src. Adding node_modules to path and then install nodemon globally. After our node modules have installed we’ll run nodemon (In order to get it recompiling on my setup I had to use the –legacy-watch flag)

We’ll now put the following into our Dockerfile in the client folder

FROM node:8

WORKDIR /usr/src

ENV PATH /usr/src/node_modules/.bin:$PATH

ADD package.json /usr/src/package.json
RUN npm install
RUN npm install react-scripts@0.9.5 -g

CMD ["npm", "start"]

This is quite similar to our server Dockerfile except that we install react-scripts and use npm start.

package.json

  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject" 
  },

As our client package.json has above script entries. When ‘npm start’ is run by our Dockerfile , the development server will start up.

Next we will create our Docker-compose file which we will use to configure and run our containers.

version: "2"
services:

  newsservice:
    container_name: newsservice
    build: ./server/
    volumes:
      - './server:/usr/src/'
      - './server/package.json:/usr/src/package.json'
    ports:
      - '3002:3002'

  reactclient:
    container_name: reactclient
    build: ./client/
    volumes:
      - './client:/usr/src/'
      - '/usr/src/node_modules'
    ports:
      - '3000:3000'
  mongodb:
    image: mongo
    ports:
      - "27017:27017"

The first service, newsservice, is our NodeJS API server. In our build property we specify ./server/ so that it uses the Dockerfile within our server folder. We then setup our volumes. The first one from our local ./server directory to the /usr/src folder within the container. This will allow us to edit and work on our files and have the changes reflected within the container without rebuilding through the use of nodemon within our server Dockerfile. We then expose the port 3002 so that our client can connect to it.

Our second container reactclient uses the /client/Dockerfile and will be the development server which is serving our react client.

Finally we have our mongodb container which will be launched from the mongo image fetched from the registry and set to be exposed on 27017.

docker-compose build

docker-compose up

dockercomposeup

Once it is built and running you should be able to edit your source on either the client or the server and have your changes compiled immediately.