Weight reduction of Docker image by multi-stage build-React application

Introduction

Nice to meet you, I'm addicted to playing around with Docker and Kubernetes lately. This time I tried to reduce the weight of the Docker image!

This time, the one created by default using the create-react-app command is containerized.

//App creation
$ create-react-app sample-react-app
$ cd sample-react-app

Dockerfile in question

Prepare the Dockerfile. As a flow --build for production --Install and run a module that executes static files

It's like that.

Dockerfile


FROM node:12
COPY . /react-app
WORKDIR /react-app
RUN npm install && npm run build && npm install -g serve
CMD ["serve","-s","build" ]

With this, by default, it listens at 5000, so if you port forward and execute as follows, you can confirm that the application works on localhost: 5000.

$ docker run -p 5000:5000 sample-react-app:0.0.1

Until yesterday I was! I was happy that I was able to create a React app container. But I thought.

Isn't it necessary to have a node environment because it only executes static files in the end?

By the way, if you look at the size of the Docker image here ...

$ docker images
REPOSITORY                                                   TAG                 IMAGE ID            CREATED             SIZE
sample-react-app                                             0.0.1               6e7bc9096dd7        9 minutes ago       1.31GB

... big.

However, I think that it is not so much to give production files to git, so if you build from the git repository using CI tools etc., I want npm install and npm run build at the stage of building with Docker. I think.

So ** multi-stage! ** There is this.

So I tried to bring the production files to nginx using multi-stage.

Improved Dockerfile

Improved Dockerfile


#the first stage(Until production file generation)
FROM node:12 as node
COPY . /react-app
WORKDIR /react-app
RUN npm install && npm run build

#Second stage(Copy only static files from the contents of the first stage container)
FROM nginx:1.19.2-alpine
COPY --from=node ./react-app/build /usr/share/nginx/html
CMD nginx -g "daemon off;"

It is a start of excitement. .. .. Let's build and run with the tag 0.0.2.

$ docker build -t sample-react-app:0.0.2 .
$ docker run -p 5000:80 sample-react-app:0.0.2

I was able to start it safely! image.png

And the size is ...

$ docker images
REPOSITORY                                                   TAG                 IMAGE ID            CREATED             SIZE
sample-react-app                                             0.0.2               9148ac06ddbe        3 minutes ago       22.5MB
It's pretty smart! If it's just the size, it's 1/60!

in conclusion

Personally, I had a good sense of accomplishment that it was changed so dramatically! In the future, I'm not satisfied with just containerization, and I would like to think carefully about how to make it.

Recommended Posts

Weight reduction of Docker image by multi-stage build-React application
[Error] Error during Docker build (solved by pulling the latest version of image)
Summary of Docker understanding by beginners ② ~ docker-compose ~
How to create a small docker image of openjdk 11 (ea) application (1GB → 85MB)
Summary of Docker understanding by beginners ① ~ docker run -p ~
Change the location folder of Docker image & container