Dockerfile文件总结
- 基础概念
- 关键命令
- dockerfile解析
- 执行命令
基础概念
Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明
docker 删除镜像前需要先删除容器(docker ps -a 查看容器) 再删镜像
关键命令
配置命令
- FROM
- MAINTAINER
- ARG 定义创建镜像中的变量
- STOPSIGNAL 指定退出的信号值
- SHELL 默认shell类型
- HEALTHCHECK 健康检查
- EXPOSE
- WORKDIR
- VOLUME
- ENV
- ENTRYPOINT
- ONBUILD
- USER
操作命令
- ADD
- COPY
- RUN
- CMD
FROM
FROM Dockerfile文件第开头必须是一个FROM命令 表示当前的镜像基于哪个父镜像
例如
FROM java8 使用java8作为父镜像 FROM 必须放在第一位
MAINTAINER
MAINTAINER 用来声明镜像的作者信息不是必须的
使用docker inspect 查看到作者信息
例如
MAINTAINER liuyijinag liuyijinag@qq.com
ARG
定义创建镜像过程中的变量
ARG <name>[=default value]
可以使用 -build-arg= 来为Dockerfile中的变量赋值
HEALTHCHECK
可以使用HEALTHCHECK 来配置容器启动后的健康检查
配置文件可以参考 my-docker-demo-sp-goods/Dockerfile
HEALTHCHECK --interval=5s --timeout=2s --retries=12 CMD curl --silent --fail localhost:5599/health || exit 1
--interval=<间隔>:两次健康检查的间隔,默认为 30 秒。
--timeout=<间隔>:健康检查命令运行超时时间,如果超过这个时间,本次健康检查就被视为失败,默认 30 秒。
--retries=<次数>:当连续失败指定次数后,则将容器状态视为 unhealthy,默认 3 次。
--start-period=<间隔>: 应用的启动的初始化时间,在启动过程中的健康检查失效不会计入,默认 0 秒(从 V17.05 引
未开启健康检查
开启后 在STATUS 出现健康状态
LABEL
LABEL 可以配置一些label 可以使用docker inspect 查看到不是必须的
例如
LABEL base.name="test"
RUN
RUN 执行命令,每执执行一个RUN指令就会在当前镜像上创建一个新的镜像层 接下来的指令在这个新镜像层上执行
执行多条命令使用 && 隔开 这样可以减少镜像层的数量
RUN 主要用于安装软件包
例如
RUN apt-get update
RUN ["apt-get","update"] //这种方式可将第一个字符串即(apt-get)理解成为可执行文件,后面就是两个参数
RUN yum install -y net-tools #运行一些命令提前安装一些东西,容器内执行指定的指令,并把结果保存下来
执行多条命令使用 && 隔开 这样可以减少镜像层的数量
例如
RUN apt-get update && apt-get install
EXPOSE
EXPOSE 指定容器内进程对外开发的端口号,多个端口号之间用空格隔开
标记显示信息,不能直接打开端口,方便运维人员在使用容器时,知道要打开哪些端口
如果没有expose端口, Container之间服务也是可以互相访问的
例如
EXPOSE 80 18080 docker ps 的时候可以看到容器支持开启80 18080端口
也可在运行容器的时候使用-p 将主机的端口与容器的端口绑定 -p 8080:8080
ADD 与 COPY
ADD 与 COPY都可以向镜像中添加文件 ,文件可以是主机文件 ,网络文件 ,或者文件夹
也会增加一个新的层
例如
ADD aapp.jar /server/aapp.jar 第一参数是主机上的原文件 第二个参数是容器中的文件文件
而ADD命令基本上是COPY命令的超集,可以实现一些方便、酷炫的拷贝操作。ADD 命令在增加了功能的同时也增加了使用它的复杂度,比如从 url 拷贝压缩文件时弊大于利。在不用自动解压工作或者添加远程文件到镜像中,同样需求下,官方推荐使用 COPY进行指令操作。
WORKDIR
WORKDIR 指定接下来的命令执行的所在目录,如果没有会自动创建
例如
WORKDIR /data/service
VOLUME
VOLUME 创建一个或多个指定的路径的挂载点,将容器内部的一个或多个文件夹挂载到主机上
注意:具体挂载到主机的哪个文件夹上需要使用docker inspect [容器id或容器名称] 查看 运行时查看
例如
VOLUME ["/data/service/logs","/docker/tmp"] 将容器内的/data/service/logs 和 /docker/tmp (没有文件夹会自动创建)挂载到主机上 (主机文件夹是docker自己随机创建的)
此方法不能指定挂载位置 如要指定挂载位置 需要使用 docker run -v 【主机文件夹】:【容器文件夹】
ENV
**ENV ** 设置容器环境变量 在运行容器的时候 通过-e参数可以修改变量值
ENV JAVA_INIT_PATH="/data/jdk" #设置一个环境变量 JAVA_INIT_PATH jdk就保存在这里
ENTRYPOINT 与 CMD
ENTRYPOINT 与 CMD 都是用来设置启动容器后的默认命令,ENTRYPOINT与 CMD不同的是 启动容器后面的命令对于CMD是覆盖 对于ENTRYPOINT是追加,
CMD 是给可执行文件传递参数 [“aa”,“pp”] 当容器启动时执行指定的指令(单独使用的时候)。如果还定义了 ENTRYPOINT ,该CMD指令将被解释为ENTRYPOINT 的参数
注意: 假如定义了多个 ENTRYPOINT 或 CMD 指令,那么只有最后一个生效,前面出现过的 CMD 指令全部无效
例如:
ENTRYPOINT ["nohup","java","-jar","my-docker-demo-springboot.jar","&"] 第一个字符串是命令,后面的字符串是参数
ONBUILD
ONBUILD 后面的命令不会在当前的build中执行 ,只会被子镜像执行 并且执行与子镜像FROM之后 的任意一个命令之前
ONBUILD构建当前镜像的时候不执行 只有构建基于当前镜像的镜像的时候执行
USER
USER 用于指定执行各种命令的用户 (在容器中最好不要使用root用户运行命令)
例如:
RUN groupadd -r java_runer_group && useradd -r -g java_runer_group java_runer 在容器内创建一个用户 useradd命令不用加密码那些
USER java_runer 使用创建的用户
dockerfile解析
FROM ascdc/jdk8 使用父镜像
MAINTAINER liuyijiang
WORKDIR "/data/service" 指定工作文件夹
VOLUME ["/data/service/logs","/docker/tmp"] 将容器内部的"/data/service/logs","/docker/tmp"两个文件夹对主机暴露
COPY my-docker-demo-springboot.jar my-docker-demo-springboot.jar
EXPOSE 5678 开放容器5678端口
ENTRYPOINT ["nohup","java","-jar","my-docker-demo-springboot.jar","&"]
执行命令
使用 **docker build -t (或者–tag) ** 来创建镜像
例如:
docker build -t xxxxx .
建议是当前目录(由于构建环境上下文会被放进一个 tar 文件,然后传给 Docker 守护进程,因此你绝对不会希望使用一个含有大量文件的目录)
1 Dockerfile 中每一个命令为一个层,例如run指令中执行一些持久的进程,譬如数据库,但到了处理下一个指令或启动容器的时候,它们就已经不再运行了
2 如果你需要在启动容器的时候同时运行一个服务或进程,它必须从 ENTRYPOINT 或 CMD 指令中启动