Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to create a custom Docker image by Dockerfile

2025-01-31 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >

Share

Shulou(Shulou.com)06/01 Report--

Editor to share with you Dockerfile how to create a custom Docker image, I hope you will learn something after reading this article, let's discuss it together!

1. Overview

There are three ways to create a Docker image

Docker commit command: image generated by container

Dockerfile file + docker build command

Import the template for: OpenVZ from the local file system.

For a general description of these three ways, please refer to yeasy/docker_practice 's creating an image.

Having recently learned about the configuration of the Dockerfile file, here is a brief summary and a comparison of the differences between the CMD and ENTRYPOINT instructions that have been a little confusing before.

Summary of 2.Dockerfile files

Dockerfile consists of one line of command statements and supports comment lines that begin with #.

Generally speaking, Dockerfile is divided into four parts: basic image information, maintainer information, mirror operation instructions and instructions to execute when the container starts.

Four parts

Instruction

Basic image information

FROM

Maintainer information

MAINTAINER

Mirror operation instruction

RUN, COPY, ADD, EXPOSE, etc.

Execute instructions when the container is started

CMD 、 ENTRYPOINT

The first instruction in the Dockerfile file must be FROM, followed by instructions for various mirrored operations, and finally a command for CMD or ENTRYPOINT to specify the container to execute when it starts.

The following quotes yeasy/docker_practice 's introduction to the instructions in Dockerfile

Instruction

The general format of instructions is INSTRUCTION arguments, and instructions include FROM, MAINTAINER, RUN and so on.

FROM

The format is FROM or FROM:.

The first instruction must be a FROM instruction. Also, if you create multiple mirrors in the same Dockerfile, you can use multiple FROM instructions (one for each mirror).

MAINTAINER

Format is MAINTAINER, specifying maintainer information.

RUN

The format is RUN or RUN ["executable", "param1", "param2"].

The former will run the command / bin/sh-c in the shell terminal; the latter will be executed using exec. Specifying the use of other terminals can be done in a second way, such as RUN ["/ bin/bash", "- c", "echo hello"].

Each RUN instruction executes the specified command based on the current mirror and is submitted as a new mirror. You can use\ to wrap lines when the command is long.

CMD

Three formats are supported

CMD ["executable", "param1", "param2"] is executed using exec, recommended

CMD command param1 param2 is executed in / bin/sh and provided to applications that need to interact

Default parameters provided to ENTRYPOINT by CMD ["param1", "param2"]

Specifies the command to be executed when the container is started, and there can be only one CMD command per Dockerfile. If multiple commands are specified, only the last one will be executed.

If the user starts the container and specifies the command to run, the command specified by CMD will be overwritten.

EXPOSE

The format is EXPOSE [...].

Tell the port number exposed by the Docker server container for use by the interconnected system. When starting the container, the host will automatically assign a port to be forwarded to the specified port through-P _ ~ ~ Docker.

ENV

The format is ENV. Specify an environment variable that will be used by subsequent RUN instructions and maintained while the container is running.

For example

ENV PG_MAJOR 9.3

ENV PG_VERSION 9.3.4

RUN curl-SL http://example.com/postgres-$PG_VERSION.tar.xz | tar-xJC / usr/src/postgress & & …

ENV PATH / usr/local/postgres-$PG_MAJOR/bin:$PATH

ADD

The format is ADD.

This command copies the specified to the container. It can be a relative path to the directory where Dockerfile is located, a URL; or a tar file (which is automatically extracted to a directory).

COPY

The format is COPY.

Copy the local host's (the relative path of the directory where the Dockerfile is located) to the container.

COPY is recommended when using the local directory as the source directory.

ENTRYPOINT

There are two formats:

ENTRYPOINT ["executable", "param1", "param2"]

ENTRYPOINT command param1 param2 (executed in shell).

Configure the commands that are executed after the container starts and cannot be overridden by the parameters provided by docker run.

There can be only one ENTRYPOINT per Dockerfile, and when more than one is specified, only the last one takes effect.

VOLUME

The format is VOLUME ["/ data"].

Create a mount point that can be mounted from a local host or other container, which is generally used to store databases, data that needs to be maintained, and so on.

USER

The format is USER daemon.

Specify the user name or UID when the container is run, and subsequent RUN will also use the specified user.

When the service does not require administrator privileges, you can specify the running user through this command. And you can create the desired user before, for example: RUN groupadd-r postgres & & useradd-r-g postgres postgres. To obtain administrator privileges temporarily, you can use gosu instead of recommended sudo.

