Dockerfile详解

本博客链接:https://security.blog.csdn.net/article/details/111321846

一、基本结构

Dockerfile 由一行行命令语句组成,并且支持以#开头的注释行。

一般Dockerfile分为四部分:基础镜像信息、维护者信息、镜像操作指令、容器启动时执行指令。

例:

# 基础镜像信息,必须放在第一行
FROM ubuntu

# 维护者信息,可以不写
MAINTAINER docker_user docker_user@email.com

# 镜像操作指令
RUN echo "deb http://archive.ubuntu.com/ubuntu/ raring main universe" >> /etc/apt/sources.list
RUN apt-get update && apt-get install -y nginx
RUN echo "\ndaemon off;" >> /etc/nginx/nginx.conf

# 容器启动时执行的指令
CMD /usr/sbin/nginx

其中,一开始必须指明所基于的镜像名称,接下来推荐说明维护者信息。

后面则是镜像操作指令,例如RUN指令,RUN指令将对镜像执行跟随的命令。每运行一条RUN指令,镜像添加新的一层,并提交。需要注意的是,一个镜像不能超过127层!

最后是CMD指令,来指定运行容器时的操作命令。

下面是一个更复杂的例子

FROM      ubuntu
MAINTAINER Victor Vieux <victor@docker.com>

RUN apt-get update && apt-get install -y inotify-tools nginx apache2 openssh-server

FROM ubuntu

# 更新并安装一些软件
RUN apt-get update && apt-get install -y x11vnc xvfb firefox
RUN mkdir /.vnc
# 设置密码
RUN x11vnc -storepasswd 1234 ~/.vnc/passwd
# 自动启动火狐
RUN bash -c 'echo "firefox" >> /.bashrc'

EXPOSE 5900
CMD    ["x11vnc", "-forever", "-usepw", "-create"]

FROM ubuntu
RUN echo foo > bar

FROM ubuntu
RUN echo moo > oink

# 此时将有两个镜像

二、指令

指令的一般格式为:INSTRUCTION arguments,指令包括:FROMMAINTAINERRUN等。

2.1、FROM

指定基础镜像,必须为第一个命令。如果在同一个Dockerfile中创建多个镜像时,可以使用多个FROM指令(每个镜像一次)。

格式为:FROM <image>FROM <image>:<tag>

tag是可选的,如果不使用这个值时,会使用latest版本的基础镜像。

2.2、MAINTAINER

格式为:MAINTAINER <name>,指定维护者信息。

2.3、RUN

构建镜像时执行的命令。

格式为:RUN <command>RUN ["executable", "param1", "param2"]

前者将在shell终端中运行命令,即/bin/sh -c;后者则使用exec执行。指定使用其它终端可以通过第二种方式实现,例如RUN ["/bin/bash", "-c", "echo hello"]

每条RUN指令将在当前镜像基础上执行指定命令,并提交为新的镜像。当命令较长时可以使用\来换行。

RUN指令创建的中间镜像会被缓存,并会在下次构建中使用。如果不想使用这些缓存镜像,可以在构建时指定--no-cache参数,如:docker build --no-cache

2.4、CMD

构建容器后调用,也就是在容器启动时才进行调用。CMD不同于RUNCMD用于指定在容器启动时所要执行的命令,而RUN用于指定镜像构建时所要执行的命令。

支持三种格式

1、CMD ["executable","param1","param2"]使用exec执行,是推荐方式;
2、CMD command param1 param2/bin/sh中执行,提供给需要交互的应用;
3、CMD ["param1","param2"]提供给ENTRYPOINT的默认参数;

指定启动容器时执行的命令,每个Dockerfile只能有一条CMD命令。如果指定了多条命令,只有最后一条会被执行。如果用户启动容器时候指定了运行的命令,则会覆盖掉CMD指定的命令。

2.5、EXPOSE

指定于外界交互的端口。

格式为:EXPOSE <port> [<port>...]

告诉Docker服务端容器暴露的端口号,供互联系统使用。在启动容器时需要通过-P,Docker主机会自动分配一个端口转发到指定的端口。

EXPOSE并不会让容器的端口访问到主机。要使其可访问,需要在docker run运行容器时通过-p来发布这些端口,或通过-P参数来发布EXPOSE导出的所有端口。

2.6、ENV

设置环境变量。

格式为:ENV <key> <value>。 指定一个环境变量,会被后续RUN指令使用,并在容器运行时保持。<key>之后的所有内容均会被视为其<value>的组成部分,因此,一次只能设置一个变量。

例:

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

2.7、ADD

将本地文件添加到容器中,tar类型文件会自动解压(网络压缩资源不会被解压),可以访问网络资源,类似wget。

