chiachan
chiachan
Published on 2025-03-21 / 16 Visits
0

docker通关攻略 - Dockerfile

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文件。

  1. 用了golang环境编译二进制文件。
  2. 再用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"]

参考文献