WORKDIR

The format is WORKDIR / path/to/workdir.

Configure the working directory for subsequent RUN, CMD, and ENTRYPOINT instructions.

Multiple WORKDIR instructions can be used, and subsequent commands, if the argument is a relative path, are based on the path specified by the previous command. For example

WORKDIR / a

WORKDIR b

WORKDIR c

RUN pwd

The final path is / a/b/c.

ONBUILD

The format is ONBUILD [INSTRUCTION].

Configure the operation instructions that are performed when the created mirror is used as the base mirror for other newly created mirrors.

For example, Dockerfile creates a mirror image-A with the following content.

[...]

ONBUILD ADD. / app/src

ONBUILD 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

Use the image of the ONBUILD directive. It is recommended to indicate it in the tag, such as ruby:1.9-onbuild.

3. Create a mirror

After writing the Dockerfile file, create a custom image by running the docker build command. The Docker build command format is as follows:

Docker build [options]

This command reads the Dockerfile under the specified path (including subdirectories) and sends all the contents under the path to the Docker server, which creates the image. Therefore, it is generally recommended that the directory where the Dockerfile is placed is an empty directory. You can also make Docker ignore directories and files under the path through the .dockerboards file (adding a matching pattern per line).

For example, the following Dockerfile sample is used to create a mirrored test:0.0.1, where the-t option is used to specify the mirrored tag. The Dockerfile file is as follows:

FROM ubuntu:14.04MAINTAINER lienhua34@xxx.comRUN mkdir / opt/lehRUN touch / opt/leh/testCMD echo "Hello lienhua34"

Now run the docker build command to generate the mirror test:0.0.1

Lienhua34@test$ sudo docker build-t test:0.0.1 .Sending build context to Docker daemon 3.072 kBStep 1: FROM ubuntu:14.04-> a5a467fddcb8Step 2: MAINTAINER lienhua34@163.com-> Running in ce9e7b02f075-> 332259a92e74Removing intermediate container ce9e7b02f075Step 3: RUN mkdir / opt/leh-> Running in e93f0a98040f-> 097e177cf37fRemoving intermediate container e93f0a98040fStep 4: RUN touch / opt/leh/test-> Running in f1531d3dea1a-> 0f68852f8356Removing intermediate container f1531d3dea1aStep 5: CMD echo "Hello lienhua34"- -- > Running in cf3c5ce2af46-- > 811ce27ce692Removing intermediate container cf3c5ce2af46Successfully built 811ce27ce692

Then start the container of the image to view the results

Lienhua34@test$ sudo docker imagesREPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZEtest 0.0.1 811ce27ce692 32 seconds ago 187.9 MBlienhua34@test$ sudo docker run-ti test:0.0.1Hello lienhua34

Each instruction in the Dockerfile file generates one layer of the image (Note: one image cannot exceed 127layers). The instructions in Dockerfile are executed one by one. Each step creates a new container, executes instructions in the container, and commits changes. When all instructions are executed, the final mirror id is returned.

Comparison of the differences between CMD and ENTRYPOINT instructions in 4.Dockerfile files

Both the CMD instruction and the ENTRYPOINT instruction are used to specify the command after the container is started for the mirror, so what are the advantages between them?

To better compare the differences between CMD instructions and ENTRYPOINT instructions, let's list the instructions for these two instructions again.

CMD

Three formats are supported

CMD ["executable", "param1", "param2"] is executed using exec, recommended

CMD command param1 param2 is executed in / bin/sh and provided to applications that need to interact

Default parameters provided to ENTRYPOINT by CMD ["param1", "param2"]

Specifies the command to be executed when the container is started, and there can be only one CMD command per Dockerfile. If multiple commands are specified, only the last one will be executed.

If the user starts the container and specifies the command to run, the command specified by CMD will be overwritten.

ENTRYPOINT

There are two formats:

ENTRYPOINT ["executable", "param1", "param2"]

ENTRYPOINT command param1 param2 (executed in shell).

Configure the commands that are executed after the container starts and cannot be overridden by the parameters provided by docker run.

There can be only one ENTRYPOINT per Dockerfile, and when more than one is specified, only the last one takes effect.

From the above instructions, we can see that there are two things in common:

You can specify how shell or exec functions are called to execute a command

When there are multiple CMD or ENTRYPOINT instructions, only the last one takes effect

And they have the following differences:

