DockerFile指令
Dockerfile指令包括:
| Dockerfile 指令 | 说明 |
|---|---|
| FROM | 指定基础镜像,用于后续的指令构建。 |
| MAINTAINER | 指定Dockerfile的作者/维护者。(已弃用,推荐使用LABEL指令) |
| LABEL | 添加镜像的元数据,使用键值对的形式。 |
| RUN | 在构建过程中在镜像中执行命令。 |
| CMD | 指定容器创建时的默认命令。(可以被覆盖) |
| ENTRYPOINT | 设置容器创建时的主要命令。(不可被覆盖) |
| EXPOSE | 声明容器运行时监听的特定网络端口。 |
| ENV | 在容器内部设置环境变量。 |
| ADD | 将文件、目录或远程URL复制到镜像中。 |
| COPY | 将文件或目录复制到镜像中。 |
| VOLUME | 为容器创建挂载点或声明卷。 |
| WORKDIR | 设置后续指令的工作目录。 |
| USER | 指定后续指令的用户上下文。 |
| ARG | 定义在构建过程中传递给构建器的变量,可使用 “docker build” 命令设置。 |
| ONBUILD | 当该镜像被用作另一个构建过程的基础时,添加触发器。 |
| STOPSIGNAL | 设置发送给容器以退出的系统调用信号。 |
| HEALTHCHECK | 定义周期性检查容器健康状态的命令。 |
| SHELL | 覆盖Docker中默认的shell,用于RUN、CMD和ENTRYPOINT指令。 |
通过 Dockerfile 中的这些指令,可以构建出一个完整的Docker 镜像。
1 基础指令
1)FROM
格式:
FROM <image>
FROM <image>:<tag>
解释:FROM是Dockerfile的第一条而且只能是除了首行注释之外的第一条指令。
2)MAINTAINER
格式:
MAINTAINER <name>
解释:指定该Dockerfile文件的维护者信息,类似我们在docker commit时候使用-a参数指定的信息。
3)RUN:(构建镜像) 运行命令(安装环境)
解释:执行命令并创建新的镜像层,通常用于安装软件包
格式:
RUN <command> (shell 模式)
RUN["executable", "param1", "param2"] (exec 模式:注意需要"双引号")
shell模式:RUN echo 1 ——/bin/sh -c ‘1 '
使用 shell 模式时,docker 会以
/bin/sh -c "task command"的方式执行任务命令。也就是说容器中的 1号进程 不是任务进程而是 bash进程
exec模式:RUN ["echo", "1"] ——
exec 模式是建议使用的模式 [注意需要"双引号"]
——因为当运行任务的进程作为容器中的 1 号进程时,我们可以通过 docker 的 stop 命令优雅的结束容器(详情请参考《在 docker 容器中捕获信号》)。
4)ENTRYPOINT:只能一个or加上CMD传参
不会被替换,可以让镜像如同一个 可执行程序
ENTRYPOINT 的 Exec 格式用于设置容器启动时要执行的命令及其参数,同时可通过CMD命令或者命令行参数提供额外的参数。ENTRYPOINT 中的参数始终会被使用,这是与CMD命令不同的一点。
可以搭配 CMD 命令使用:一般是变参才会使用 CMD ,这里的 CMD 等于是在给 ENTRYPOINT 传参
格式:
ENTRYPOINT ["executable", "param1","param2"] (exec 模式)
ENTRYPOINT command param1 param2 (shell模式)
解释:每个Dockerfile中只能有一个ENTRYPOINT,当指定多个时,只有最后一个起效。
- 下面是一个例子:
ENTRYPOINT ["/bin/echo", "Hello"]
当容器通过 docker run -it [image] 启动时,输出为:
Hello
而如果通过 docker run -it [image] CloudMan 启动(run时指定额外参数),则输出为:
Hello CloudMan
将Dockerfile修改为:
ENTRYPOINT ["/bin/echo", "Hello"]
CMD ["world"]
当容器通过 docker run -it [image] 启动时,输出为:
Hello world
而如果通过 docker run -it [image] CloudMan 启动,输出依旧为:
Hello CloudMan
ENTRYPOINT 中的参数始终会被使用,而 CMD 的额外参数可以在容器run启动时增加命令——动态替换掉。
5)CMD:单独or配合ENTRYPOINT
CMD 指令允许用户指定容器的默认执行的命令。此命令会在容器启动且 docker run 没有指定其他命令时运行。
格式:
CMD <command>
能够被 run 后替换:设置容器启动后默认执行的命令及其参数,但CMD设置的命令能够被
docker run命令后面的命令行参数替换
正确姿势
对于 CMD 和 ENTRYPOINT 的设计而言,多数情况下它们应该是单独使用的。 ——当然,有一个例外是 CMD 为 ENTRYPOINT 提供默认的可选参数。
我们大概可以总结出下面几条规律:
• 如果 ENTRYPOINT 使用了shell 模式,CMD 指令会被忽略。
• 如果 ENTRYPOINT 使用了 [exec] 模式,CMD 指定的内容被追加为 ENTRYPOINT 指定命令的参数。
• 如果 ENTRYPOINT 使用了 [exec] 模式,CMD 也应该使用 [exec] 模式。
- 例子
ENTRYPOINT [ "sh" ]
CMD [ "/entrypoint.sh" ]
docker信号处理:stop=SIGTERM、kill=SIGKILL
参考: 在 docker 容器中捕获信号
6)EXPOSE:暴露端口
格式:
EXPOSE <port> [<port>...]
解释:设置Docker容器对外暴露的端口号,Docker为了安全,不会自动对外打开端口,如果需要外部提供访问,还需要启动容器时增加-p或者-P参数对容器的端口进行分配。
2 文件编辑指令
1)ADD:复制(如果是压缩包则 [解压])
格式:
ADD <src>... <dest>
ADD ["<src>",... "<dest>"]
解释:将宿主机指定的文件复制到容器文件系统的中。
注意:如果源文件是个压缩文件,则docker会自动帮解压到指定的容器中。
2)COPY:复制(单纯)
格式:
COPY <src>... <dest>
COPY ["<src>",... "<dest>"]
解释:单纯复制文件场景,Docker推荐使用COPY。
3)VOLUME:匿名卷
默认Docker容器中数据都是 只读 的,要让它可写 + 并且可以共享给其他容器,就必须创建 VOLUME
VOLUME <路径>
VOLUME ["<路径1>", "<路径2>"...]
解释:VOLUME指令可以在镜像中创建挂载点,这样只要通过该镜像创建的容器都有了挂载点。
注意:通过VOLUME指令创建的挂载点,无法指定主机上对应的目录,Docker会自动为这些挂载点分配一个主机上的匿名数据卷。
关于卷(Volume):Dockerfile与Docker run
容器运行时应该尽量保持容器存储层不发生写操作,对于数据库类需要保存动态数据的应用,其数据库文件应该保存于卷(volume)中。
为了防止运行时用户忘记将动态文件所保存目录挂载为卷,在 Dockerfile 中,我们可以事先指定某些目录挂载为匿名卷,这样在run运行时如果用户(忘了)没有指定挂载,其应用也可以正常运行,不会向容器存储层写入大量数据。
例如
VOLUME /data
- 这里的
/data目录就会在容器运行时自动挂载为匿名卷,任何向/data中写入的信息都不会记录进容器存储层,从而保证了容器存储层的无状态化。
当然,运行容器时可以覆盖这个挂载设置。比如:
$ docker run -d -v mydata:/data xxxx
在这行命令中,就使用了 mydata 这个命名卷挂载到了 /data 这个位置,替代了 Dockerfile 中定义的匿名卷的挂载配置——变成命名卷了。
3 环境指令
1)ENV:设置容器环境变量
格式:
ENV <key> <value>
ENV <key>=<value> ...
ENV <key1>=<value1> \
<key2>=<value2>...
解释:设置环境变量,可以在RUN之前使用,然后RUN命令时调用,容器启动时这些环境变量都会被指定。
ENV VERSION=1.0 DEBUG=on \
NAME="Happy Feet"
2)ARG:Dockerfile内局部变量
构建参数,与 ENV 作用一致。不过作用域不一样。ARG 设置的环境变量仅对 Dockerfile 内有效,也就是说只有 docker build 的过程中有效,构建好的镜像内不存在此环境变量。
构建命令 docker build 中可以用 –build-arg <参数名>=<值> 来覆盖。
3)WORKDIR:切换目录(cd)
格式:
WORKDIR /path/to/workdir (shell 模式)
解释:切换目录,为后续的RUN、ENTRYPOINT 指令配置工作目录,相当于cd。
可以使用多个WORKDIR 指令,后续命令如果参数是相对路径,则会基于之前命令指定的路径。
进入容器后进入 最后一个 WORKDIR目录
举例:
WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd
则最终路径为 /a/b/c(进入容器后默认进入此目录)
DockerFile 构建镜像
docker build 命令用于使用 Dockerfile 创建镜像。
# 创建镜像:使用当前目录的Dockerfile(点.)
docker build -t 标签/名 .
# 使用网络url的Dockerfile创建镜像
docker build github.com/creack/docker-firefox
Dockerfile实践
1)编辑Dockerfile文件
# 基础镜像
FROM ubuntu
# 镜像作者
MAINTAINER '[email protected]'
# 执行操作
ADD ./example.tar /
COPY ./example.tar /
VOLUME ["/data"]
# 启动指令
ENTRYPOINT /bin/bash
2)创建镜像
docker build -t test:v1.0 .
3)查看镜像
docker images
4)创建容器并查看
docker run -it test:v1.0 /bin/bash
- ADD解压复制与COPY直接复制

更新:使用alpine作为基础镜像,运行python项目
FROM alpine:3.11
#系统环境
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories && \
apk update && \
cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
echo "Asia/Shanghai" > /etc/timezone
#python环境
WORKDIR /app
COPY requirements.txt /app
ARG PYPI_MIRROR=https://mirrors.aliyun.com/pypi/simple
RUN apk add python3 py3-pip tzdata libffi-dev python3-dev openssl-dev freetds-dev libc-dev gcc && \
pip3 install -i $PYPI_MIRROR -r /app/requirements.txt && \
rm -rf /app ~/.cache/pip /var/cache/apk/*