序言

  • docker镜像制作,学习记录

1. docker镜像制作的常见方法

1.1 docker commit基于已有容器构建镜像(手工)
  • 这种方法将已有容器存为新的镜像,但是不建议使用使用这种方式,原因:
    (1) 手工创建镜像容器出错,效率低且可重复性弱
    (2) 使用者不知道镜像创建过程、里面是否有恶意程序

  • 构建过程
    (1) 运行容器
    (2) 修改容器
    (3) 将容器保存为新的镜像

  • 举例:

    docker run -it --name=myContainer myImage /bin/bash        // 新建容器并运行
    docker exec -it myContainer /bin/bash                   // 进入容器vim .bashrc报错vim: command not foundapt-get update                                            // 更新安装源
    apt-get install vim                                     // 安装vim退出来保存新镜像:使用commit存为新镜像
    docker commit -m "install vim" myContainer newImage:newTagdocker images                                           // 查看新镜像重新创建容器测试vim已可用
    docker history newImage:newTag                          // 查看镜像构建历史
    
1.2 使用Dockerfile自动构建镜像(自动化)
  • docker程序通过读取Dockerfile文件中的指令生成生成镜像
  • Dockerfile的每一行命令都生成了一个镜像层
  • Dockerfile的结构:基础镜像信息 + 维护者信息 + 镜像操作指令 + 容器启动时执行指令

2. Dockerfile镜像构建命令

(1) FROM

  • 功能:指定基础镜像,必须为第一条指令;如果不以任何镜像为基础,FROM scratch

  • 语法

    FROM <image>:<tag> # tag可不指定,默认为latest
    
  • 注1:tag尽量具体指定,不要用latest,基础镜像更新后不一定是我们想要的

  • 注2:在一个Dockerfile中使用多个基础镜像

    一种是多阶段multi-stage构建:写多个基础镜像入口?构建时指定基于哪个创建

    另一种是整合多个基础镜像的Dockerfile:Dockerfile内没法FROM多个基础镜像

  • 举例

    FROM ubuntu:latest    # 基于ubuntu:latest创建镜像FROM scratch       # 不基于任何镜像创建
    

(2) RUN

  • 功能:为镜像构建指定要运行的命令行命令,这些命令在docker build时执行

  • 语法

    # shell格式(常用)
    RUN <command>     # command为终端操作的shell命令,可以是下载或安装软件等# exec格式
    RUN ["executable", "param1", "param2", ...]   # 可理解为可执行文件+参数
    
  • 注1:每个RUN命令会生成一个镜像层,为了避免镜像臃肿尽量多个命令合到一个指令;不同命令间通过 && 间隔开,换行符 \ 连接换行

  • 举例

    RUN     apt-get update && apt-get install -y vim   # 安装vim
    

(3) CMD

  • 功能:容器启动时执行的命令,这些命令在docker run时执行

  • 语法

    # 1、shell格式
    CMD <command># 2、exec命令格式(常用)
    CMD ["<可执行文件或命令>","<param1>","<param2>",...] # 3、该写法是为ENTRYPOINT指令指定的程序提供默认参数
    CMD ["<param1>","<param2>",...]
    
  • 注1:每个Dockerfile只能有一条CMD命令,如果有多条CMD命令只会执行最后一条

  • 注2:容器启动时如果加了命令行参数会覆盖CMD指定的命令

  • 举例

    CMD     /bin/bash   # 启动容器后执行/bin/bash启动shell终端
    

(4) LABEL

  • 功能:为镜像添加标签,包括创作者、公司、版本等

  • 语法

    LABEL <key>=<value> <key>=<value> ...# e.g.
    LABEL maintainer="shuaixio@gmail.com"
    LABEL version="1.1"LABEL maintainer="shuaixio@gmail.com" \version="1.1"
    
  • 注1:LABEL可以替换MAINTAINER的功能,MAINTAINER已被弃用

  • 注2:LABEL可以继承基础镜像中的LABEL,key相同则会覆盖

