Dockerfile指令

官方文档地址:https://docs.docker.com/engine/reference/builder/

Dockerfile是一个文本格式的配置文件,其内容包含众多指令,用户可以使用它快速的创建自定义镜像。

部分指令列表

指令 作用 备注
FROM 指定基础镜像 任何Dockerfile中的第一条指令都必须是FROM
一个文件中可以存在多个FROM指令。
LABEL 为镜像添加元数据标签信息。
ARG 定义创建镜像过程中使用的变量,编译成功后不存在。 在运行docker build时,指定--builder-arg为变量赋值。
ENV 设置环境变量 在镜像启动时也会存在。
docker run --env key=value 会覆盖同名变量
WORKDIR 指定工作目录 可以使用多个,建议使用绝对路径。
VOLUME 创建数据卷挂载点 例如VOLUME ["/data/a","/data/b"]
EXPOSE 声明镜像内服务监听的端口 只起声明作用,不会自动完成映射。
USER 指定运行容器时的用户名或ID 后续RUN指令也会以这个用户身份运行。
STOPSIGNAL 指定所创建镜像启动的容器接收退出的信号值

COPY/ADD

COPY src dst / ADD src dst

其相同点是:作用都是复制内容到镜像中;dst不存在时会创建;路径支持正则。

不同点在于:

  • ADD的src可以是相对于Dockerfile的相对路径;也可以是一个URL;还可以是一个tar文件(自动解压)。
  • COPY的src只能是文件或者目录。

除了目的明确是要将一个URL或者tar文件作为src的情况下,其他情况推荐使用COPY。

CMD/ENTRYPOINT

命令格式

  • exec方式: ["executable","param1","param2"](JSON数组,所以一定要是双引号)
  • shell方式: command param1 param2

CMD与ENTRYPOINT两种方式都支持,但推荐使用exec方式。

作用

在任意一个Dockerfile下:

  • 只有最后一条CMD才会被执行。用来指定容器启动时默认执行的命令及参数。但是会被docker run命令行参数覆盖。
  • 只有最后一条ENTRYPOINT才会被执行。用来配置容器启动时的执行命令。并且会将docker run的命令行参数或者CMD的所有参数追加在ENTRYPOINT指令后作为参数。运行时可以被--entrypoint参数覆盖。

伪代码

  1. finallyCommand = ""
  2. if exists(ENTRYPOINT) {
  3. finallyCommand = ENTRYPOINT
  4. if exists(dockerRunCommandParam){
  5. // 情景一
  6. finallyCommand += dockerRunCommandParam
  7. }elseif exists(CMD) {
  8. // 情景二。除了CMD指令本身,包括后面JSON数组所有
  9. finallyCommand += CMDParams
  10. }
  11. // 情景三
  12. }elseif exists(dockerRunCommandParam){
  13. // 情景四
  14. finallyCommand = dockerRunCommandParams
  15. }elseif exists(CMD){
  16. // 情景五
  17. finallyCommand = CMD
  18. }

总结起来一句话:有ENTRYPOINT,CMD和docker run指定的命令都作为参数追加到ENTRYPOINT的参数后;没有ENTRYPOINT,docker run指定了命令就执行,否则执行CMD(如果有的话)。

实操

Dockerfile内容、构建镜像

  1. FROM alpine:latest
  2. ENTRYPOINT ["/bin/echo","entrypoint"]
  3. -> [feifei@ffmac.local] [~/work/docker] docker build -t test .
  4. // 情景三
  5. -> [feifei@ffmac.local] [~/work/docker] docker run --rm test
  6. entrypoint
  7. // 情景一
  8. -> [feifei@ffmac.local] [~/work/docker] docker run --rm test 12 34
  9. entrypoint 12 34

Dockerfile添加CMD指令、构建镜像

  1. FROM alpine:latest
  2. ENTRYPOINT ["/bin/echo","entrypoint"]
  3. CMD ["/bin/echo","cmd"]
  4. -> [feifei@ffmac.local] [~/work/docker] docker build -t test .
  5. // 情景二:CMD中的 "/bin/echo" 没有被当做命令执行,而是与"cmd"一起成为了ENTRYPOINT的参数。
  6. -> [feifei@ffmac.local] [~/work/docker] docker run --rm test
  7. entrypoint /bin/echo cmd

Dockerfile删除ENTRYPOINT指令、构建镜像

  1. FROM alpine:latest
  2. CMD ["/bin/echo","cmd"]
  3. -> [feifei@ffmac.local] [~/work/docker] docker build -t test .
  4. // 情景五
  5. -> [feifei@ffmac.local] [~/work/docker] docker run --rm test
  6. cmd
  7. // 情景四
  8. -> [feifei@ffmac.local] [~/work/docker] docker run --rm test echo 33
  9. 33

RUN

exec方式:RUN ["executable","param1","param2"]

shell方式:RUN command param1 param2