When the container specified by the differential 1:CMD instruction starts, the command can be overridden by the command specified by docker run, while the command specified by ENTRYPOINT instruction cannot be overwritten, but the parameters specified by docker run can be regarded as the parameters of the ENTRYPOINT specified command.

The differential 2:CMD instruction can set default parameters for the ENTRYPOINT instruction and can be overridden by the parameters specified by docker run

The above two differences are described in detail below.

4.1 difference 1

When the container specified by the CMD instruction starts, the command can be overridden by the command specified by docker run, while the command specified by the ENTRYPOINT instruction cannot be overridden, but the parameter specified by docker run is regarded as the parameter of the ENTRYPOINT specified command.

Here is an executable shell script named startup, which simply outputs command-line arguments. The content is as follows

#! / bin/bashecho "in startup, args: $@"

Specify the container startup command through CMD:

Now let's create a new Dockerfile file that copies the startup script to the container's / opt directory and uses the CMD directive to specify that the startup script be run when the container starts. Its contents are as follows

FROM ubuntu:14.04MAINTAINER lienhua34@xxx.comADD startup / optRUN chmod axix / opt/startupCMD ["/ opt/startup"]

Then we generate a test:latest image by running the docker build command

Lienhua34@test$ sudo docker build-t test .Sending build context to Docker daemon 4.096 kBStep 1: FROM ubuntu:14.04-> a5a467fddcb8Step 2: MAINTAINER lienhua34@163.com-- > Using cache-> 332259a92e74Step 3: ADD startup / opt-> 3c26b6a8ef1bRemoving intermediate container 87022b0f30c5Step 4: RUN chmod axix / opt/startup-- > Running in 4518ba223345-> 04d9b53d6148Removing intermediate container 4518ba223345Step 5: CMD / opt/startup-> Running in 64a07c2f5e64-- > 18a2d5066346Removing intermediate container 64a07c2f5e64Successfully built 18a2d5066346

Then use docker run to start two test:latest mirrored containers. The first docker run command does not specify the container startup command, and the second docker run command specifies that the container startup command is "/ bin/bash-c 'echo Hello'".

Lienhua34@test$ sudo docker run-ti-- rm=true testin startup, args: lienhua34@test$ sudo docker run-ti-- rm=true test / bin/bash-c 'echo Hello'Hello

As you can see from the above run results, the run command specified when the docker run command starts the container overrides the command specified by the CMD directive in the Dockerfile file.

Specify the container startup command through ENTRYPOINT:

Replace CMD in the above Dockerfile with ENTRYPOINT, as shown below

FROM ubuntu:14.04MAINTAINER lienhua34@xxx.comADD startup / optRUN chmod axix / opt/startupENTRYPOINT ["/ opt/startup"]

Similarly, generate a test:latest image by running docker build

Lienhua34@test$ sudo docker build-t test .Sending build context to Docker daemon 4.096 kBStep 1: FROM ubuntu:14.04-> a5a467fddcb8Step 2: MAINTAINER lienhua34@163.com-- > Using cache-- > 332259a92e74Step 3: ADD startup / opt-- > Using cache-- > 3c26b6a8ef1bStep 4: RUN chmod axix / opt/startup-- > Using cache-- > 04d9b53d6148Step 5: ENTRYPOINT / opt/startup-> Running in cdec60940ad7-- > 78f8aca2edc2Removing intermediate container cdec60940ad7Successfully built 78f8aca2edc2

Then use docker run to start two test:latest mirrored containers. The first docker run command does not specify the container startup command, and the second docker run command specifies that the container startup command is "/ bin/bash-c 'echo Hello'".

Lienhua34@test$ sudo docker run-ti-- rm=true testin startup, args: lienhua34@test$ sudo docker run-ti-- rm=true test / bin/bash-c 'echo Hello'in startup, args: / bin/bash-c echo Hello

From the above running results, it can be seen that the container running command specified by the docker run command can not override the command specified by the ENTRYPOINT instruction in the Dockerfile file, but is passed as a parameter to the command specified by the ENTRYPOINT instruction.

4.2 difference 2

The CMD directive can set default parameters for the ENTRYPOINT directive and can be overridden by the parameters specified by docker run

Also use the startup script above. Write the Dockerfile as follows

FROM ubuntu:14.04MAINTAINER lienhua34@xxx.com ADD startup / optRUN chmod axix / opt/startupENTRYPOINT ["/ opt/startup", "arg1"] CMD ["arg2"]

Run the docker build command to generate a test:latest image