(5) ADD

  • 功能:复制命令,把文件复制到镜像中;功能类似COPY,相当于linux中的scp

  • 语法

    ADD <src>... <dest>
    或
    ADD ["<src>",... "<dest>"]
    
  • 注1:src可以是本地的一个文件、文件夹、压缩包甚至url,如果是url,则ADD相当于wget
    尽量不要把src写成文件夹,会复制整个目录的内容包括系统元数据
    如果是压缩包,拷贝后会自动解压到目标路径

  • 注2:dest路径的填写可以是容器内的绝对路径也可以是相对路径

  • 注3:除非需要从url提取文件或者自动解压文件,否则一律用COPY

  • 举例

    ADD xxx.zip /myzipdir/           # 拷贝后自动加压ADD test1.txt test2.txt /mydir/    # 拷贝多个文件
    

(6) COPY

  • 功能:复制命令,把文件复制到镜像中

  • 语法

    COPY <src>... <dest>COPY ["<src>",... "<dest>"]
    
  • 注1:与ADD的区别,COPY只能复制本地文件,其他一样

  • 注2:拷贝多个文件

    COPY file_a file_b /root
    COPY ["file_a", "file_b", "/root"]
    

(7) WORKDIR

  • 功能:指定工作目录。该工作目录必须提前创建好,在镜像构建的每一层中都存在,对RUN,CMD,ENTRYPOINT,COPY,ADD生效

  • 语法

    WORKDIR /path/to/workdir# e.g.
    WORKDIR /a
    WORKDIR b
    WORKDIR c
    RUN pwd # 结果是/a/b/c
    

(8) ENV

  • 功能:设置环境变量,通过$访问

  • 语法

    ENV <key> <value>                    # 设置一个
    ENV <key1>=<value1> <key2>=<value2>   # 设置多个
    
  • 举例

    ENV CUDA_VERSION=11.1.1       # 设置cuda版本,设置完可通过 ${CUDA_VERSION}来访问
    

(9) VOLUME

  • 功能:可实现挂在,将本地文件夹或其他容器中文件夹挂在到这个容器中

  • 为什么要挂载
    避免重要数据因容器重启而丢失
    避免容器体积不断扩大

  • 语法

    VOLUME <path>
    或
    VOLUME ["<path1>", "<path2>", ...]
    
  • 注1:启动容器时可通过docker run -v参数修改挂载点

(10) EXPOSE

  • 功能:暴露容器运行时候的端口给外部

  • 语法

    EXPOSE <port1> [<port2> ...]
    
  • 注1:使用docker run -P时会自动随机映射宿主机与EXPOSE的端口,-p需指定具体端口

  • 举例

    EXPOSE 80# 在docker启动时
    docker run -P # 宿主机随机端口映射到docker 80端口docker run -d -p 80:80 nginx:v4cmd # -p设置具体的端口映射
    

(11) ARG

  • 功能:设置镜像构建参数,只在docker build构建镜像的过程中有用

  • 语法

    ARG <key>=<value>
    
  • 注1:镜像构建时使用docker build --build-tag =来指定参数

  • 注2:- -build-tag中的参数名需在Dockerfile中定义,或者Dockerfile中ARG定义参数没有被使用,会报告警

  • 注3:ARG可定义默认值,- -build-tag中进行覆盖

(12) ENTRYPOINT

  • 功能:容器启动时执行的命令,与CMD类似

  • 语法

    # 可执行文件+参数
    ENTRYPOINT command param1 param2# shell格式
    ENTRYPOINT ["executable", "param1", "param2"]
    
  • 注1:与CMD命令的差异同
    只能写一条,如果有多条,最后一条生效
    容器启动时运行,而不是镜像构建时运行;

    CMD:docker run时如果加了命令行参数会被覆盖
    ENTRYPOINT:不会被覆盖

  • 注2:如果Dockerfile中同时写了ENTRYPOINT和CMD,并且CMD不是一个完整指令,那么CMD内容将作为ENTRYPOINT的参数(组合使用的方式更常见);如果CMD是一个完整指令,那么会相互覆盖,谁在最后谁生效