每条RUN指令将在当前镜像基础上执行指令,并且提交为新的镜像层。当命令较长时可以使用\来换行

ONBUILD

ONBUILD [INSTRUCTION]

作为父镜像被使用时自动执行的命令。对孙子镜像无效。可用于自动编译,检查等。

假如父镜像ParentImage的Dockerfile中有如下指令:

  1. ONBUILD RUN mkdir /root/test

使用docker build基于ParentImage创建子镜像ChildImage的时候,会先执行ParentImage中的ONBUILD指令。等价于在ChildImage中添加了:

  1. RUN mkdir /root/test

HEALTHCHECK

健康检查

HEALTHCHECK [OPTIONS] CMD command :根据执行命令返回值判断,0是成功,1是不健康。

HEALTHCHECK NONE :禁止健康检查

OPTIONS参数如下:

  • --interval=DURATION (default: 30s) 多长时间检查一次
  • --timeout=DURATION (default: 30s) 检查一次的超时时间
  • --start-period=DURATION (default: 0s) 开始阶段时长,此阶段内第一次成功之前的失败不计入retries。
  • --retries=N (default: 3) 确定最终失败的重试次数

构建镜像

docker build

docker build [OPTIONS] PATH | URL | -

该命令默认读取指定路径下的Dockerfile(也可使用 -f 指定),并将该路径下的所有数据作为上下文发送给Docker服务端。逐条执行指令,生成镜像。

选择父镜像

一般情况下都需要使用FROM来指定父镜像,所以父镜像会影响到新生成镜像的大小和功能。

通常有两种镜像可作为父镜像:基础镜像和普通镜像(由第三方创建,基于基础镜像)。基础镜像一般是基于scratch或者Dockerfile中不存在FROM指令。

多步骤构建

对于编译型语言通常需要编译环境和运行环境两个镜像:

  • 编译环境镜像:包括完整的编译环境、依赖库等,体积较大。作用是将代码编译为二进制程序。
  • 运行环境镜像:运行二进制程序,而不需要与编译环境,体积比较小。

app.go

  1. package main
  2. import "fmt"
  3. func main() {
  4. fmt.Println("Hello World")
  5. }

Dockerfile中使用两次FROM

  1. FROM golang:1.14-alpine as builder
  2. WORKDIR /go/src/test
  3. COPY app.go .
  4. RUN CGO_ENABLED=0 GOOS=linux go build -o app app.go
  5. FROM alpine:latest
  6. COPY --from=builder /go/src/test/app /root/ #此处 --from=builder 也可以改为 --from=0
  7. CMD ["/root/app"]

构建、运行

  1. -> [feifei@ffmac.local] [~/work/docker] docker build -t hello .
  2. -> [feifei@ffmac.local] [~/work/docker] docker run --rm hello
  3. Hello World

小技巧

清理untagged镜像

多阶段构建会生成编译环境镜像,也会将之前的同名镜像变为<none>:<none>,清理此类镜像可执行以下命令:

  1. docker rmi $(docker images --filter dangling=true -q)

COPY --from指定其他镜像

COPY指令的--from选项也可以指定本地或者远程仓库的镜像

准备一个Dockerfile,内容是从ubuntu镜像中COPY一个文件到新镜像的/root/下

  1. FROM alpine:latest
  2. COPY --from=ubuntu:latest /bin/bash /root/
  3. CMD ["/bin/ls","/root/"]

dokcer build 构建镜像

  1. -> [feifei@ffmac.local] [~/work/docker] docker build -t test .
  2. Sending build context to Docker daemon 19.46kB
  3. Step 1/3 : FROM alpine:latest
  4. ---> f70734b6a266
  5. Step 2/3 : COPY --from=ubuntu:latest /bin/bash /root/
  6. latest: Pulling from library/ubuntu
  7. d51af753c3d3: Pull complete
  8. fc878cd0a91c: Pull complete
  9. 6154df8ff988: Pull complete
  10. fee5db0ff82f: Pull complete
  11. Digest: sha256:747d2dbbaaee995098c9792d99bd333c6783ce56150d1b11e333bbceed5c54d7
  12. Status: Downloaded newer image for ubuntu:latest
  13. ---> Using cache
  14. ---> 082f95ffaa69
  15. Step 3/3 : CMD ["/bin/ls","/root/"]
  16. ---> Using cache
  17. ---> 76fa9d9a1abd
  18. Successfully built 76fa9d9a1abd
  19. Successfully tagged test:latest

dokcer run 运行镜像

  1. -> [feifei@ffmac.local] [~/work/docker] docker run --rm test
  2. bash

注意事项

  • 使用.dockerignore文件,避免发送不必要的数据
  • 提供注释和维护者信息
  • 正确使用镜像版本号
  • 每条RUN都会提交为新的镜像层,尽量合并RUN指令
  • 删除缓存和临时文件

