一次Dockerfile優化

Dockerfile優化

本文的原由是在作的一個項目打包時間實在太慢了,所謂代碼5分鐘,打包半小時,又正好在看docker的一些東西,因此打算優化一下這個dockerfilenode

文前

一.首先來看下這個dockerfilegit

  • 首先將一個image1鏡像(這裏隨意寫的,舉例而已)做爲compile鏡像
  • 指定了/code目錄
  • 拷貝了本地的package.json,yarn.lock,npmrc文件到/code目錄中,用於安裝NPM模塊
  • 運行了yarn install --production,而且將node_module拷貝到臨時目錄
  • 再運行yarn
  • 在拷貝全部文件到/code目錄中
  • 運行npm run build來打包項目
  • 到這裏先提出兩個問題
    • 問題1:爲何要運行了yarn install --production之後再運行yarn,這不是重複了,畫蛇添足嗎
    • 問題2:爲何要拷貝了package.json/code目錄下,而後再拷貝一遍所有文件呢,這不是也重複了嗎
  • 而後將image2鏡像做爲release鏡像
  • 將本地的文件拷貝到當前鏡像中
  • 指定/code目錄
  • 從上一層鏡像臨時目錄中中拷貝node_module
  • 從上一層鏡像中client,config文件夾
  • 運行yarn start
  • 解決問題
    • 問題1:當時沒想通,後來忽然想通了,運行了yarn install --production是安裝了生產要用的NPM包,而後拷貝到臨時目錄裏,後面從臨時目錄裏拷貝,拷貝出來的是生產時要用的包,不是所有的包,減小了包的體積
    • 問題2:爲何要先拷貝package.json,是由於咱們應該把變化最少的部分放在Dockerfile的前面,這樣能夠充分利用鏡像緩存,詳見 zhuanlan.zhihu.com/p/26904830 中的 11.合理調整COPY與RUN的順序

二.這個dockerfile打包出來的鏡像的大小,能夠看到有725M,中間鏡像有2.11G,真的對得起代碼5分鐘,打包半小時github

三.dive工具分析這個鏡像,(dive 鏡像id),詳見 github.com/wagoodman/d… 能夠看到總共725M,能夠優化的有421Mdocker

四.優化後的dockerfilenpm

  • 我爲何這麼優化json

  • 我沒有先拷貝package.json等文件並安裝了NPM包之後再拷貝其餘文件,由於本篇文章中的 zhuanlan.zhihu.com/p/26904830 的合理調整COPY與RUN的順序中寫到的是首先將package.json拷貝進來,而後安裝包,再將剩餘其餘文件拷貝進指定的目錄,而我這個項目,package.json之外的文件都要用到,第一次拷貝package.json等文件之後,第二次拷貝最方便的方法是COPY . /code,要拷貝其餘文件,而排除package.json文件的作法反而繁瑣緩存

  • 基於上面那一點的操做的考慮之後,在compile鏡像中服務器

    • 指定/code目錄,
    • 將本地文件拷貝到/code目錄下,
    • yarn build代替npm run build,而後將yarnyarn build命令合併
  • release鏡像中工具

    • 去掉code . /code,由於和後面的copy --from=compile那些命令重複了
    • 去掉code . /code之後,鏡像是跑不起來的,由於少了一些文件,package.jsonnext.config.js,運行yarn start的時候要package.json文件,而yarn start命令是NEXT_ENV=prod PORT=3000 next start client,要next的配置文件
  • 我是怎麼知道少了這些文件的優化

    • docker run --name test -p 4040:3000 5be399174a72首先先跑起這個鏡像
    • docker ps -a 找出容器
    • docker exec -it c57cb2999203 /bin/sh進入到容器中查看,能夠看到/code目錄中有這些文件,對比起先能夠跑起來的容器裏面的文件和跑不起來的容器的報錯,排查出少了哪些文件,須要哪些文件
  • 根據問題1的解答,我爲何不用yarn install --production了,由於只用這些包,yarn start命令是跑不起來的,並且從下面的dive工具顯示,能夠優化的已經只有358K了,也就沒有必要運行這個命令再拷貝到臨時目錄了,畢竟後面也還要運行yarn

五.能夠看到如今鏡像只有489M的,中間鏡像compile也變少了,只有1.71G

六.再用dive工具查看這個鏡像,發現總共489M,能夠優化的只有358K了

七. 優化升級.dockerignore

  • 由於咱們會用yarn從新,因此沒有必要將本地的node_module包傳到docker服務器上
  • 能夠看到,設置.dockerignore之後,傳到docker服務器上的大小從343M減到了29M

八.爲何這個dockerfile跑不起來

  • 由於根據dive工具分析出了是node_module,因此這個dockerfile在最初的dockerfile上加了一句RUN /bin/rm -fr node_modules
  • 前面說到了,yarn start的時候要用到node_module,因此在前面刪了node_module會跑不起來
相關文章
相關標籤/搜索