(13) ONBUILD

  • 功能:配置当前镜像作为基础镜像时,子镜像执行的命令

  • 语法

    ONBUILD [INSTRUCTION]
    
  • 举例

    ONBUILD RUN ls -al
    

    ls -al命令不会在当前镜像中执行,当作为基础镜像时,会在子镜像构建的时候执行ls -al

(14) HEALTHCHECK

  • 功能:容器启动后健康检查命令

  • 语法

    # 容器内运行一个命令来检查容器的健康状况
    HEALTHCHECK [OPTIONS] CMD command# 基础镜像中取消健康检查
    HEALTHCHECK NONE
    
  • 注1:命令只能出现一次,如果出现多次只有最后一个生效

  • 注2:HEALTHCHECK支持的选项
    - -interval=<间隔>:两次健康检查的间隔,默认为 30 秒;
    - -timeout=<时长>:健康检查命令运行超时时间,如果超过这个时间,本次健康检查就被视为失败,默认 30 秒;
    - -retries=<次数>:当连续失败指定次数后,则将容器状态视为 unhealthy,默认 3 次

  • CMD后命令的返回值决定了本次健康检查是否成功,具体返回值如下
    0: success - 表示容器是健康的
    1: unhealthy - 表示容器已经不能工作了
    2: reserved - 保留,不要使用该值

  • 注2:HEALTHCHECK的状态可以通过 docker container ls查看,健康检查的结果可以通过docker inspect来查看

2. Dockerfile自动构建镜像实例

2.1 Dockerfile镜像构建实例
# This dockerfile uses the alpine image
# VERSION 1.0
# Author: shuaixio# base image
FROM    nvidia/cuda:11.1.1-cudnn8-runtime-ubuntu18.04# label info
LABEL   maintainer="shuaixio@email.com" version="1.0"# apt-get: install necessary softwares
RUN apt-get update && apt-get install -y vim wget libxml2 gcc g++ libeigen3-dev pkg-config sqlite3 libsqlite3-dev git autoconf automake libtool unzip libboost-dev && cd ~/# wget: install cmake3.20.0
RUN wget http://www.cmake.org/files/v3.20/cmake-3.20.0.tar.gz && tar xf cmake-3.20.0.tar.gz && cd cmake-3.20.0 && ./configure && make -j8 && make install && cd ~/# git clone: install geographiclib
RUN git clone https://github.com/sotex/geographiclib.git && cd geographiclib && mkdir build && cd build && cmake .. && make -j8 && make install && cd ~# set expose port
EXPOSE  22 80# /bin/bash after run container
CMD /bin/bash
2.2 镜像构建命令
  • 通过docker build基于Dockerfile构建镜像

    docker build -t imageName:Tag .
    
  • 注1:.表示当前目录,代表从本目录的Dockerfile执行;也可以写成绝对路径
    由于构建镜像可能有复制该目录下数据的操作,所以不要直接在根目录下进行构建

  • 注2:tag自己写,如果和之前镜像重复则会覆盖之前镜像

2.3 查看和保存镜像构建历史
  • 使用docker history命令能清楚的看到每一层进行的操作,方便使用者review

    docker history imageId
    
  • 另外 docker history image 可以看到每一层的大小

  • docker history命令还可以用来保存镜像的dockerfile操作过程

    docker history --no-trunc=true imageId > image_dockerfile
    

参考文章:
Dockerfile镜像构建命令1
Dockerfile镜像构建命令2
docker dockerfile详解
Dockerfile实战
Docker镜像构建实例-推荐
docker-hub官网

created by shuaixio, 2022.05.14

