When developing React applications, using Docker ensures consistency across different environments. Instead of running React with npm start, we can serve the production build using nginx, improving performance and efficiency.

In this post, we will:

  1. - Create a Dockerfile to build and serve a React application using nginx.
  2. - Write a custom nginx.conf to properly serve the React app.
  3. - Use docker-compose.yml to run the containerized application.

📌 Project Structure

Your project should have the following structure:

/my-react-app
 ├── src/               # React source files
 ├── node_modules/      # Installed dependencies
 ├── public/            # Public assets
 ├── package.json       # Dependencies and scripts
 ├── Dockerfile         # Docker configuration
 ├── docker-compose.yml # Docker Compose setup
 ├── nginx.conf         # Nginx configuration

We will try model

  1. Run React application in dev mode docker
  2. Build & Run React application in prod mode with nginx docker

🌱 Run React application in dev mode docker

Here’s the Dockerfile and docker-compose.yml setup for your React application. This will allow you to run your app in a containerized environment and access it on http://localhost:3000.

🛠 Step 1: Create the Dockerfile

This Dockerfile will:

  • Use node:23 to build the React app.
  • Use nginx to serve the production-ready app.
# Use Node.js image as the base image
FROM node:23-alpine AS build-stage

# Set the working directory inside the container
WORKDIR /app

# Copy package.json and package-lock.json to the working directory
COPY package*.json ./

# Install dependencies
RUN npm install

# Copy the entire project to the working directory
COPY . .

# Expose the port React runs on
EXPOSE 3000

# Start the React application
CMD ["npm", "start"]

⚙️ Step 2: Create docker-compose.yml

This allows us to run the containerized application easily.

version: "3.8"

services:
  react-app:
    container_name: react_app
    build: .
    ports:
      - "3000:3000"
    volumes:
      - .:/app
      - /app/node_modules
    stdin_open: true
    tty: true

🧇 Build & Run React application in prod mode with nginx docker

This setup ensures that our React application runs efficiently in production with nginx.

🛠 Step 1: Create the Dockerfile

This Dockerfile will:

  • Use node:23 to build the React app.
  • Use nginx to serve the production-ready app.
  • Copy the built files into the nginx server.
# Use Node.js image to build the React app
FROM node:23-alpine AS build-stage

# Set working directory
WORKDIR /app

# Copy package.json and package-lock.json
COPY package*.json ./

# Install dependencies
RUN npm install

# Copy the entire project
COPY . .

# Build the React app
RUN npm run build

# Use Nginx to serve the build files
FROM nginx:alpine

# Copy the built files from the previous step
COPY --from=build /app/build /usr/share/nginx/html

# Copy the custom Nginx configuration
COPY nginx.conf /etc/nginx/conf.d/default.conf

# Expose port 3000
EXPOSE 3000

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

🔧 Step 2: Create nginx.conf

This file ensures that nginx correctly serves the React app, handling routes properly.

server {
    listen 3000;
    server_name localhost;

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

    error_page 404 /index.html;

    location /api/ {
        proxy_pass http://backend:5000;  # Modify if you have a backend service
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

⚙️ Step 3: Create docker-compose.yml

This allows us to run the containerized application easily.

version: "3.8"

services:
  react-app:
    container_name: unified_portal_c
    build: .
    ports:
      - "3000:3000"
    restart: always

🚀 Running the Application

Now that everything is set up, follow these steps to run your React app in a Docker container:

1️⃣ Build and start the container

docker-compose up --build

2️⃣ Open in your browser

http://localhost:3000

3️⃣ Stop the container

docker-compose down