- 1. FROM:指明当前的镜像基于哪个镜像构建
- 2. LABEL: 标记镜像信息
- 3.
MAINTAINER:指定镜像的作者信息,包含镜像的所有者和联系人信息(已废弃,改用LABEL代替) - 4. RUN : 运行命令
- 5. CMD:指定容器的默认执行的命令
- 6. EXPOSE:指定容器将要监听的端口
- 7. ENV:定义环境变量
- 8. COPY: 将宿主机文件拷贝到镜像中
- 除了指定完整的文件名外,COPY 命令还支持 Go 风格的通配符,比如:
- * 是任意字符的占位符,匹配文件 test11 test22
- ? 是单个字符的占位符,匹配文件 test1.txt test2.txt
- 对于目录而言,COPY 只复制目录中的内容而不包含目录自身。 如下目录结构:
- 镜像的 /tmp 目录下,将得到这样的文件结构:
- 如果要带目录拷贝到镜像中,需要使用
1. FROM:指明当前的镜像基于哪个镜像构建
FROM <基础镜像:版本>
2. LABEL: 标记镜像信息
给镜像添加标签来标记镜像信息,每个标签一行。
LABEL <标签>=<描述>
3. MAINTAINER:指定镜像的作者信息,包含镜像的所有者和联系人信息(已废弃,改用LABEL代替)
# MAINTAINER <NAME># 例如:# MAINTAINER nickname@domain.com# 使用LABEL来标记LABEL maintainer="nickname@domain.com"
4. RUN : 运行命令
RUN <命令>RUN echo 'text' > test.txt# 为了保持 Dockerfile 文件的可读性,以及可维护性,建议将长的或复杂的RUN指令用反斜杠\分割成多行。RUN apt update && apt install -y \vim \emacs# 使用apt update && apt install -y 中间使用&&连接Update和install命令,防止因缓存导致update无效
注意:Dockerfile 的指令每执行一次都会在 docker 上新建一层。所以过多无意义的层,会造成镜像膨胀过大。以 && 符号连接命令,只会创建 1 层镜像
FROM centosRUN yum install wgetRUN wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz"RUN tar -xvf redis.tar.gz以上执行会创建 3 层镜像。可简化为以下格式:FROM centosRUN yum install wget \&& wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" \&& tar -xvf redis.tar.gz
5. CMD:指定容器的默认执行的命令
CMD ["可执行命令", "参数1", "参数2"...]CMD ["echo" "hello"]
docker run 没有指定其他命令时,CMD 指令会在容器执行。Dockerfile 中 CMD 只能有一个,如果写了多个 CMD,则以最后一个为准。
Tips:ENTRYPOINT 与 CMD 类似,但不会被 docker run 指定的命令覆盖
6. EXPOSE:指定容器将要监听的端口
EXPOSE 端口号
启动容器时,如果我们使用自动映射 -P 或 --net=host 宿主机网络模式,容器中 EXPOSE 标记暴露的端口与宿主机网络会自动建立关联。
如果没有指定 EXPOSE,使用 -p 手动指定端口映射参数也可以访问到容器内提供服务的端口。EXPOSE 显式地标明镜像开放端口,一定程度上提供了操作的便利,也提高了 Dockerfile 的可读性和可维护性。
运行时使用-p参数映射端口,: -p <宿主机端口>:<容器端口>
7. ENV:定义环境变量
ENV 环境变量名 环境变量值ENV PATH /usr/local/nginx/bin:$PATH
Tips:
- 通过 ENV 定义的环境变量,可以被后面的所有指令中使用,但是不能被 CMD 指令使用。
- 通过 ENV 定义的环境变量,会永久的保存到该镜像创建的任何容器中,我们可以在 docker run 命令中通过 -e 标记来传递环境变量,启动的容器将会使用我们指定的变量值。
- ARG 指令与 ENV 作用基本一致,区别在于它仅在构建过程中使用,不会保留到容器中。
8. COPY: 将宿主机文件拷贝到镜像中
```dockerfile COPY <宿主机文件路径> <镜像文件路径>
除了指定完整的文件名外,COPY 命令还支持 Go 风格的通配符,比如:
* 是任意字符的占位符,匹配文件 test11 test22
COPY test* /tmp
? 是单个字符的占位符,匹配文件 test1.txt test2.txt
COPY test?.txt /tmp
对于目录而言,COPY 只复制目录中的内容而不包含目录自身。 如下目录结构:
testdir/ ├── file1 └── file2 COPY testdir /tmp
镜像的 /tmp 目录下,将得到这样的文件结构:
tmp/ ├── file1 └── file2
如果要带目录拷贝到镜像中,需要使用
COPY testdir /tmp/testdir
`ADD`和`COPY`用法类似,一般优先使用 COPY。COPY 只支持简单将本地文件拷贝到容器中,而 ADD 还有从压缩包中提取文件的功能,如:```dockerfile# 宿主机压缩包test.tar 解压到 镜像/tmp中ADD test.tar /tmp
9. VOLUME:指定目录为数据卷存储方式
为了防止运行时用户忘记将需要保存数据的目录挂载为卷,我们可以事先指定某些目录挂载为匿名卷,这样在运行时如果用户不指定挂载,其应用也不会向容器存储层写入大量数据。
VOLUME ["<路径1>", "<路径2>"...]VOLUME ["/data"]# 这里的 /data 目录就会在运行时自动挂载为匿名卷,容器运行时使用 -v mydata:/data 可以覆盖这个挂载设置。
10. USER:指定运行容器时的用户名或 UID
USER <user>[:<group>]或USER <UID>[:<GID>]USER www
当容器中运行的服务不需要管理员权限时,可以先建立一个特定的用户和用户组,为它分配必要的权限,然后通过该命令,使用 USER 切换到这个用户。
Tips:
- 使用USER指定用户时,可以使用用户名、UID或GID,或是两者的组合。
- 使用USER指定用户后,Dockerfile中其后的命令RUN、CMD、ENTRYPOINT都将使用该用户。
我们可以在docker run中使用-u参数指定用户执行命令,来替代默认设定,如果为了精确控制用户的id,也可以传入uid。
docker run -i -t -u 1001 busybox sh
11. WORKDIR: 切换到镜像中的指定路径
在WORKDIR中需要使用绝对路径,如果镜像中对应的路径不存在,会自动创建此目录。
我们使用 WORKDIR 来替代 RUN cd <path> && <do something>的这类切换目录进行操作的指令。
WORKDIR指令对ADD COPY等指令也生效,如下操作会将宿主机的test.txt 文件复制到 镜像的/tmp/test.txt。
WORKDIR /tmpCOPY test.txt .
12. ONBUILD:引用后构建指令
ONBUILD <其他指令>
# ONBUILD 是一个特殊的指令,它后面跟的是其它指令,比如 RUN, COPY 等。
ONBUILD COPY . /tmp/
FROM alpine:latest
ONBUILD RUN mkdir /app
ONBUILD COPY . /app/
CMD [ "echo", "hello" ]
# 使用上面 Dockerfile 在构建基础镜像的时候,这两行 ONBUILD 并不会被执行。它的效果等价于:
FROM alpine:latest
CMD [ "echo", "hello" ]
构建出来的镜像作为基础镜像,在其他 Dockerfile 的 FROM 指令中被引用,去构建新镜像的时候,ONBUILD 后的指令会执行。
