FROM node:10 WORKDIR \/appCOPY app \/appRUN npm install -g webserver.localRUN npm install && npm run build EXPOSE 3000CMD webserver.local -d .\/build"}}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/0b\/0bc747430757de34de72748a511f05b8.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":"center","origin":null},"content":[{"type":"text","text":"图2:镜像的初始大小为1.16GB"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"第一步优化:使用轻量化基础镜像"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在"},{"type":"link","attrs":{"href":"https:\/\/hub.docker.com\/","title":"","type":null},"content":[{"type":"text","text":"Docker Hub"}]},{"type":"text","text":"(公共Docker仓库)中,有一些镜像可供下载,每个镜像都有不同的特征和大小。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"通常,相较于基于其他Linux发行版(例如"},{"type":"link","attrs":{"href":"https:\/\/hub.docker.com\/_\/ubuntu","title":"","type":null},"content":[{"type":"text","text":"Ubuntu"}]},{"type":"text","text":")的镜像,基于"},{"type":"link","attrs":{"href":"https:\/\/hub.docker.com\/_\/alpine","title":"","type":null},"content":[{"type":"text","text":"Alpine"}]},{"type":"text","text":"或"},{"type":"link","attrs":{"href":"https:\/\/hub.docker.com\/_\/busybox","title":"","type":null},"content":[{"type":"text","text":"BusyBox"}]},{"type":"text","text":"的镜像非常小。这是因为Alpine镜像和类似的其他镜像都经过了优化,其中仅包含最少的必须的软件包。在下面的图片中,你可以看到Ubuntu、Alpine、Node和基于Alpine的Node镜像之间的大小比较。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/86\/8636fe5ac03b51740ed84bc2d8de4990.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":"center","origin":null},"content":[{"type":"text","text":"图3:基础镜像的不同大小"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"通过修改Dockerfile并使用Alpine作为基础镜像,我们的镜像最终大小为330MB:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"embedcomp","attrs":{"type":"table","data":{"content":"FROM node:10-alpine WORKDIR \/appCOPY app \/appRUN npm install -g webserver.localRUN npm install && npm run build EXPOSE 3000CMD webserver.local -d .\/build"}}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/b0\/b0c525a22c2b853edc10853e58bc385b.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":"center","origin":null},"content":[{"type":"text","text":"图4:经过第一步优化后镜像大小为330MB"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"第二步优化:多阶段构建"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"通过多阶段构建,我们可以在Dockerfile中使用多个基础镜像,并将编译成品、配置文件等从一个阶段复制到另一个阶段,这样我们就可以丢弃不需要的东西。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在本例中,我们部署React应用程序需要的是编译后的代码,我们不需要源文件,也不需要node_modules目录和package.json文件等。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"通过将Dockerfile修改为如下内容,我们最终得到的镜像大小为91.5MB。请记住,来自第一阶段(第1-4行)的镜像不会被自动删除,Docker将它保存在cache中,如果我们在另一个构建镜像过程中执行了相同的阶段,就可以使镜像构建更快。所以你必须手动删除第一阶段镜像。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"embedcomp","attrs":{"type":"table","data":{"content":"FROM node:10-alpine AS buildWORKDIR \/appCOPY app \/appRUN npm install && npm run build FROM node:10-alpineWORKDIR \/appRUN npm install -g webserver.localCOPY --from=build \/app\/build .\/buildEXPOSE 3000CMD webserver.local -d .\/build"}}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/de\/defd6ffdfe16ec546d5a5b083c94a322.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":"center","origin":null},"content":[{"type":"text","text":"图5:第二步优化后的镜像大小为91.5MB"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"现在我们有了一个Dockerfile,它有两个阶段:在第一个阶段中,我们编译项目,在第二个阶段中,我们在web服务器上部署应用程序。然而,Node容器并不是提供网页(HTML、CSS和JavaScript文件、图片等)服务的最佳选择,最好的选择是使用像Nginx或Apache这样的服务。在本例中,我将使用Nginx。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"通过将Dockerfile修改为如下内容,我们的镜像最终大小是22.4MB,如果我们运行这个容器,我们可以看到网页"},{"type":"text","text":"可以正常工作,没有任何问题"},{"type":"text","text":"(图7)。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"embedcomp","attrs":{"type":"table","data":{"content":"FROM node:10-alpine AS buildWORKDIR \/appCOPY app \/appRUN npm install && npm run build FROM nginx:stable-alpineCOPY --from=build \/app\/build \/usr\/share\/nginx\/htmlEXPOSE 80CMD [\"nginx\", \"-g\", \"daemon off;\"]"}}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/a5\/a5679d4a483b0592976dff51e625a40b.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":"center","origin":null},"content":[{"type":"text","text":"图6:第三步优化后的镜像大小为22.4MB"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/5a\/5aea754a91e0157bf3503daca2a5337a.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":"center","origin":null},"content":[{"type":"text","text":"图7:最终容器的运行结果"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"参考"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https:\/\/docs.docker.com\/get-started\/","title":"","type":null},"content":[{"type":"text","marks":[{"type":"underline"}],"text":"https:\/\/docs.docker.com\/get-started\/"}]}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https:\/\/docs.docker.com\/develop\/develop-images\/multistage-build\/","title":"","type":null},"content":[{"type":"text","marks":[{"type":"underline"}],"text":"https:\/\/docs.docker.com\/develop\/develop-images\/multistage-build\/"}]}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"原文链接:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"https:\/\/medium.com\/the-agile-crafter\/docker-image-optimization-from-1-16gb-to-22-4mb-53fdb4c53311"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}}]} |
|
|
|