Dockerfile RUN, CMD & ENTRYPOINT

  • Post author:
  • Post category:其他


在使用Dockerfile创建image时, 有几条指令比较容易混淆, RUN, CMD, ENTRYPOINT.
RUN是在building image时会运行的指令, 在Dockerfile中可以写多条RUN指令.
CMD和ENTRYPOINT则是在运行container 时会运行的指令, 都只能写一条, 如果写了多条, 则最后一条生效.
CMD和ENTRYPOINT的区别是:
CMD在运行时会被command覆盖, ENTRYPOINT不会被运行时的command覆盖, 但是也可以指定.
例如 :
Usage: docker run [OPTIONS] IMAGE [COMMAND] [ARG…]

–entrypoint=””            Overwrite the default entrypoint of the image
docker run postgres:9.3.5 psql
这里的psql就是command, 将覆盖Dockerfile的CMD, 但是不会覆盖ENTRYPOINT.
如果要覆盖ENTRYPOINT, 那么可以在docker run运行时输入



–entrypoint=”….”.



CMD和ENTRYPOINT一般用于制作具备后台服务的image, 例如apache, database等. 在使用这种image启动container时, 自动启动服务.



这几条指令的详细用法 :

RUN

RUN has 2 forms:


  • RUN <command>

    (the command is run in a shell –

    /bin/sh -c



    shell

    form)

  • RUN ["executable", "param1", "param2"]

    (

    exec

    form)

The

RUN

instruction will execute any commands in a new layer on top of the current image and commit the results. The resulting committed image will be used for the next step in the

Dockerfile

.

Layering

RUN

instructions and generating commits conforms to the core concepts of Docker where commits are cheap and containers can be created from any point in an image’s history, much like source control.

The

exec

form makes it possible to avoid shell string munging, and to

RUN

commands using a base image that does not contain

/bin/sh

.


Note

: To use a different shell, other than ‘/bin/sh’, use the

exec

form passing in the desired shell. For example,

RUN ["/bin/bash", "-c", "echo hello"]


Note

: The

exec

form is parsed as a JSON array, which means that you must use double-quotes (“) around words not single-quotes (‘).


Note

: Unlike the

shell

form, the

exec

form does not invoke a command shell. This means that normal shell processing does not happen. For example,

CMD [ "echo", "$HOME" ]

will not do variable substitution on

$HOME

. If you want shell processing then either use the

shell

form or execute a shell directly, for example:

CMD [ "sh", "-c", "echo", "$HOME" ]

.

The cache for

RUN

instructions isn’t invalidated automatically during the next build. The cache for an instruction like

RUN apt-get dist-upgrade -y

will be reused during the next build. The cache for

RUN

instructions can be invalidated by using the

--no-cache

flag, for example

docker build --no-cache

.

See the


Dockerfile

Best Practices guide

for more information.

The cache for

RUN

instructions can be invalidated by

ADD

instructions. See

below

for details.

Known Issues (RUN)


  • Issue 783

    is about file permissions problems that can occur when using the AUFS file system. You might notice it during an attempt to

    rm

    a file, for example. The issue describes a workaround.

CMD

The

CMD

instruction has three forms:


  • CMD ["executable","param1","param2"]

    (

    exec

    form, this is the preferred form)

  • CMD ["param1","param2"]

    (as

    default parameters to ENTRYPOINT

    )

  • CMD command param1 param2

    (

    shell

    form)

There can only be one

CMD

instruction in a

Dockerfile

. If you list more than one

CMD

then only the last

CMD

will take effect.


The main purpose of a

CMD

is to provide defaults for an executing container.

These defaults can include an executable, or they can omit the executable, in which case you must specify an

ENTRYPOINT

instruction as well.


Note

: If

CMD

is used to provide default arguments for the

ENTRYPOINT

instruction, both the

CMD

and

ENTRYPOINT

instructions should be specified with the JSON array format.


Note

: The

exec

form is parsed as a JSON array, which means that you must use double-quotes (“) around words not single-quotes (‘).


Note

: Unlike the

shell

form, the

exec

form does not invoke a command shell. This means that normal shell processing does not happen. For example,

CMD [ "echo", "$HOME" ]

will not do variable substitution on

$HOME

. If you want shell processing then either use the

shell

form or execute a shell directly, for example:

CMD [ "sh", "-c", "echo", "$HOME" ]

.

When used in the shell or exec formats, the

CMD

instruction sets the command to be executed when running the image.

If you use the

shell

form of the

CMD

, then the

<command>

will execute in

/bin/sh -c

:

FROM ubuntu
CMD echo "This is a test." | wc -

If you want to

run your


<command>


without a shell

then you must express the command as a JSON array and give the full path to the executable.

This array form is the preferred format of

CMD

.

Any additional parameters must be individually expressed as strings in the array:

FROM ubuntu
CMD ["/usr/bin/wc","--help"]

If you would like your container to run the same executable every time, then you should consider using

ENTRYPOINT

in combination with

CMD

. See


ENTRYPOINT


.

If the user specifies arguments to

docker run

then they will override the default specified in

CMD

.


Note

: don’t confuse

RUN

with

CMD

.

RUN

actually runs a command and commits the result;

CMD

does not execute anything at build time, but specifies the intended command for the image.

ENTRYPOINT

ENTRYPOINT has two forms:


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

    (

    exec

    form, the preferred form)

  • ENTRYPOINT command param1 param2

    (

    shell

    form)

There can only be one

ENTRYPOINT

in a

Dockerfile

. If you have more than one

ENTRYPOINT

, then only the last one in the

Dockerfile

will have an effect.

An

ENTRYPOINT

helps you to configure a container that you can run as an executable. That is, when you specify an

ENTRYPOINT

, then the whole container runs as if it was just that executable.

Unlike the behavior of the

CMD

instruction, The

ENTRYPOINT

instruction adds an entry command that will

not

be overwritten when arguments are passed to

docker run

. This allows arguments to be passed to the entry point, i.e.

docker run <image> -d

will pass the

-d

argument to the entry point.

You can specify parameters either in the

ENTRYPOINT

JSON array (as in “like an exec” above), or by using a

CMD

instruction. Parameters in the

ENTRYPOINT

instruction will not be overridden by the

docker run

arguments, but parameters specified via a

CMD

instruction will be overridden by

docker run

arguments.

Like a

CMD

, you can specify a plain string for the

ENTRYPOINT

and it will execute in

/bin/sh -c

:

FROM ubuntu
ENTRYPOINT ls -l

For example, that

Dockerfile

‘s image will

always

take a directory as an input and return a directory listing. If you wanted to make this optional but default, you could use a

CMD

instruction:

FROM ubuntu
CMD ["-l"]
ENTRYPOINT ["ls"]


Note

: The

exec

form is parsed as a JSON array, which means that you must use double-quotes (“) around words not single-quotes (‘).


Note

: Unlike the

shell

form, the

exec

form does not invoke a command shell. This means that normal shell processing does not happen. For example,

CMD [ "echo", "$HOME" ]

will not do variable substitution on

$HOME

. If you want shell processing then either use the

shell

form or execute a shell directly, for example:

CMD [ "sh", "-c", "echo", "$HOME" ]

.


Note

: It is preferable to use the JSON array format for specifying

ENTRYPOINT

instructions.