【工作向】docker镜像构建方法与命令相关推荐

  1. 追求极简:Docker镜像构建演化史

    // Dockerfile.target.alpine 自从2013年dotCloud公司(现已改名为Docker Inc)发布Docker容器技术以来,到目前为止已经有五年多的时间了.这期间Dock ...

  2. 从Docker镜像构建演化史来了解多阶段构建的影响

    现在很多开发者都会慢慢习惯在开发环境通过Docker来构建开发环境,有时候可能会有环境移植的问题,所以需要我们写好一套Dockerfile来构建相关的开发镜像,既然说到镜像,那我想问问大家了解Dock ...

  3. docker 导入镜像_官方下一代Docker镜像构建神器 -- BuildKit

    BuildKit是Docker官方社区推出的下一代镜像构建神器--可以更加快速,有效,安全地构建docker 镜像.Docker v18.06已经集成了该组件.BuildKit可用于多种导出格式(例如 ...

  4. Dockerfile 文件结构、docker镜像构建过程详细介绍

    [Docker那些事]系列文章 Dockerfile 文件结构.docker镜像构建过程详细介绍 Dockerfile文件中CMD指令与ENTRYPOINT指令的区别 构建Docker镜像指南,含实战 ...

  5. Docker 镜像构建可以分享的快乐

    通过上一篇 Dockerfile 语法与指令的学习,本节就开始使用Dockerfile 来制作自己的 Docker 镜像啦. Docker 镜像构建 新建 app.py 文件 from flask i ...

  6. Docker学习(3)-Docker镜像构建和使用

    Docker学习(1)-Docker简介 Docker学习(2)-Docker基础1 Docker 镜像与制作 Docker 镜像内是否包含内核(bootfs)? 首先,从镜像的体积大小来说,一个比较 ...

  7. Docker 镜像构建之 Dockerfile

    Docker 镜像构建之 Dockerfile 在 Docker 中构建镜像最常用的方式,就是使用 Dockerfile.Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜 ...

  8. Docker教程(四) Docker镜像构建

    Docker教程(四) Docker镜像构建 本文链接:https://blog.csdn.net/yuan_xw/article/details/77744272 Docker教程(四) Docke ...

  9. 各型号交换机端口镜像配置方法和命令

    各型号交换机端口镜像配置方法和命令 "Port Mirror"即端口镜像,端口镜像为网络传输提供了备份通道.此外,还可以用于进行数据流量监测.可以这样理解:在端口A和端口B之间建立 ...

最新文章

  1. 原生js——四种对话框
  2. JavaWeb入门_模仿天猫整站Tmall_SSH实践项目
  3. Replation requires the actual server name ... Replication.Utilies
  4. 存储过程或视图的字符串查询
  5. Scrum 项目4.0--软件工程
  6. 前端学习(2799):实现资讯的结构和列表
  7. 在网页中显示CHM (c# csharp .net asp.net winform)
  8. windows使用markdown离线编写文章(可设置图床)
  9. 基于visual Studio2013解决C语言竞赛题之1054抽牌游戏
  10. KDD20 | 图模型的信息融合专题
  11. 3. SQL 语句本身的优化(慢查询)
  12. Fiddler(Web/HTTP调试利器)
  13. 精品软件介绍 Wireless Network Watcher 中文版 - 防蹭网监视软件
  14. js 封装原生XMLHttpRequest
  15. 林志颖在微博展示iPhone 5
  16. 微信视频聊天记录怎么录制
  17. clustalw2 使用简介
  18. QQ透明头像通用设置教程!不仅简单而且免费!
  19. 好程序员web前端分享用CSS和JS打造一个简单的图片编辑器
  20. 新海诚没有参与制作的作品_超豪华的制作团队只有这一次——新海诚《你的名字》访谈(下)...

热门文章

  1. mysql默认民族_56个民族及民族代码的sql语句
  2. 工作总结PPT怎么写?60套工作总结PPT模板:年度汇报、项目汇报,晋升述职
  3. javaScript基础面试题 ---闭包
  4. 如何理解BRD、MRD、PRD这些名词
  5. 图片修改分辨率怎么改?一键在线修改分辨率
  6. error: void value not ignored as it ought to be
  7. 前端通信:ajax设计方案(三)--- 集成ajax上传技术
  8. 哪里有英语,哪里有欢乐
  9. Bug 生命周期 中的 各个状态!
  10. 页目录和页表结构---醍醐灌顶