如何使用 NodeJs 缩小 Docker 镜像的大小

Posted

技术标签:

【中文标题】如何使用 NodeJs 缩小 Docker 镜像的大小【英文标题】:How to shrink size of Docker image with NodeJs 【发布时间】:2017-05-20 01:20:53 【问题描述】:

我通过 angular-cli 创建了新的 Angular2 应用并在 Docker 中运行。

首先我在本地机器上初始化应用程序:

ng new project && cd project &&  "put my Dockerfile there" && docker build -t my-ui && docker run.

我的 Dockerfile

FROM node

RUN npm install -g angular-cli@v1.0.0-beta.24 && npm cache clean && rm -rf ~/.npm

RUN mkdir -p /opt/client-ui/src
WORKDIR /opt/client-ui  

COPY package.json /opt/client-ui/
COPY angular-cli.json /opt/client-ui/
COPY tslint.json /opt/client-ui/

ADD src/ /opt/client-ui/src

RUN npm install
RUN ng build --prod --aot

EXPOSE 4200

ENV PATH="$PATH:/usr/local/bin/"    
CMD ["npm", "start"]

一切正常,问题是图片大小:939MB!!!我尝试使用 FROM: ubuntu:16.04 并在其上安装 NodeJs(它有效),但我的图像仍然有 ~ 450 MB。我知道 node:alpine 存在,但我无法在其中安装 angular-cli。

如何缩小图片尺寸?是否需要在 Dockerfile 中运行“npm install”和“ng build”?我希望在 localhost 上构建应用程序并将其复制到图像。我试图复制 dist dir 和 package.json 等文件,但它不起作用(应用程序启动失败)。谢谢。

【问题讨论】:

空间使用量从何而来? du -h 使用docker history <imagename>显示图像的所有层以查找空间的使用位置。 【参考方案1】:

对于生产,您不需要分发带有 Node.js、NPM 依赖项等的镜像。您只需要一个可用于启动数据卷容器的镜像,该容器提供编译源、发布源映射和其他资产,实际上不超过您通过 NPM 使用包重新分发的内容,您可以附加到您的网络服务器。

因此,对于您的 CI 主机,您可以选择一个 node:alpine 发行版并复制源代码并在其中安装依赖项,然后您可以重新使用该映像来运行测试构建的容器,直到您最终运行执行生产编译的容器,您可以命名。

docker run --name=compile-$RELEASE ci-$RELEASE npm run production

在容器中完成源代码编译后,运行一个容器,该容器附加了编译容器中的卷,并将源代码复制到容器上的一个卷中,并将其推送到上游的 Docker:

docker run --name=release-$RELEASE --volumes-from=compile-$RELEASE -v /srv/public busybox cp -R /myapp/dist /srv/public
docker commit release-$RELEASE release-$RELEASE myapp:$RELEASE

【讨论】:

【参考方案2】:

You can certainly use my alpine-ng image if you like.

You can also check out the dockerfile, if you want to try and modify it in some way.

很遗憾地通知您,即使基于 alpine,它仍然是 610MB。可以肯定的是,这是一个改进,但无法回避 Angular 编译器非常庞大的事实。

【讨论】:

【参考方案3】:

试试FROM mhart/alpine-node:base-6也许会奏效。

【讨论】:

以上是关于如何使用 NodeJs 缩小 Docker 镜像的大小的主要内容,如果未能解决你的问题,请参考以下文章

如何在docker里部署nodejs

如何通过docker编译vue项目

如何使用Docker将NodeJS应用程序与cron作业进行容器化?

Docker实践--部署Nodejs应用

带有混合基础镜像的 Docker 镜像

Docker实战--部署简单nodejs应用