您的位置:首页 > 运维架构 > Docker

Dockerfile RUN, CMD & ENTRYPOINT

2016-08-26 14:55 633 查看
转自: http://blog.163.com/digoal@126/blog/static/163877040201410411715832/
在使用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 durin
4000
g 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
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 willnot 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.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  docker