How to Dockerize a React Application In 5 Minutes
What is docker?
Docker is a platform that enables developers to package and distribute applications along with their dependencies in a consistent and isolated environment, known as a container. Containers encapsulate an application and its runtime, libraries, and system tools, ensuring that the application runs consistently across different environments. Docker facilitates the creation, deployment, and scaling of applications by providing a lightweight, portable, and reproducible containerization solution. It simplifies the development process by streamlining collaboration between developers and operations teams, making it easier to build, ship, and run applications across various computing environments.
What is a docker image?
A Docker image is a lightweight, standalone, and executable package that includes all the necessary components to run a software application, including the code, runtime, libraries, and system tools. It serves as a snapshot of a file system and the parameters needed for an application to run. Docker images are created from a set of instructions called a Dockerfile, which specifies the base image, application code, dependencies, and configuration settings. Once an image is built, it can be easily shared and deployed across different environments, providing consistency and reproducibility in application development and deployment. Images are stored in repositories, and Docker uses these repositories to manage and distribute images efficiently. Containers are instances of Docker images, and they run in isolation from the host system, making Docker images a fundamental building block for containerized applications.
Base Image:
A base image is the foundation for a Docker image. It is a pre-built and minimalistic image that provides a specific operating system and runtime environment. Developers use base images as starting points for their applications, adding necessary dependencies and configurations to create a customized image. Common base images include official images provided by Docker, such as those for different Linux distributions or programming runtimes like Node.js or Python.
Parent Image:
The parent image is the image upon which another image is built. When creating a Docker image, developers often start with a base image as the parent and then add layers of customization. Each layer represents a set of changes made to the image, and the resulting image becomes the parent for subsequent layers.
Layers:
Docker images are composed of layers. Each layer represents a set of file system changes, commands, or instructions added to the image during the build process. Layers are designed to be immutable, meaning once a layer is created, it cannot be modified. This immutability contributes to the efficiency and reproducibility of Docker images. When an image is updated or modified, only the layers that change need to be rebuilt, reducing the time and resources required for image creation and distribution.
Container Layer:
The container layer is the top layer of a Docker image. It is the read-write layer where runtime changes, such as file modifications or data updates, occur during the execution of a container. The container layer is ephemeral, meaning any changes made to it are discarded when the container stops, preserving the immutability of the underlying image layers.
Docker Manifest:
The Docker manifest is a JSON file that describes an image, including its layers, architecture, and operating system. It provides metadata about the image and allows Docker to manage multi-platform images, which are images designed to run on different architectures. The manifest ensures that the correct image layers are pulled and assembled when the image is deployed on various systems.
What is a docker container?
A Docker container is a self-contained and lightweight executable unit that encapsulates an application along with its dependencies and runtime environment. Created from a Docker image, a container operates in isolation from the host system and other containers, ensuring consistency across diverse environments. Containers are portable, efficient, and scalable, providing a means to package, deploy, and run applications seamlessly across development, testing, and production environments. With their rapid startup and minimal resource usage, Docker containers have become a fundamental building block for modern, containerized application deployment and management.
Steps to Dockerize React Application
Step 1: Set Up Your React.js Application
Create a Reactjs application with the following command
npx create-react-app my-react-app
Ensure you have a React.js application with the following structure:
my-react-app/
├── src/
│ └── (React components and files)
├── public/
│ └── (HTML and static assets)
├── package.json
└── Dockerfile
Step 2: Create a Dockerfile
Create a Dockerfile
in the root of your React.js application. This file will build the React app and serve it using NGINX.
# Build Stage
FROM node:latest as build-stage
WORKDIR /app
# Copy package.json and package-lock.json to the working directory
COPY package*.json ./
# Install dependencies
RUN npm install
# Copy the rest of the application files to the working directory
COPY . .
# Build the React application
RUN npm run build
# Production Stage
FROM nginx:latest
# Copy the NGINX configuration file
COPY nginx.conf /etc/nginx/conf.d/default.conf
# Copy the build artifacts from the build stage to NGINX web server
COPY --from=build-stage /app/build/ /usr/share/nginx/html
# We need to make sure not to run the container as a non root user
# for better security
WORKDIR /app
RUN chown -R nginx:nginx /app && chmod -R 755 /app && \
chown -R nginx:nginx /var/cache/nginx && \
chown -R nginx:nginx /var/log/nginx && \
chown -R nginx:nginx /etc/nginx/conf.d
RUN touch /var/run/nginx.pid && \
chown -R nginx:nginx /var/run/nginx.pid
USER nginx
# Expose port 80 for the NGINX server
EXPOSE 80
# Command to start NGINX when the container is run
CMD ["nginx", "-g", "daemon off;"]
After building the docker image in the node you can see that the image size is around 500 Mb. This is not really sustainable for production. So we will now serve the react build files via a web server for better performance. We can use Nginx image to run our static file. Let's create an Nginx config file.
NGINX Configuration (nginx.conf)
Create an nginx directory at the root of your project and add an nginx.conf file inside it:
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html;
try_files $uri $uri/ /index.html;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
location /health {
return 200;
}
}
This NGINX configuration ensures that all requests are redirected to your React app’s index.html
. It's a common setup for single-page applications.
Building and Running
Build and run the Docker container using the same commands as before:
docker build -t my-react-app .

Run the following command to see the created image:
docker image ls

Now we should run the image we built in the previous step.
docker run -d -p 80:80 my-react-app

Et voila!

Feel free to check out the GitHub repository.