ReactJs production deployment using Docker and Nginx
- Published on
- -5 mins read-––– views
- Author
- Name
- Endalkachew Biruk
In this article we are going to build and deploy the default create-react-app using Docker and Nginx. To get started let's create a new react project.
npx create-react-app react-app --template typescript
If you want to jump to the code directly, you can use the following link: https://github.com/endalk200/blog_posts/tree/reactjs-docker-setup
Dockerfile
Create Dockerfile
and add the following multi stage Dockerfile there.
# Dependency installation stage.FROM node:alpine AS dependencies
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine# to understand why libc6-compat might be needed.RUN apk add --no-cache libc6-compat
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
# React app build stage.FROM node:alpine AS builder
WORKDIR /app
COPY . .
COPY --from=dependencies /app/node_modules ./node_modules
## Install build toolchain, install node deps and compile native add-onsRUN apk add --no-cache python3 make g++
RUN npm run build && npm install --production --ignore-scripts --prefer-offline
# Nginx configuration and runing stage.FROM nginx:alpine AS runner
# Set working directory to nginx asset directoryWORKDIR /usr/share/nginx/html
# Remove default nginx static assetsRUN rm -rf ./*
# Copy static assets from builder stageCOPY --from=builder /app/build .
EXPOSE 80
# Containers run nginx with global directives and daemon offENTRYPOINT ["nginx", "-g", "daemon off;"]
After creating the dockerfile now create .dockerignore
file. Any files or directories referenced here will be ignored in th build process. This can help use
reduce our image size.
node_modules/
Let's go over the dockerfile configuration one by one.
# Dependency installation stage.FROM node:alpine AS dependencies
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine# to understand why libc6-compat might be needed.RUN apk add --no-cache libc6-compat
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
In this stage of the dockerfile we are going to install the dependencies for the application. Firs chose the node:alpine image. This image is a base image
for the nodejs application. Second install libc6-compat
which is shared missing library from node:alpine
base image so we need to install that. If you want to read
more about this refer https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine
Then we are going to install npm dependencies. We are going to use the npm ci
command to install the dependencies. This command is preferable over npm install
because npm ci
is
optimized for CI run while npm install
is not.
# React app build stage.FROM node:alpine AS builder
WORKDIR /app
COPY . .
COPY --from=dependencies /app/node_modules ./node_modules
## Install build toolchain, install node deps and compile native add-onsRUN apk add --no-cache python3 make g++
RUN npm run build && npm install --production --ignore-scripts --prefer-offline
This is the build stage. Copy the node_modules
directory from the dependency installation stage. Then add python3 make and g++ which are part of build tools in linux,
So they will facilitate the build process. Then run npm run build && npm install --production --ignore-scripts --prefer-offline
. Basicaly we are runing the build
script with production tag. At this point we have the built static files under build
directory.
# Nginx configuration and runing stage.FROM nginx:alpine AS runner
# Set working directory to nginx asset directoryWORKDIR /usr/share/nginx/html
# Remove default nginx static assetsRUN rm -rf ./*
# Copy static assets from builder stageCOPY --from=builder /app/build .
EXPOSE 80
# Containers run nginx with global directives and daemon offCMD ["nginx", "-g", "daemon off;"]
We have reached the final stage. At this stage we are going to copy the static files from the build stage to the nginx asset directory. Then we are going to run the nginx container.
WORKDIR /usr/share/nginx/html
is the working directory where nginx
assets reside. we are going to remove the default files and configurations from this directory RUN rm -rf ./*
.
After removing the default assets we are going to copy the static files from the build stage to the nginx asset directory. Then we are going to run nginx using ENTRYPOINT ["nginx", "-g", "daemon off;"]
Build and Run
In the above section we have created a Dockerfile for the production ready ReactJS application. Now we are going to build the image and run the container. To build the Dockerfile run
docker run -t react-app-image .
Here we are building the dockerfile and naming the resulting image react-app-image
. Then we can run the container using the following command:
docker run react-app-image -p 8080:80
Nginx default port is 80 so we need to map that port to our port. Here I have set to 8080. Now we can access the application using the following URL: http//localhost:8080
.
Conclusion
Now that we a have our react app runing in production environment the only thing left is configure the IP address, domain and SSL certificate. To refer to the full code for this guide visit https://github.com/endalk200/blog_posts/tree/reactjs-docker-setup