exec
执行
RUN ["executable","param1","param2"]
RUN
可以执行任何命令,然后在当前镜像上创建一个新层并提交。提交后的结果镜像将会用在Dockerfile
文件的下一步。
通过RUN
执行多条命令时,可以通过
换行执行:
RUN /bin/bash -c 'source $HOME/.bashrc;
echo $HOME'
也可以在同一行中,通过分号分隔命令:
RUN /bin/bash -c 'source $HOME/.bashrc; echo $HOME'
RUN
指令创建的中间镜像会被缓存,并会在下次构建中使用。如果不想使用这些缓存镜像,可以在构建时指定--no-cache
参数,如:docker build --no-cache
。
5.3?CMD
CMD
用于指定在容器启动时所要执行的命令。CMD
有以下三种格式:
CMD ["executable","param2"]
CMD ["param1","param2"]
CMD command param1 param2
CMD
不同于RUN
,CMD
用于指定在容器启动时所要执行的命令,而RUN
用于指定镜像构建时所要执行的命令。
CMD
与RUN
在功能实现上也有相似之处。如:
docker run -t -i itbilu/static_web_server /bin/true
等价于:
cmd ["/bin/true"]
CMD
在Dockerfile
文件中仅可指定一次,指定多次时,会覆盖前的指令。
另外,docker run
命令也会覆盖Dockerfile
中CMD
命令。如果docker run
运行容器时,使用了Dockerfile
中CMD
相同的命令,就会覆盖Dockerfile
中的CMD
命令。
如,我们在构建镜像的Dockerfile
文件中使用了如下指令:
CMD ["/bin/bash"]
使用docker build
构建一个新镜像,镜像名为itbilu/test
。构建完成后,使用这个镜像运行一个新容器,运行效果如下:
$ sudo docker run -i -t itbilu/test
root@e3597c81aef4:/#
在使用docker run
运行容器时,我们并没有在命令结尾指定会在容器中执行的命令,这时Docker就会执行在Dockerfile
的CMD
中指定的命令。
如果不想使用CMD
中指定的命令,就可以在docker run
命令的结尾指定所要运行的命令:
$ sudo docker run -i -t itbilu/test /bin/ps
PID TTY TIME CMD
1 ? 00:00:00 ps
这时,docker run
结尾指定的/bin/ps
命令覆盖了Dockerfile
的CMD
中指定的命令。
5.4?ENTRYPOINT
ENTRYPOINT
用于给容器配置一个可执行程序。也就是说,每次使用镜像创建容器时,通过ENTRYPOINT
指定的程序都会被设置为默认程序。ENTRYPOINT
有以下两种形式:
ENTRYPOINT ["executable","param2"]
ENTRYPOINT command param1 param2
ENTRYPOINT
与CMD
非常类似,不同的是通过docker run
执行的命令不会覆盖ENTRYPOINT
,而docker run
命令中指定的任何参数,都会被当做参数再次传递给ENTRYPOINT
。Dockerfile
中只允许有一个ENTRYPOINT
命令,多指定时会覆盖前面的设置,而只执行最后的ENTRYPOINT
指令。
docker run
运行容器时指定的参数都会被传递给ENTRYPOINT
,且会覆盖CMD
命令指定的参数。如,执行docker run 时,-d
参数将被传递给入口点。
也可以通过docker run --entrypoint
重写ENTRYPOINT
入口点。
如:可以像下面这样指定一个容器执行程序:
ENTRYPOINT ["/usr/bin/nginx"]
完整构建代码:
# Version: 0.0.3
FROM ubuntu:16.04
MAINTAINER 何民三 "cn.liuht@gmail.com"
RUN apt-get update
RUN apt-get install -y nginx
RUN echo 'Hello World,我是个容器'
> /var/www/html/index.html
ENTRYPOINT ["/usr/sbin/nginx"]
EXPOSE 80
使用docker build
构建镜像,并将镜像指定为itbilu/test
:
$ sudo docker build -t="itbilu/test" .
构建完成后,使用itbilu/test
启动一个容器:
$ sudo docker run -i -t itbilu/test -g "daemon off;"
在运行容器时,我们使用了-g "daemon off;"
,这个参数将会被传递给ENTRYPOINT
,最终在容器中执行的命令为/usr/sbin/nginx -g "daemon off;"
。
5.5?LABEL
LABEL
用于为镜像添加元数据,元数以键值对的形式指定:
LABEL
使用LABEL
指定元数据时,一条LABEL
指定可以指定一或多条元数据,指定多条元数据时不同元数据之间通过空格分隔。推荐将所有的元数据通过一条LABEL
指令指定,以免生成过多的中间镜像。
如,通过LABEL
指定一些元数据:
LABEL version="1.0" description="这是一个Web服务器" by="IT笔录"
指定后可以通过docker inspect
查看:
$sudo docker inspect itbilu/test
"Labels": {
"version": "1.0","description": "这是一个Web服务器","by": "IT笔录"
},
注意;Dockerfile
中还有个MAINTAINER
命令,该命令用于指定镜像作者。但MAINTAINER
并不推荐使用,更推荐使用LABEL
来指定镜像作者。如:
LABEL maintainer="itbilu.com"
5.6?EXPOSE
EXPOSE
用于指定容器在运行时监听的端口:
EXPOSE
EXPOSE
并不会让容器的端口访问到主机。要使其可访问,需要在docker run
运行容器时通过-p
来发布这些端口,或通过-P
参数来发布EXPOSE
导出的所有端口。
5.7?ENV
ENV
用于设置环境变量,其有以下两种设置形式:
ENV
如,通过ENV
设置一个环境变量:
ENV ITBILU_PATH /home/itbilu/
设置后,这个环境变量在ENV
命令后都可以使用。如:
WORKERDIR $ITBILU_PATH
这些环境变量不仅可以构建镜像过程使用,使用该镜像创建的容器中也可以使用。如:
$ docker run -i -t itbilu/test
root@196ca123c0c3:/# cd $ITBILU_PATH
root@196ca123c0c3:/home/itbilu#
5.8?ADD
ADD
用于复制构建环境中的文件或目录到镜像中。其有以下两种使用方式:
ADD
通过ADD
复制文件时,需要通过来指定目标位置。URL,但不能访问构建上下文之外的文件或目录。
如,通过ADD
复制一个网络文件:
ADD http://wordpress.org/latest.zip $ITBILU_PATH
在上例中,$ITBILU_PATH
是我们使用ENV
指定的一个环境变量。
另外,如果使用的是本地归档文件(gzip
、bzip2
、xz
)时,Docker会自动进行解包操作,类似使用tar -x
。
5.9?COPY
COPY
同样用于复制构建环境中的文件或目录到镜像中。其有以下两种使用方式:
COPY
COPY
指令非常类似于ADD
,不同点在于COPY
只会复制构建目录下的文件,不能使用URL
也不会进行解压操作。
5.10?VOLUME
VOLUME
用于创建挂载点,即向基于所构建镜像创始的容器添加卷:
VOLUME ["/data"]
一个卷可以存在于一个或多个容器的指定目录,该目录可以绕过联合文件系统,并具有以下功能:
- 卷可以容器间共享和重用
- 容器并不一定要和其它容器共享卷
- 修改卷后会立即生效
- 对卷的修改不会对镜像产生影响
- 卷会一直存在,直到没有任何容器在使用它
VOLUME
让我们可以将源代码、数据或其它内容添加到镜像中,而又不并提交到镜像中,并使我们可以多个容器间共享这些内容。
如,通过VOLUME
创建一个挂载点:
ENV ITBILU_PATH /home/itbilu/
VOLUME [$ITBILU_PATH]
构建的镜像,并指定镜像名为itbilu/test
。构建镜像后,使用新构建的运行一个容器。运行容器时,需-v
参将能本地目录绑定到容器的卷(挂载点)上,以使容器可以访问宿主机的数据。
$ sudo docker run -i -t -v ~/code/itbilu:/home/itbilu/ itbilu/test
root@31b0fac536c4:/# cd /home/itbilu/
root@31b0fac536c4:/home/itbilu# ls
README.md app.js bin config.js controller db demo document lib minify.js node_modules package.json public routes test views
如上所示,我们已经可以容器的/home/itbilu/
目录下访问到宿主机~/code/itbilu
目录下的数据了。
5.11?USER
USER
用于指定运行镜像所使用的用户:
USER daemon
使用USER
指定用户时,可以使用用户名、UID
或GID
,或是两者的组合。以下都是合法的指定试:
USER user
USER user:group
USER uid
USER uid:gid
USER user:gid
USER uid:group
使用USER
指定用户后,Dockerfile
中其后的命令RUN
、CMD
、ENTRYPOINT
都将使用该用户。镜像构建完成后,通过docker run
运行容器时,可以通过-u
参数来覆盖所指定的用户。
5.12?WORKDIR
WORKDIR
用于在容器内设置一个工作目录:
WORKDIR /path/to/workdir
通过WORKDIR
设置工作目录后,Dockerfile
中其后的命令RUN
、CMD
、ENTRYPOINT
、ADD
、COPY
等命令都会在该目录下执行。
如,使用WORKDIR
设置工作目录:
WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd
在以上示例中,pwd
最终将会在/a/b/c
目录中执行。
在使用docker run
运行容器时,可以通过-w
参数覆盖构建时所设置的工作目录。
5.13?ARG
ARG
用于指定传递给构建运行时的变量:
ARG
如,通过ARG
指定两个变量:
ARG site
ARG build_user=IT笔录
以上我们指定了site
和build_user
两个变量,其中build_user
指定了默认值。在使用docker build
构建镜像时,可以通过--build-arg 参数来指定或重设置这些变量的值。
$ sudo docker build --build-arg site=itiblu.com -t itbilu/test .
这样我们构建了itbilu/test
镜像,其中site
会被设置为itbilu.com
,由于没有指定build_user
,其值将是默认值IT笔录
。
5.14?ONBUILD
ONBUILD
用于设置镜像触发器:
ONBUILD [INSTRUCTION]
当所构建的镜像被用做其它镜像的基础镜像,该镜像中的触发器将会被钥触发。
如,当镜像被使用时,可能需要做一些处理:
[...]
ONBUILD ADD . /app/src
ONBUILD RUN /usr/local/bin/python-build --dir /app/src
[...]
5.15?STOPSIGNAL
STOPSIGNAL
用于设置停止容器所要发送的系统调用信号:
STOPSIGNAL signal
所使用的信号必须是内核系统调用表中的合法的值,如:9
、SIGKILL
。
5.16?SHELL
SHELL
用于设置执行命令(shell
式)所使用的的默认shell
类型:
SHELL ["executable","parameters"]
SHELL
在Windows环境下比较有用,Windows下通常会有cmd
和powershell
两种shell
,可能还会有sh
。这时就可以通过SHELL
来指定所使用的shell
类型:
FROM microsoft/windowsservercore
# Executed as cmd /S /C echo default
RUN echo default
# Executed as cmd /S /C powershell -command Write-Host default
RUN powershell -command Write-Host default
# Executed as powershell -command Write-Host hello
SHELL ["powershell","-command"]
RUN Write-Host hello
# Executed as cmd /S /C echo hello
SHELL ["cmd","/S"","/C"]
RUN echo hello
(编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!