Install Docker and Docker-compose
Before starting the project install Docker and Docker-compose.
You can install it from here.
Create React App
Now, let's create a simple React application using the create-react-app
npm install -g create-react-app
create-react-app react-docker-demo-app
Lets Dockerize the App
Add Dockerfile
Create a file named Dockerfile at the root of the project directory.
FROM node:10-alpine as builder
# install and cache app dependencies
COPY package.json package-lock.json ./
RUN npm install --only=prod&& mkdir /react-frontend && mv ./node_modules ./react-frontend
WORKDIR /react-frontend
COPY . .
RUN npm run build
The first stage is using Node to build the app. we are using Alpine version here as its lightest version.
The build would generate a build directory which contains chunk file.
Add .dockerignore
Create a .dockerignore file and add node_modules directory to it
node_modules
This would speed up the process of building images as our local dependencies will not be sent to the Docker daemon.
Now time to Build the Docker image
docker build -t react-frontend .
Then, run the container using the Image which we just created.
docker run -p 3000:3000 react-frontend
Open http://localhost:3000 in the browser and you should be able to see homepage of the react app
Production build
Add NGINX server
NGINX acts a reverse proxy like a middleman between a client making a request to that proxy and that proxy making requests and retrieving its results from other servers.
To add nginx as a server to our app we need to create a nginx.conf in the project root folder.
nginx.conf
server {
listen 80;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
Then, add the below lines to the Dockerfile
FROM nginx:1.16.0-alpine
COPY --from=builder /app/build /usr/share/nginx/html
RUN rm /etc/nginx/conf.d/default.conf
COPY nginx/nginx.conf /etc/nginx/conf.d
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Here we are copying the build in the previous step and pasting into the nginx folder and exposing the port 80 - that's going to be the port on which the container will be listening for connections.
This produces, production ready image
Finally, the whole Dockerfile should look like this:
FROM node:10-alpine as builder
# install and cache app dependencies
COPY package.json package-lock.json ./
RUN npm install && mkdir /react-frontend && mv ./node_modules ./react-frontend
WORKDIR /react-frontend
COPY . .
RUN npm run build
# ------------------------------------------------------
# Production Build
# ------------------------------------------------------
FROM nginx:1.16.0-alpine
COPY --from=builder /react-frontend/build /usr/share/nginx/html
RUN rm /etc/nginx/conf.d/default.conf
COPY nginx/nginx.conf /etc/nginx/conf.d
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
docker-compose.yml
Docker compose is a basically tool to run multiple container from a single service. It uses a yaml file which contains the configuration to run the containers
version: '3.7'
services:
react-frontend:
container_name: react-frontend
build:
context: .
dockerfile: Dockerfile
volumes:
- '.:/app'
- '/app/node_modules'
ports:
- '3000:3000'
environment:
- NODE_ENV=development
To start the containers
docker-compose up
To stop the containers
docker-compose down
Next Steps
With that , you should be able to add React to a larger Docker powered project for both development and production environments.
Top comments (7)
When you say
How it's this possible? If you run
yarn build
only, there is not web server!maybe he meant to run it with:
docker run -p 3000:3000 --entrypoint /bin/sh react-frontend -c "npm start"
Thanks, works for me
Hi, thank you for the great article. I'd like to mention about the crate-react-app command.
According to the doc for the command,
global installs of create-react-app are no longer supported.
We need to use that command with npx now.
ref: create-react-app.dev/docs/getting-...
Hi. Why would you create the volumes ?
for share code between local server and internal container, the /app/modules is for prevent rebuilding of container when we run a docker compose
Thank you! I had to modify mine a bit to fit my application but it was an awesome start!