Docker学习笔记(三):Dockerfile及多步骤构建镜像的更多相关文章

  1. Docker学习笔记三 Dockerfile 指令 定制镜像

    本文地址:https://www.cnblogs.com/veinyin/p/10412079.html  镜像是分层存储的,每一层都是独立存在的,修改当前层并不会修改其依赖的上一层,删除某一层也只是 ...

  2. Docker学习笔记三:Docker部署Java web系统

    Docker部署Java Web系统 1.在root目录下创建一个路径test/app mkdir test && cd test&& mkdir app && ...

  3. Docker学习笔记之Dockerfile

    Dockerfile的编写格式为<命令><形式参数>,命令不区分大小写,但一般使用大写字母.Docker会依据Dockerfile文件中编写的命令顺序依次执行命令.Docker ...

  4. Docker学习笔记三

    4.Docker数据管理 4.1.数据卷 数据卷是一个可供容器使用的特殊目录,它将主机操作系统目录直接映射进容器,类似与Linux的mount行为. 特性: 数据卷可以在容器之间共事和重用,容器间传递 ...

  5. docker学习笔记5:利用commit命令创建镜像 和 删除本地镜像

    一.概述 创建镜像有两种方法,一是用commit命令,二是用dockerfile方法(这个更常用,在下面文章介绍).本章介绍commit方法. 在介绍commit命令前,我们先回顾下对代码的版本控制, ...

  6. Docker学习(三): Dockerfile指令介绍

    特别声明: 博文主要是学习过程中的知识整理,以便之后的查阅回顾.部分内容来源于网络(如有摘录未标注请指出).内容如有差错,也欢迎指正! =============系列文章============= 1 ...

  7. Docker学习笔记之二,基于Dockerfile搭建JAVA Tomcat运行环境

    前言 在第一篇文字中,我们完全人工方式,一个命令一个命令输入,实现一个 java tomcat运行环境,虽然也初见成效,但很累人.如果依靠依靠脚本构建一个Tomcat容器实例,一个命令可以搞定,何乐而 ...

  8. Docker学习笔记总结

    Docker学习笔记 https://yeasy.gitbooks.io/docker_practice/content/   一 环境搭建 Ubuntu安装 .添加软件源的GPG密钥 curl -f ...

  9. Docker学习笔记之-在CentOS中安装Docker

    上一节演示了如何 通过Xshell连接CentOS服务,链接:Docker学习笔记之-通过Xshell连接 CentOS服务 本节将演示 如何在CentOS中安装 Docker 第一步:更新系统包到最 ...

随机推荐

  1. fashion_mnist多分类训练,两种模型的保存与加载

    from tensorflow.python.keras.preprocessing.image import load_img,img_to_array from tensorflow.python ...

  2. STM32 内存分配解析及变量的存储位置

    内存映射 在一些桌面程序中,整个内存映射是通过虚拟内存来进行管理的,使用一种称为内存管理单元(MMU)的硬件结构来将程序的内存映射到物理RAM.在对于 RAM 紧缺的嵌入式系统中,是缺少 MMU 内存 ...

  3. phpstorm破解版

    查看下载:https://www.7down.com/soft/229568.html 破解:https://www.7down.com/article/305640.html 主题更换和下载:htt ...

  4. Spring Boot的TestRestTemplate使用

    文章目录 添加maven依赖 TestRestTemplate VS RestTemplate 使用Basic Auth Credentials 使用HttpClientOption 使用RestTe ...

  5. js 实现淘宝无缝轮播图效果,可更改配置参数 带完整版解析代码[slider.js]

    前言:         本人纯小白一个,有很多地方理解的没有各位大牛那么透彻,如有错误,请各位大牛指出斧正!小弟感激不尽.         本篇文章为您分析一下原生JS写淘宝无缝轮播图效果 需求分析: ...

  6. 飞机大战-面向对象-pygame

    飞机大战 最近学习了python的面向对象,对面向对象的理解不是很深刻. 面向对象是数据和函数的'打包整理',将相关数据和处理数据的方法集中在一个地方,方便使用和管理. 本着学习的目的,在网上找了这个 ...

  7. uniq 只能相邻行去重

    uniq只可以将相邻行重复数据进行去重处理: [root@localhost /data/mysql/mysql3306]#last | cut -d ' ' -f 1 | tail -15 > ...

  8. Jaba_Web--JDBC 删除记录操作模板

    import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import ...

  9. 《Docker从入门到跑路》之镜像和容器的基本操作

    一.获取镜像 官方提供了一个公共镜像仓库Docker Hub,默认是从这上面获取镜像的. 搜素镜像使用docker search 命令: # docker search --help Usage: d ...

  10. php报错:strip_tags() expects parameter 1 to be string, array given

    囧....... 这个表示参数需要字符串,而你传入了数组,所以出错了~ 检查下函数或者方法是否正确,还有参数