You’ve created you React application and are now looking to create a docker image for it.
Before we look at the Dockerfile, create yourself a .dockerignore file that looks like this
.git node_modules
We do not require the .git folder in our image and we’re going to install our node modules via npm install as you’ll find copying the node_modules folder(s) is slow.
Let’s jump straight in and look at a Dockerfile that will take our React code containerize it and set the container up to run nginx to host it.
FROM node:21-alpine3.18 as build WORKDIR /usr/app COPY . . RUN npm install RUN npm run build FROM nginx:alpine COPY --from=build /usr/app/build /usr/share/nginx/html EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]
We’re using a node alpine image as our base. This is a lightweight image as we won’t our image to be lean. Next we create our WORKDIR, this can be set to your preferred location but just remember to reuse that location in the COPY command. We’re using .dockerignore to ignore .git and node_modules which allows us to then just copy everything to the image, where we then install then build our React application.
Finally we use nginx to serve our application, first copying the build folder to nginx and finally we set up the CMD to run nginx once the container is started, thus hosting our React application.
To build our image we can just use the following (change the tag name and version to suit your application)
docker build -t my-app:0.1.0 .
and to run, again set your application name any port redirects and use you tagged and version
docker run --rm --name my-app -p 8080:80 -d my-app:0.1.0
We could also extend this sample to include copying of nginx.conf to the image, for example if you want the supply a config like this
worker_processes 4; events { worker_connections 1024; } http { server { listen 4200; root /usr/share/nginx/html; include /etc/nginx/mime.types; location / { root /usr/share/nginx/html; index index.html; try_files $uri $uri/ /index.html; } } }
If we assume we’re storing out nginx.conf file in a folder named .ngnix (this is not required it’s just for this example) then we could add the following to the Dockerfile, after the line FROM nginx:alpine add the following and whilst we’re at it let’s get rid of the default files that might be located in the images nginx/html folder
COPY ./.nginx/nginx.conf /etc/nginx/nginx.conf RUN rm -rf /usr/share/nginx/html/*
Docker Compose
Whilst we’re here, let’s create a simple docker-compose.yaml file for our new image.
version: '3.8' services: front-end: build: context: ./ui dockerfile: ./ui/Dockerfile ports: - 4200:4200 image: putridparrot/my-app:0.1.0 container_name: my-app
We might like to store configuration for this image on the hosting server, i.e. via a volume in which case we’d simply add to the bottom of this file the following
volumes: - ./ui/public/appsettings.json:/usr/share/nginx/html/appsettings.json
In this example we’re using an appsettings.json file to configure the environment, or it might include feature flag settings or whatever and assuming it’s stored in the public folder of you React application.
Now we just docker-compose up.