DEV Community

Cover image for Dockerize React app for dev and prod
Vishnu Prasaath
Vishnu Prasaath

Posted on • Originally published at blog.vishnuprasaath.dev on

4 1 1 1

Dockerize React app for dev and prod

Okay, you have a frontend React app and you want to serve it via Docker. Let's do that!

In this wiki, we will dockerize both the development and production environment via separate Dockerfiles.

Step 1: Project setup

Initialized a pretty standard react project using the default create react app (CRA) template. Or pick your existing React app. Below is the sample project folder structure.

 node_modules
 public
    favicon.ico
    index.html
    manifest.json
    robots.txt
 src
    App.css
    App.js
    index.css
    index.js
    logo.svg
 package.json
 yarn.lock

Enter fullscreen mode Exit fullscreen mode

Step 2: Init .dockerignore

Add a .dockerignore file, this will help us ignore node_modules, .env etc

.git
.gitignore
**/node_modules
**/npm-debug.log
build

Enter fullscreen mode Exit fullscreen mode

Step 3: Dockerize Development env

Init Dockerfile

Start by adding a Dockerfile.dev

FROM node:14-alpine AS development
ENV NODE_ENV development

# Add a work directory
WORKDIR /app

# Cache and Install dependencies
COPY package.json .
COPY yarn.lock .

#RUN yarn install
RUN npm i

# Copy app files
COPY . .

# Expose port
EXPOSE 3000

# Start the app
CMD ["yarn", "start"]

Enter fullscreen mode Exit fullscreen mode

Init docker-compose

Create a docker-compose.dev.yml. Additionally, we will mount our code in a volume so that our code changes are in sync with the container during development.

version: "3.8"

services:
  app:
    container_name: app-dev-c
    image: app-dev-i
    build:
      context: .
      dockerfile: Dockerfile.dev
    volumes:
      - ./src:/app/src
    ports:
      - "3000:3000"

Enter fullscreen mode Exit fullscreen mode

Let's start our React app for development!

docker-compose -f docker-compose.dev.yml up

Enter fullscreen mode Exit fullscreen mode

To make life easier add docker-compose commands to package.json

"docker-dev-up": "docker-compose -f docker-compose.dev.yml up"
"docker-dev-down": "docker-compose -f docker-compose.dev.yml down"

Enter fullscreen mode Exit fullscreen mode

Let's check our container!

> docker ps

REPOSITORY TAG IMAGE ID CREATED SIZE
app-dev latest 5867f4e40c98 About a minute ago 436MB

Enter fullscreen mode Exit fullscreen mode

Visit the app at http://localhost:3000


Step 4: Dockerize Production env

Let's use nginx to serve our static assets and help resolve routes when we're using React Router or any kind of routing.

Configure nginx

Create a nginx.conf with the below content. This will help handle URI changes during routing.

server {
  listen 80;

  location / {
    root /usr/share/nginx/html/;
    include /etc/nginx/mime.types;
    try_files $uri $uri/ /index.html;
  }
}

Enter fullscreen mode Exit fullscreen mode

Init Dockerfile

Start by adding a Dockerfile.prod

FROM node:14-alpine AS builder
ENV NODE_ENV production

# Add a work directory
WORKDIR /app

# Cache and Install dependencies
COPY package.json .
COPY yarn.lock .
RUN npm i

# Copy app files
COPY . .

# Build the app
RUN npm run build

# Bundle static assets with nginx
FROM nginx:1.21.0-alpine as production
ENV NODE_ENV production

# Copy built assets from builder
COPY --from=builder /app/build /usr/share/nginx/html

# Add your nginx.conf
COPY nginx.conf /etc/nginx/conf.d/default.conf

# Expose port
EXPOSE 80

# Start nginx
CMD ["nginx", "-g", "daemon off;"]

Enter fullscreen mode Exit fullscreen mode

Init docker-compose

Add a docker-compose.prod.yml file

version: "3.8"

services:
  app:
    container_name: app-prod-c
    image: app-prod-i
    build:
      context: .
      dockerfile: Dockerfile.prod
    ports:
        - "8080:80"

Enter fullscreen mode Exit fullscreen mode

Build production image

docker-compose -f docker-compose.prod.yml build

Enter fullscreen mode Exit fullscreen mode

Let's check out our built production image

> docker images

REPOSITORY TAG IMAGE ID CREATED SIZE
app-prod latest c5db8d308bb9 About a minute ago 23.1MB

Enter fullscreen mode Exit fullscreen mode

Start our production container on port 80 with the name react-app

docker run -p 8080:80 --name react-app app-prod

Enter fullscreen mode Exit fullscreen mode

Visit the app at http://localhost:8080

Here is how the final project struct looks:

 node_modules
 public
    index.html
   ...
    manifest.json
 src
    App.css
   ...
    index.js
 package.json
 yarn.lock
 .dockerignore
 Dockerfile.dev
 Dockerfile.prod
 docker-compose.dev.yml
 docker-compose.prod.yml

Enter fullscreen mode Exit fullscreen mode

Hurrayyy!! We can now use docker in our workflow and deploy our production images faster to any platform.

Heroku

Simplify your DevOps and maximize your time.

Since 2007, Heroku has been the go-to platform for developers as it monitors uptime, performance, and infrastructure concerns, allowing you to focus on writing code.

Learn More

Top comments (0)

Image of Docusign

🛠️ Bring your solution into Docusign. Reach over 1.6M customers.

Docusign is now extensible. Overcome challenges with disconnected products and inaccessible data by bringing your solutions into Docusign and publishing to 1.6M customers in the App Center.

Learn more