如何在docker中正确安装程序?
我知道,如何在docker中正确安装程序?,docker,dockerfile,Docker,Dockerfile,我知道,RUN…的每一行都会给docker图像添加一个层,建议将RUN命令与&&连接起来。但我的问题是: 这样更好: RUN apk update && apk upgrade \ && apk add openssh \ && apk add --update nodejs nodejs-npm \ && npm install -g @angular/cli \ && apk add openjdk11 \ &a
RUN…
的每一行都会给docker图像添加一个层,建议将RUN命令与&&连接起来。但我的问题是:
这样更好:
RUN apk update && apk upgrade \
&& apk add openssh \
&& apk add --update nodejs nodejs-npm \
&& npm install -g @angular/cli \
&& apk add openjdk11 \
&& apk add maven \
&& apk add git
或者这个:
RUN apk update && apk upgrade
RUN apk add openssh
RUN apk add --update nodejs nodejs-npm
RUN npm install -g @angular/cli
RUN apk add openjdk11
RUN apk add maven
RUN apk add git
第一个只创建一层,但当任何版本的图像发生更改时,必须从头开始,而不是从现金开始。第二种方法将创建更多的层,但当仅更改git版本时,只需重新构建git层,并且可以从现金中使用以前的所有层。这两种方法都在extreem上,您需要尝试最小化层以实现“可重用性”,同时优化以减少层数 根据您的示例,构建可以按如下方式组织:
RUN apk update && apk upgrade \
&& apk add openssh \
&& apk add --update nodejs nodejs-npm \
&& apk add openjdk11 \
&& apk add maven \
&& apk add git
RUN npm install -g @angular/cli \
现在我只有两层,第一层是操作系统包,第二层是处理node.js
包。现在,这可以更好地在其他构建中重用
完成此修改后,您可以转到多级构建,这样您就可以更好地控制和重用中间容器,如图所示。这两种方法都在extreem上,您需要尝试最小化“可重用性”的层,同时优化较少的层数 根据您的示例,构建可以按如下方式组织:
RUN apk update && apk upgrade \
&& apk add openssh \
&& apk add --update nodejs nodejs-npm \
&& apk add openjdk11 \
&& apk add maven \
&& apk add git
RUN npm install -g @angular/cli \
现在我只有两层,第一层是操作系统包,第二层是处理node.js
包。现在,这可以更好地在其他构建中重用
完成此修改后,您可以转到多级构建,在那里您将能够更好地控制和重用中间容器,就像我建议的那样:
- 在单个
调用中安装所有操作系统软件包:启动软件包管理器时会有一些开销(在apk
/dpkg
中更明显),如果启动一次并安装几个软件包,速度会更快apt
- 如果需要运行
命令,请始终以与其他package manager步骤相同的update
命令运行该命令。这避免了Docker层缓存的一些问题(同样,在run
中非常明显),其中apt
不会重新运行Docker build
,但它会尝试运行更改后的update
安装步骤;当它尝试使用昨天的包索引安装包时,今天发生的包上载删除了昨天的文件,下载将失败
- 不要
npm安装单个软件包。这意味着您的
文件不完整。把它加在那里package.json
升级
,我已经看到了两种建议。保持最新的安全补丁是很重要的;Docker Hub上的基础映像也会定期更新。因此,如果您的图像是来自alpine:latest的,那么进行docker build--pull
将使您获得显式apk升级的大部分效果
从风格上讲,如果我需要大量的软件包,我会发现如果我按字母顺序排序并将一个软件包放在一行中,列表会更易于维护,但这纯粹是个人喜好
将这一切放在一起会将您的示例转化为:
运行apk更新\
&&apk升级\
&&apk地址\
吉特\
马文\
nodejs\
nodejsnpm\
openjdk11\
openssh
复制package.json package-lock.json.#包括@angular/cli
运行npm ci
如果有意义的话,不要害怕使用多个容器。(什么是同时使用Java和Node的应用程序;可以将其拆分为两个单一语言部分?)不要在映像中安装不必要的面向开发人员的工具。(应用程序是否在运行时调用了git
;是否直接从GitHub安装依赖项;或者是否可以删除git
?)不要尝试在容器中运行ssh守护程序。(它打破了“每个容器一个进程”的规则,这会立即使事情变得更难管理;90%的SO示例都有硬编码的用户密码和sudo权限,这并不是真正的安全最佳做法;管理凭据基本上是不可能的。)我建议:
- 在单个
apk
调用中安装所有操作系统软件包:启动软件包管理器时会有一些开销(在dpkg
/apt
中更明显),如果启动一次并安装几个软件包,速度会更快
- 如果需要运行
update
命令,请始终以与其他package manager步骤相同的run
命令运行该命令。这避免了Docker层缓存的一些问题(同样,在apt
中非常明显),其中Docker build
不会重新运行update
,但它会尝试运行更改后的安装步骤;当它尝试使用昨天的包索引安装包时,今天发生的包上载删除了昨天的文件,下载将失败
- 不要
npm安装单个软件包。这意味着您的package.json
文件不完整。把它加在那里
关于是否运行完整的升级
,我已经看到了两种建议。保持最新的安全补丁是很重要的;Docker Hub上的基础映像也会定期更新。因此,如果您的图像是来自alpine:latest的,那么进行docker build--pull
将使您获得显式apk升级的大部分效果
从风格上讲,如果我需要大量的软件包,我会发现如果我按字母顺序排序并将一个软件包放在一行中,列表会更易于维护,但这纯粹是个人喜好
把这些放在一起