Lienhua34@test$ sudo docker build-t test .Sending build context to Docker daemon 4.096 kBStep 1: FROM ubuntu:14.04-> a5a467fddcb8Step 2: MAINTAINER lienhua34@163.com-- > Using cache-- > 332259a92e74Step 3: ADD startup / opt-- > Using cache-- > 3c26b6a8ef1bStep 4: RUN chmod axix / opt/startup-- > Using cache-- > 04d9b53d6148Step 5: ENTRYPOINT / opt/startup arg1-> Running in 54947233dc3d-> 15a485253b4eRemoving intermediate container 54947233dc3dStep 6: CMD arg2-> Running in 18c43d2d90fd-> 4684ba457cc2Removing intermediate container 18c43d2d90fdSuccessfully built 4684ba457cc2

Next, run docker run to start the container of two test:latest images. The first docker run command does not specify a parameter, and the second docker run command specifies the parameter arg3. The result is as follows

Lienhua34@test$ sudo docker run-ti-rm=true testin startup, args: arg1 arg2lienhua34@test$ sudo docker run-ti-rm=true test arg3in startup, args: arg1 arg3

From the running results of the first container above, we can see that the CMD instruction sets the default parameters for the ENTRYPOINT instruction; from the running results of the second container, we can see that the parameters specified by the docker run command override the parameters specified by the CMD instruction.

4.3 pay attention

The default parameters provided by the CMD directive to the ENTRYPOINT directive are based on the mirror hierarchy, not on whether it is in the same Dockerfile file. This means that if Dockerfile specifies the startup command specified by ENTRYPOINT in the base image, the CMD in the Dockerfile still sets the default parameter for ENTRYPOINT in the base image.

For example, we have the following Dockerfile file

FROM ubuntu:14.04MAINTAINER lienhua34@xxx.com ADD startup / optRUN chmod axix / opt/startupENTRYPOINT ["/ opt/startup", "arg1"]

Generate a test:0.0.1 image by running the docker build command, and then create a container for the image to view the running result

Lienhua34@test$ sudo docker build-t test:0.0.1 .Sending build context to Docker daemon 6.144 kBStep 1: FROM ubuntu:14.04-> a5a467fddcb8Step 2: MAINTAINER lienhua34@163.com-- > Running in 57a96522061a-> c3bbf1bd8068Removing intermediate container 57a96522061aStep 3: ADD startup / opt-> f9884fbc7607Removing intermediate container 591a82b2f382Step 4: RUN chmod axix / opt/startup-- > Running in 7a19f10b5513-> 16c03869a764Removing intermediate container 7a19f10b5513Step 5: ENTRYPOINT / opt/startup arg1-> Running in b581c32b25c3-- > c6b1365afe03Removing Intermediate container b581c32b25c3Successfully built c6b1365afe03lienhua34roomtest $sudo docker run-ti-rm=true test:0.0.1in startup Args: arg1

Next, create a new Dockerfile file. The basic image is the newly generated test:0.0.1, and the string "in test:0.0.2" is specified through CMD to be printed through echo. The contents of the file are as follows

FROM test:0.0.1MAINTAINER lienhua34@xxx.comCMD ["/ bin/bash", "- c", "echo in test:0.0.2"]

Run the docker build command to generate a test:0.0.2 image, and then start a container of test:0.0.2 images by running docker run to view the results

Lienhua34@test$ sudo docker build-t test:0.0.2 .Sending build context to Docker daemon 6.144 kBStep 1: FROM test:0.0.1-- > c6b1365afe03Step 2: MAINTAINER lienhua34@163.com-- > Running in deca95cf4c15-- > 971b5a819b48Removing intermediate container deca95cf4c15Step 3: CMD / bin/bash-c echo in test:0.0.2-- > Running in 4a31c4652e1e-- > 0ca06ba31405Removing intermediate container 4a31c4652e1eSuccessfully built 0ca06ba31405lienhua34diagnostic test $sudo docker run-ti-- rm=true test:0.0.2in startup Args: arg1 / bin/bash-c echo in test:0.0.2

As you can see from the above results, the container started by the mirror test:0.0.2 does not print the string "in test:0.0.2", but takes the command specified by the CMD directive as the parameter to run the script startup specified by ENTRYPOINT in the base image test:0.0.1.

After reading this article, I believe you have some understanding of "how Dockerfile creates a custom Docker image". If you want to know more about it, you are welcome to follow the industry information channel. Thank you for reading!

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.

Share To

Servers

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report