docker通关攻略 - Dockerfile
官方仓库的 Dockerfile 都是参考典范:https://github.com/docker-library/docs
Dockerfile 是一个文本文件,其内包含了一条条的指令(Instruction),每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。
上下文
docker build
命令时,当前的工作目录被称为构建上下文。
默认情况下,Dockerfile 就位于该路径下,当然您也可以使用-f参数来指定不同的位置。
构建镜像
docker build
命令构建镜像这里有个重点的概念,叫上下文。当前的工作目录被称为构建上下文。
我们常用 . 指定当前目录作为上下文。默认情况下,Dockerfile 就位于该路径下,当然您也可以使用-f参数来指定不同的位置。
docker build -t <镜像名>:<标签> <上下文路径>
docker build -t <镜像名>:<标签> -f <Dockerfile文件路径> <上下文路径>
例如:
这里最后的 . 代表本次执行的上下文路径
docker build -t nginx:v3.0 .
.dockerignore文件
为了提高构建镜像的效率,可以在目录下新建一个.dockerignore
文件来指定要忽略的文件和目录。
.dockerignore 文件的排除模式语法和 Git 的 .gitignore 文件相似。
构建缓存
在执行每条指令之前,Docker 都会在缓存中查找是否已经存在可重用的镜像,如果有就使用现存的镜像,不再重复创建。
当然如果你不想在构建过程中使用缓存,你可以在 docker build 命令中使用--no-cache=true
选项。
Dockerfile 指令
Dockerfile 指令 | 说明 |
---|---|
FROM | 指定基础镜像,用于后续的指令构建。 |
MAINTAINER | 指定Dockerfile的作者/维护者。(已弃用,推荐使用LABEL指令) |
LABEL | 添加镜像的元数据,使用键值对的形式。 |
RUN | 在构建过程中在镜像中执行命令。 |
CMD | 指定容器创建时的默认命令。(可以被覆盖) |
ENTRYPOINT | 设置容器创建时的主要命令。(不可被覆盖) |
EXPOSE | 声明容器运行时监听的特定网络端口。 |
ENV | 在容器内部设置环境变量。 |
ADD | 将文件、目录或远程URL复制到镜像中。 |
COPY | 将文件或目录复制到镜像中。 |
VOLUME | 为容器创建挂载点或声明卷。 |
WORKDIR | 设置后续指令的工作目录。 |
USER | 指定后续指令的用户上下文。 |
ARG | 定义在构建过程中传递给构建器的变量,可使用 "docker build" 命令设置。 |
ONBUILD | 当该镜像被用作另一个构建过程的基础时,添加触发器。 |
STOPSIGNAL | 设置发送给容器以退出的系统调用信号。 |
HEALT HCHECK | 定义周期性检查容器健康状态的命令。 |
SHELL | 覆盖Docker中默认的shell,用于RUN、CMD和ENTRYPOINT指令。 |
dockerfile支持的命令有以上,我们主要掌握下面几种基本就够用了
1. FROM命令
定制的镜像都是基于 FROM 的镜像,这里的 nginx 就是定制需要的基础镜像。后续的操作都是基于 nginx。
例如:
FROM nginx
RUN echo '这是一个本地构建的nginx镜像' > /usr/share/nginx/html/index.html
2. RUN命令
用于执行后面跟着的命令行命令。有以下俩种格式:
RUN <命令行命令>
RUN ["可执行文件", "参数1", "参数2"]
例如:
FROM centos
RUN yum -y install wget
RUN wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz"
RUN tar -xvf redis.tar.gz
3. COPY命令
复制指令,从上下文目录中复制文件或者目录到容器里指定路径。
例如:
COPY hom* /mydir/
COPY hom?.txt /mydir/
4. CMD命令
指定默认要运行的程序,程序运行结束,容器也就结束。CMD 指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖。
CMD <shell 命令>
CMD ["<可执行文件或命令>","<param1>","<param2>",...]
CMD ["<param1>","<param2>",...] # 该写法是为 ENTRYPOINT 指令指定的程序提供默认参数
在指定了 ENTRYPOINT
指令后,用 CMD
指定具体的参数。
例如:
FROM nginx
ENTRYPOINT ["nginx", "-c"] # 定参
CMD ["/etc/nginx/nginx.conf"] # 变参
5. ENV命令
指定环境变量
ENV <key> <value>
ENV <key1>=<value1> <key2>=<value2>...
例如:
ENV NODE_VERSION 7.2.0
ENV GOPATH=/home/ubuntu/go GOROOT=/home/ubuntu/.go
6. WORKDIR命令
指定工作目录
WORKDIR <WORKDIR PATH>
例如:
WORKDIR /home/ubuntu
多阶段构建
构建过程,我们可能需要用到多个环境,参考下面的DockerFile文件。
- 用了golang环境编译二进制文件。
- 再用alpine环境运行
FROM golang:alpine as builder
RUN apk --no-cache add git
WORKDIR /go/src/github.com/go/helloworld/
RUN go get -d -v github.com/go-sql-driver/mysql
COPY app.go .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .
FROM alpine:latest as prod
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=0 /go/src/github.com/go/helloworld/app .
CMD ["./app"]