In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-15 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >
Share
Shulou(Shulou.com)06/01 Report--
How to view Dockerfile best practices, in view of this problem, this article introduces the corresponding analysis and answers in detail, hoping to help more partners who want to solve this problem to find a simpler and easier way.
Although Dockerfile simplifies the process of building images and makes it possible to version control, improper use of Dockerfile can cause a lot of problems:
The docker image is too large. If you often use mirrors or build mirrors, you are bound to encounter large mirrors, some of which can even reach a few gigabytes.
The build time of the docker image is too long. Each build takes a long time, which can be a big problem in places where you need to build images (such as unit tests) frequently
Repeat the work. Most of the content between multiple mirror builds is exactly the same and repeated, but it has to be done each time, which is a waste of time and resources.
General guidelines and recommendations containers should be short-lived
The container model is a process, not a machine, and does not require boot initialization. Run when needed, stop when not needed, be able to delete and rebuild, and minimize configuration and startup.
Use the .dockerkeeper file
In docker build, ignoring some useless files and directories can speed up the build. Such as the .git directory. The definition of dockerignore is similar to gitignore. For specific usage, please refer to the link.
Avoid installing unnecessary installation packages
To reduce the complexity, size, and build time of the image, you should avoid installing useless packages.
Each container runs only one process
A container runs only one process. Containers play the role of isolating applications and isolating data. different applications run in different containers to make the vertical expansion of the cluster and the reuse of containers easier. When you need multiple application interactions, use the link command to combine or use docker-compose.
Minimize the number of layers
You need to strike a balance between the readability of Dockerfile and the number of mirror layers. It is not recommended to use too many mirror layers.
Multiline commands are sorted alphabetically
Alphabetical sorting of command lines helps avoid repetitive execution and improve Dockerfile readability. Apt-get update should be combined with apt-get install, with a backslash (\) for line breaks. For example:
RUN apt-get update & & apt-get install-y\ bzr\ cvs\ git\ mercurial\ subversion build cache
Each instruction of Dockerfile submits the result as a new mirror. The next instruction is built based on a mirror image of the previous instruction. If a mirror has the same parent image and instruction (except ADD), Docker will use the mirror instead of executing the instruction, that is, caching.
Therefore, in order to make effective use of the cache, try to keep the Dockerfile consistent, and put the same in front and often change at the end.
If you don't want to use caching, add the parameter-- no-cache=true-- when you execute docker build.
The rules for Docker matching images to determine whether to use caching are as follows:
Starting with the underlying images that exist in the cache, compare all the child images to see if the instructions they build are exactly the same as the current ones. If it is inconsistent, the cache does not match.
In most cases, it is sufficient to compare instructions in Dockerfile. However, specific instructions require more judgment.
In the ADD COPY directive, the files to be added to the image are also checked. Usually check the checksum (checksum) of the file.
Cache matching checks do not check files in the container. For example, when a file in the container is updated with the RUN apt-get-y update command, it is not used by the cache checking policy as a basis for cache matching.
Time zone
The time zone used by the official Image is basically the standard UTC time. If the container wants to use Chinese standard time, the Debian-based system is added to the Dockerfile.
RUN ln-sf / usr/share/zoneinfo/Asia/Shanghai / etc/localtimeRUN echo "Asia/Shanghai" > > / etc/timezone
Centos-based system is added to Dockerfile
RUN ln-sf / usr/share/zoneinfo/Asia/Shanghai / etc/localtime modify the default source
Sometimes you may feel that the official source update or software installation is slow. You can modify the official default source in Dockerfile. For example, if alpine wants to use Ali source, you can add it to Dockerfile:
RUN echo-e "http://mirrors.aliyun.com/alpine/v3.5/main\nhttp://mirrors.aliyun.com/alpine/v3.5/community" > / etc/apk/repositoriesDockerfile instruction FROM
It is recommended to use the image in the official repository as the base image.
RUN
Write complex or overly long RUN statements in the form of multiple lines ending with\ to improve readability and maintainability.
Apt-get update and apt-get install are executed together, otherwise an exception will occur in apt-get install.
Avoid running apt-get upgrade or dist-upgrade. In unprivileged containers, many necessary packages cannot be upgraded properly. If the basic image is out of date, you should contact the maintainer. It is recommended that apt-get update & & apt-get install-y package-a package-b be updated first and then install the latest software package.
RUN apt-get update & & apt-get install-y\ aufs-tools\ automake\ build-essential\ curl\ dpkg-sig\ libcap-dev\ libsqlite3-dev\ mercurial\ reprepro\ ruby1.9.1\ ruby1.9.1-dev\ s3cmdlines 1.1.*\ & & rm-rf / var/lib/apt/lists/*
In addition, you can reduce the image size by removing / var/lib/apt/lists.
Note: the official Ubuntu and Debian run apt-get clean automatically, so there is no need to explicitly call
CMD
Formats such as CMD ["executable", "param1", "param2"] are recommended. If the image is used to run the service, you need to use CMD ["apache2", "- DFOREGROUND"], and the instructions in this format apply to any service image.
ENTRYPOINT
ENTRYPOINT should be used as the main command for mirroring, and use CMD as the default setting, taking s3cmd as an example:
ENTRYPOINT ["s3cmd"] CMD ["--help"]
Get help:
Docker run s3cmd
Or execute the command:
Docker run s3cmd ls s3://mybucket
This is useful when the image name is the same as the program name.
ENTRYPOINT can also start custom scripts: define scripts:
#! / bin/bashset-eif ["$1" = 'postgres']; then chown-R postgres "$PGDATA" if [- z "$(ls-A" $PGDATA ")"]; then gosu postgres initdb fiexec gosu postgres "$@" fiexec "$@"
Note: this script uses the exec command to ensure that the final application starts with a PID of 1 in the container. This script allows the container to receive Unix signals.
COPY. / docker-entrypoint.sh / ENTRYPOINT ["/ docker-entrypoint.sh"]
This script provides users with a variety of ways to interact with Postgres:
You can simply start Postgres:
Docker run postgres .
Or run postgres and pass in parameters:
Docker run postgres postgres-help.
You can even start a completely different program from the image, such as Bash:
Docker run-- rm-it postgres bashEXPOSE
The default port should be used whenever possible. For example, the Apache web service uses EXPOSE 80 and MongoDB uses EXPOSE 27017.
ENV
You can use ENV to update the PATH environment variable. For example, ENV PATH / usr/local/nginx/bin:$PATH ensures that CMD ["nginx"] is working properly.
ENV can also provide environment variables required by the program, such as Postgres's PGDATA.
ENV can set information such as version. Make version information easier to maintain.
ENV PG_MAJOR 9.3ENV PG_VERSION 9.3.4RUN curl-SL http://example.com/postgres-$PG_VERSION.tar.xz | tar-xJC / usr/src/postgress & & … ENV PATH / usr/local/postgres-$PG_MAJOR/bin:$PATHADD or COPY
Although the function of ADD is similar to that of COPY, COPY is recommended. COPY only supports basic file copy functions, which is more controllable. ADD has more specific features, such as automatic extraction of tar files and support for URL. ADD is usually used when you need to extract files from tarball to a container.
If multiple files are used in Dockerfile, each file should use a separate COPY directive. In this way, only instructions with file changes will not use caching.
In order to control the size of the image, it is not recommended to use the ADD directive to get the URL file. The right thing to do is to use wget or curl in the RUN directive to get the file and delete the file when it is not needed.
RUN mkdir-p / usr/src/things\ & & curl-SL http://example.com/big.tar.gz\ | tar-xJC / usr/src/things\ & & make-C / usr/src/things allVOLUME
VOLUME is typically used as a data volume, and VOLUME should be used to mount any variable files, including database files, code bases, or files / directories created by containers.
USER
If the service does not require privileges to run, use the USER directive to switch to a non-root user. Use * * RUN groupadd-r mysql & & useradd-r-g mysql mysql * * to switch users with USER mysql
Avoid using sudo to elevate privileges, because it creates far more problems than it can solve. If you really need such a feature, you can choose to use gosu.
Finally, don't switch users repeatedly. Reduce unnecessary layers.
WORKDIR
For clarity and maintainability, WORKDIR should be used to define the work path. It is recommended to use WORKDIR instead of RUN cd. Instructions like & & do-something.
ONBUILD
Other instructions in Dockerfile are prepared to customize the current image, but ONBUILD is prepared to help others customize themselves.
The ONBUILD instruction is used to set some triggered instructions to perform some operations when the image is used as the basic image to create another image (that is, when the FROM in Dockerfile is the current image). The instruction defined in ONBUILD will be executed after the FROM instruction used to generate other mirrored Dockerfile files. Any of the instructions described above can be used for ONBUILD instructions and can be used to perform operations that change due to the environment. Make the mirror more versatile.
Note:
Instructions defined in ONBUILD are not executed in the currently mirrored build.
You can view the contents of a mirror ONBUILD directive definition by viewing the Onbuild key of the docker inspect command execution result.
The instruction defined in ONBUILD will be executed as part of the FROM instruction referencing the mirrored Dockerfile file, and the execution order will be in the order defined by ONBUILD. If any instruction defined in ONBUILD fails, it will interrupt the FROM instruction and cause the entire build to fail. When all the instructions defined in ONBUILD are completed successfully, the execution of build will continue in the normal order.
The directives defined in ONBUILD are not inherited into the currently referenced image, that is, all referenced ONBUILD directives will be cleared when the mirror referencing ONBUILD is created.
Nesting is not allowed in ONBUILD instructions, such as ONBUILD ONBUILD ADD. / data is not allowed.
The ONBUILD instruction does not execute the FROM or MAINTAINER instructions it defines.
For example, Dockerfile creates a mirror image-A with the following:
[...] ONBUILD ADD. / app/srcONBUILD RUN / usr/local/bin/python-build-- dir / app/src [...]
If you create a new image based on image-A, when you specify the base image using FROM image-An in the new Dockerfile, the content of the ONBUILD instruction will be executed automatically, which is equivalent to adding two instructions later.
FROM image-A#Automatically run the followingADD. / app/srcRUN / usr/local/bin/python-build-- dir / app/src usage scenario Node.js
Suppose we want to make a mirror image of the application written by Node.js. We all know that Node.js uses npm for package management, and all dependencies, configuration, startup information, etc., are placed in the package.json file. After getting the program code, you need to npm install before you can get all the needed dependencies. You can then launch the application through npm start. Therefore, Dockerfile is generally written as follows:
FROM node:slimRUN mkdir / appWORKDIR / appCOPY. / package.json / appRUN ["npm", "install"] COPY. / app/CMD ["npm", "start"]
Put this Dockerfile in the root directory of the Node.js project, and after building the image, you can directly start the container to run. But what if we have a second Node.js project? All right, then copy this Dockerfile to the second project. What if there is a third project? Copy it again? The more copies of the file, the more difficult it is to version control, so let's continue to look at the maintenance of such scenarios.
If the first Node.js project finds a problem in the Dockerfile during the development process, such as typing the wrong word, or needs to install an additional package, then the developer fixes the Dockerfile, builds it again, and the problem is solved. The first project is fine, but what about the second project? Although the initial Dockerfile is copied and pasted from the first project, their Dockerfile is not fixed because the first project is fixed, and the Dockerfile of the second project is automatically fixed.
So can we make a basic image and then use this basic image for each project? In this way, the basic image is updated, and each project does not need to synchronize the changes of Dockerfile. After reconstruction, it inherits the update of the basic image? All right, well, let's see what happens. Then the Dockerfile above will become:
FROM node:slimRUN mkdir / appWORKDIR / appCMD ["npm", "start"]
Here we take out the build instructions related to the project and put them into the sub-project. Assuming that the name of the basic image is my-node, the Dockerfile in each project will be:
FROM my-nodeCOPY. / package.json / appRUN ["npm", "install"] COPY. / app/
After the basic image changes, each project uses this Dockerfile to rebuild the image and inherits the update of the basic image.
So, is the problem solved? No. To be exact, it's only half solved. What if there is something in this Dockerfile that needs to be adjusted? For example, what if npm install needs to add some parameters uniformly? It is impossible to put this line of RUN into the basic image, because it involves the. / package.json of the current project, do you have to modify it one by one? Therefore, making the basic image in this way only solves the problem of changes in the first four instructions of the original Dockerfile, while the changes of the last three instructions are completely impossible to deal with.
ONBUILD can solve this problem. Let's rewrite the Dockerfile of the basic image with ONBUILD:
FROM node:slimRUN mkdir / appWORKDIR / appONBUILD COPY. / package.json / appONBUILD RUN ["npm", "install"] ONBUILD COPY. / app/CMD ["npm", "start"]
This time we go back to the original Dockerfile, but this time add the project-related instructions to ONBUILD so that these three lines are not executed when building the underlying image. Then the Dockerfile of each project becomes simply:
FROM my-node
Yes, it's the only line. When the image is built with this one-line Dockerfile in each project directory, the three lines of ONBUILD of the previous basic image will be executed, successfully copying the code of the current project into the image, and executing npm install for the project to generate the application image.
Maven
For compiled projects like Java,Go, you can use the ONBUILD directive to optimize Dockerfile.
Write the onbuild Dockerfile as follows:
FROM maven:3-jdk-8RUN mkdir-p / usr/src/appWORKDIR / usr/src/appONBUILD ADD. / usr/src/appONBUILD RUN mvn install
Then the Dockerfile of all projects that rely on maven compilation can be simplified to the following form:
FROM maven:3.3-jdk-8-onbuildCMD ["java", "- jar", "/ usr/src/app/target/demo-1.0-SNAPSHOT-jar-with-dependencies.jar"] this is the answer to the question on how to view Dockerfile best practices. I hope the above content can be of some help to you. If you still have a lot of questions to solve, you can follow the industry information channel for more related knowledge.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.