If you are using Docker Compose to manage the services of your application, it is convenient to use it to host the React web app itself as well. To do this, there are two approaches that you can follow.

Let's walk through both approaches.

A sketch of a stick figure composer instructing the React logo

Using a custom docker image

As I mentioned in this post, you can create a custom docker image for your React app that will automatically create a production build and include it in a web server image that can be run directly.

Once you have placed the Dockerfile, nginx.conf and .dockerignore files from that post into the root folder of your project, you can simply place the following code into a docker-compose.yml file at the same place.

version: "3"
services:
react-app:
build: .
ports:
- "8000:80"

Replace react-app with a name of your choice. This configuration maps port 80 of the custom container to port 8000 on the host machine so that it is accessible from the host machine. You can run this compose file with the following command in the root folder of the project.

$ docker compose up

Mount a production build into a web server image

If you can place a production build of your react app and the nginx.conf file in the same location as the docker-compose.yml file, you can mount it directly into a web server container with the following config.

version: "3"
services:
web:
image: nginx:1.24-alpine
volumes:
- ./dist:/usr/share/nginx/html
- ./nginx.conf:/etc/nginx/conf.d/default.conf
ports:
- "8000:80"

This config uses the nginx:1.24-alpine web server image to directly host the production build. Version 1.24 of nginx is expected to be supported until early 2024, you can find the latest version of nginx here. It assumes that the production build is placed in a folder called dist, change this if your project uses a different folder to store the production build.

It also expects a custom nginx configuration in the nginx.conf file. A custom nginx configuration is required since the default nginx configuration does not work with client-side routing solutions like React router. Place the following code into the nginx.conf file to address this issue. You can find more information about how this nginx config works in this post.

server {
listen 80;
listen [::]:80;

location / {
root /usr/share/nginx/html;
try_files $uri $uri/ /index.html;
}
}
Prabashwara Seneviratne

Written by

Prabashwara Seneviratne

Author. Lead frontend developer.