Dockerfile optimization

The reason of this paper is that the packaging time of a project I am working on is too slow. The so-called code takes 5 minutes and the packaging takes half an hour. I am also looking at some things of Docker, so I plan to optimize the dockerfile

The text before
  • Dive tool, which can be used to analyze mirror size, portal: github.com/wagoodman/d…
  • Dockerfile best practices, portal: zhuanlan.zhihu.com/p/26904830

Let’s take a look at this dockerfile

  • First of all, aimage1Mirror image (written arbitrarily here, for example only) ascompileThe mirror
  • Specifies the/codedirectory
  • Copy localpackage.json.yarn.lock.npmrcThe file to/codeDirectory for installationNPMThe module
  • Run theyarn install --productionAnd will benode_moduleCopy to a temporary directory
  • Run againyarn
  • Before copying all files to/codeIn the directory
  • runnpm run buildTo package the project
  • Here are two questions
    • Question 1: Why is it runningyarn install --productionRun lateryarnIsn’t that redundant
    • Question 2: Why copypackage.jsonto/codeDirectory, and then copy the entire file again, isn’t that also repeated
  • thenimage2Mirror asreleaseThe mirror
  • Copy local files to the current image
  • The specified/codedirectory
  • Copy from the image temporary directory at the previous levelnode_module
  • From the mirror image of the previous layerclient.configfolder
  • runyarn start
  • To solve the problem
    • Problem 1: It didn’t work out, but then it worked outyarn install --productionIt’s installed for productionNPMPackage, and then copy to the temporary directory, then copy from the temporary directory, copy out the package for production, not all packages, reduce the volume of the package
    • Question 2: Why copy firstpackage.json, because we should put the part that changes least in front of the Dockerfile to make full use of the image cachezhuanlan.zhihu.com/p/26904830In the11. Adjust the sequence of COPY and RUN

The size of the image packaged by dockerfile can be seen as 725M, and the middle image has 2.11G, which is really worthy of the code in 5 minutes and packed for half an hour

The Dive tool analyzes the image, (Dive mirror ID), as shown in github.com/wagoodman/d… You can see that there are 725M, 421M that can be optimized

4. Optimized dockerfile

  • Why am I optimizing this way

  • I don’t have to COPY package. The json file and install the NPM package COPY other files later, because this article zhuanlan.zhihu.com/p/26904830 reasonable adjustment of the COPY with the order of the RUN. First of all, the package is written in json COPY to come in, Then install the package and COPY the remaining files to the specified directory. For this project, I will use all files other than package.json. After copying package.json and other files for the first time, the most convenient way to COPY them for the second time is COPY. Excluding package.json files is tedious

  • With that in mind, in the compile image

    • The specified/codeDirectory,
    • Copy the local file to/codeDirectory,
    • withyarn buildInstead ofnpm run buildAnd thenyarnandyarn buildCommand to merge
  • In the Release image

    • To get rid ofcode . /codeBecause of the followingcopy --from=compileThe orders were repeated
    • To get rid ofcode . /codeIn the future, the image won’t work because some files are missing,package.jsonandnext.config.jsRun,yarn startWhen you needpackage.jsonFile, andyarn startCommand isNEXT_ENV=prod PORT=3000 next start clientNext configuration file
  • How did I know these files were missing

    • docker run --name test -p 4040:3000 5be399174a72So let’s start with the mirror image
    • docker ps -aFind out the container
    • docker exec -it c57cb2999203 /bin/shIf you go into the container and look at it, you can see/codeWith these files in the directory, compare the files in the container that started running with those in the container that didn’t, and figure out which files are missing and which files are needed
  • According to question 1, why didn’t I use yarn install –production? The yarn start command won’t run with these packages, and as the Dive tool below shows, only 358K can be optimized. There is no need to run this command to copy to the temporary directory, after all, yarn needs to be run later

5. It can be seen that now the mirror is only 489M, and the middle mirror compile is also reduced, only 1.71g

6. Dive then looked at the mirror and found that there was 489M in total and only 358K that could be optimized

DockerIgnore

  • Because we will use YARN again, there is no need to place the localnode_moduleThe package is uploaded to the Docker server
  • As you can see, Settings.dockerignoreLater, the size uploaded to the Docker server was reduced from 343M to 29M


Why doesn’t this dockerfile run

  • Because according to the Dive tool analysis, yesnode_moduleSo this dockerfile adds a sentence to the original dockerfileRUN /bin/rm -fr node_modules
  • As I said,yarn startYou need to use itnode_module“, so I deleted it in frontnode_moduleIt won’t run