Dockerfile
是一个文本文件,其内包含了一条条的 指令(Instruction),每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。
使用 Dockerfile
定制镜像
1 2 3
| mkdir test cd test touch Dockerfile
|
1 2
| FROM nginx RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html
|
这个 Dockerfile
很简单,一共就两行。涉及到了两条指令,FROM
和 RUN
。
在 Dockerfile
文件所在目录执行:
1 2 3 4 5 6 7 8 9 10
| [root@caoxl test_nginx] Sending build context to Docker daemon 2.048kB Step 1/2 : FROM nginx ---> 53f3fd8007f7 Step 2/2 : RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html ---> Running in b4a1b636bff4 Removing intermediate container b4a1b636bff4 ---> 9ab56bb5f020 Successfully built 9ab56bb5f020 Successfully tagged nginx:v3
|
Dockerfile
指令详解
FROM
- 指定基础镜像
所谓定制镜像,那一定是以一个镜像为基础,在其上进行定制。
RUN
- 执行命令
RUN
指令是用来执行命令行命令的。由于命令行的强大能力,RUN
指令在定制镜像时是最常用的指令之一。其格式有两种:
- shell 格式:
RUN <命令>
,就像直接在命令行中输入的命令一样。
1
| RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html
|
- exec 格式:
RUN ["可执行文件", "参数1", "参数2"]
,这更像是函数调用中的格式
1 2 3 4 5 6
| FROM debian:stretch
RUN buildDeps='gcc libc6-dev make wget' \ && apt-get update \ && apt-get install -y $buildDeps \ && wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" \
|
COPY
- 复制文件
- 格式
COPY [--chown=<user>:<group>] <源路径>... <目标路径>
COPY [--chown=<user>:<group>] ["<源路径1>",... "<目标路径>"]
1
| COPY package.json /usr/src/app/
|
ADD
- 更高级的复制文件
ADD
指令和 COPY
的格式和性质基本一致。但是在 COPY
基础上增加了一些功能。
1
| ADD ubuntu-xenial-core-cloudimg-amd64-root.tar.gz /
|
在 Docker
官方的 Dockerfile
最佳实践文档 中要求,尽可能的使用 COPY
,因为 COPY
的语义很明确,就是复制文件而已,而 ADD
则包含了更复杂的功能,其行为也不一定很清晰
CMD 容器启动命令
- CMD 指令的格式和 RUN 相似,也是两种格式:
- shell 格式:
CMD <命令>
- exec 格式:
CMD ["可执行文件", "参数1", "参数2"...]
在指令格式上,一般推荐使用 exec
格式,这类格式在解析时会被解析为 JSON 数组,因此一定要使用双引号 "
,而不要使用单引号。
如果使用 shell
格式的话,实际的命令会被包装为 sh -c
的参数的形式进行执行。比如:
在实际执行中,会将其变更为:
1
| CMD [ "sh", "-c", "echo $HOME" ]
|
ENTRYPOINT
- 入口点
ENTRYPOINT
的目的和 CMD
一样,都是在指定容器启动程序及参数。ENTRYPOINT
在运行时也可以替代,不过比 CMD
要略显繁琐,需要通过 docker run
的参数 --entrypoint
来指定。
1 2 3 4 5
| FROM ubuntu:18.04 RUN apt-get update \ && apt-get install -y curl \ && rm -rf /var/lib/apt/lists
|
ENV
- 设置环境变量
- 格式
ENV <key> <value>
ENV <key1>=<value1> <key2>=<value2>...
1 2
| ENV VERSION=1.0 DEBUG=on \ NAME="Happy Feet"
|
WORKDIR
- 指定工作目录
1 2 3 4
| FROM node:slim RUN mkdir /app WORKDIR /app CMD [ "npm", "start" ]
|
USER
- 指定当前用户
1 2 3
| RUN groupadd -r redis && useradd -r -g redis redis USER redis RUN [ "redis-server" ]
|
如果以 root
执行的脚本,在执行期间希望改变身份,比如希望以某个已经建立好的用户来运行某个服务进程,不要使用 su
或者 sudo
,这些都需要比较麻烦的配置,而且在 TTY 缺失的环境下经常出错。建议使用 gosu
。
1 2 3 4 5 6 7 8
| RUN groupadd -r redis && useradd -r -g redis redis
RUN wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/1.7/gosu-amd64" \ && chmod +x /usr/local/bin/gosu \ && gosu nobody true
CMD [ "exec", "gosu", "redis", "redis-server" ]
|
Dockerfile
多阶段构建
实战多阶段构建 Laravel
镜像
待更新…
参考