格式为:ADD <src> <dest>

该命令将复制指定的<src>到容器中的<dest>。 其中<src>可以是Dockerfile所在目录的一个相对路径;也可以是一个URL;还可以是一个tar文件(自动解压为目录)。

2.8、COPY

功能类似ADD,但是是不会自动解压文件,也不能访问网络资源。

格式为:COPY <src> <dest>

复制本地主机的<src>(为Dockerfile所在目录的相对路径)到容器中的<dest>

当使用本地目录为源目录时,推荐使用COPY

2.9、ENTRYPOINT

配置容器,使其可执行化。配合CMD可省去"application",只使用参数。

两种格式:

1、ENTRYPOINT ["executable", "param1", "param2"]
2、ENTRYPOINT command param1 param2(shell中执行)。

配置容器启动后执行的命令,并且不可被docker run提供的参数覆盖。

ENTRYPOINTCMD非常类似,不同的是通过docker run执行的命令不会覆盖ENTRYPOINT,而docker run命令中指定的任何参数,都会被当做参数再次传递给ENTRYPOINTDockerfile中只允许有一个ENTRYPOINT命令,多指定时会覆盖前面的设置,而只执行最后的ENTRYPOINT指令。

2.10、VOLUME

用于指定持久化目录。

格式为:VOLUME ["/data"]

创建一个可以从本地主机或其他容器挂载的挂载点,一般用来存放数据库和需要保持的数据等。

一个卷可以存在于一个或多个容器的指定目录,该目录可以绕过联合文件系统,并具有以下功能:

1、卷可以容器间共享和重用
2、容器并不一定要和其它容器共享卷
3、修改卷后会立即生效
4、对卷的修改不会对镜像产生影响
5、卷会一直存在,直到没有任何容器在使用它

2.11、USER

指定运行容器时的用户名或UID,后续的RUN也会使用指定用户。使用USER指定用户时,可以使用用户名、UID或GID,或是两者的组合。当服务不需要管理员权限时,可以通过该命令指定运行用户。并且可以在之前创建所需要的用户

格式为:USER daemon

当服务不需要管理员权限时,可以通过该命令指定运行用户。并且可以在之前创建所需要的用户,例如:RUN groupadd -r postgres && useradd -r -g postgres postgres。要临时获取管理员权限可以使用gosu,而不推荐sudo

使用USER指定用户后,Dockerfile中其后的命令RUNCMDENTRYPOINT都将使用该用户。镜像构建完成后,通过docker run运行容器时,可以通过-u参数来覆盖所指定的用户。

2.12、WORKDIR

工作目录,类似于cd命令。

格式为:WORKDIR /path/to/workdir

为后续的RUNCMDENTRYPOINT指令配置工作目录。

可以使用多个WORKDIR指令,后续命令如果参数是相对路径,则会基于之前命令指定的路径。例如

WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd

则最终路径为/a/b/c

通过WORKDIR设置工作目录后,Dockerfile中其后的命令RUNCMDENTRYPOINTADDCOPY等命令都会在该目录下执行。在使用docker run运行容器时,可以通过-w参数覆盖构建时所设置的工作目录。

2.13、ONBUILD

用于设置镜像触发器。

格式为:ONBUILD [INSTRUCTION]

配置当创建的镜像作为其它新创建镜像的基础镜像时,所执行的操作指令。

例如,Dockerfile使用如下的内容创建了镜像image-A

[...]
ONBUILD ADD . /app/src
ONBUILD RUN /usr/local/bin/python-build --dir /app/src
[...]

如果基于image-A创建新的镜像时,新的Dockerfile中使用FROM image-A指定基础镜像,会自动执行ONBUILD指令内容,等价于在后面添加了两条指令。

FROM image-A

# 自动运行以下两条指令
ADD . /app/src
RUN /usr/local/bin/python-build --dir /app/src

使用ONBUILD指令的镜像,推荐在标签中注明,例如ruby:1.9-onbuild

三、创建镜像

编写完成Dockerfile之后,可以通过docker build命令来创建镜像。

基本的格式为:docker build [选项] 路径,该命令将读取指定路径下(包括子目录)的Dockerfile,并将该路径下所有内容发送给Docker服务端,由服务端来创建镜像。因此一般建议放置Dockerfile的目录为空目录。也可以通过.dockerignore文件(每一行添加一条匹配模式)来让Docker忽略路径下的目录和文件。

要指定镜像的标签信息,可以通过-t选项,例如:

# 构建镜像名为test:v1,地址是/tmp/test1/
docker build -t test:v1 /tmp/test1/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

武天旭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值