简体   繁体   中英

How to correctly install programs in docker?

I know that every line of RUN... will add a layer to the docker image and that it is recommended to make RUN commands connected with &&. But my question is:

Is better this:

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

Or this:

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

The first one creates just one layer but when a version of anything changes the image would have to start from the beginning, not from cash. The second approach will create more layers but when just the version of git changes only the git layer needs to be build again and all previous layers can be used from cash.

Both approaches are on the extreem, you need to try to minimize the layers for "reusability" at the same time to optimize for lower number of layers.

Based on your example, the build can be organized as follows:

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 \

Now I have only 2 layers, first one is bringing the OS packages and the second one dealing with the node.js packages. Now this can better be reused in other builds.

Once you have done this modification, you can move to multistage build where you will be able to better control and reuse the intermediate containers like in this example

I'd recommend:

  • Install all the OS packages in a single apk invocation: there is some overhead in starting the package manager (more noticeable with dpkg / apt ) and it is faster if you start it once and install several packages

  • If you need to run an update command, always run it in the same RUN command as your other package-manager steps. This avoids some trouble with Docker layer caching (again, very noticeable with apt ) where docker build doesn't re-run update , but then it does try to run a changed install step; when it tries to install a package using yesterday's package index, the upload of that package that happened today deleted yesterday's file and the download will fail.

  • Don't npm install single packages. That means your package.json file is incomplete. Add it there.

I've seen recommendations both ways as to whether or not to run a full upgrade . Keeping up-to-date on security fixes is important; the underlying base images on Docker Hub also update pretty regularly. So if your image is FROM alpine:latest , doing a docker build --pull will get you much of the effect of an explicit apk upgrade .

Stylistically, if I need any substantial number of packages, I find the list a little more maintainable if I sort it alphabetically and put one package on a line, but this is purely personal preference.

Putting this all together would transform your example into:

RUN apk update \
 && apk upgrade \
 && apk add \
      git \
      maven \
      nodejs \
      nodejs-npm \
      openjdk11 \
      openssh
COPY package.json package-lock.json . # includes @angular/cli
RUN npm ci

Don't be afraid to use multiple containers, if that makes sense. (What's your application that uses both Java and Node together; can it be split into two single-language parts?) Don't install unnecessary developer-oriented tools in your image. (Does your application invoke git while it's running; do you install a dependency directly from GitHub; or can you remove git ?) Don't try to run an ssh daemon in your container. (It breaks the "one process per container" rule which instantly makes things harder to manage; 90% of the SO examples have a hard-coded user password plus sudo rights, which is not really a security best practice; managing the credentials is essentially impossible.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM