这种方法将已有容器存为新的镜像,但是不建议使用使用这种方式,原因:
(1) 手工创建镜像容器出错,效率低且可重复性弱
(2) 使用者不知道镜像创建过程、里面是否有恶意程序
构建过程
(1) 运行容器
(2) 修改容器
(3) 将容器保存为新的镜像
举例:
docker run -it --name=myContainer myImage /bin/bash // 新建容器并运行
docker exec -it myContainer /bin/bash // 进入容器
vim .bashrc报错vim: command not found
apt-get update // 更新安装源
apt-get install vim // 安装vim
退出来保存新镜像:使用commit存为新镜像
docker commit -m "install vim" myContainer newImage:newTag
docker images // 查看新镜像
重新创建容器测试vim已可用
docker history newImage:newTag // 查看镜像构建历史
1.2 使用Dockerfile自动构建镜像(自动化)
docker程序通过读取Dockerfile文件中的指令生成生成镜像Dockerfile的每一行命令都生成了一个镜像层Dockerfile的结构:基础镜像信息 + 维护者信息 + 镜像 *** 作指令 + 容器启动时执行指令
2. Dockerfile镜像构建命令
(1) FROM
功能:指定基础镜像,必须为第一条指令;如果不以任何镜像为基础,FROM scratch
语法:
FROM : # 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
# 2、exec命令格式(常用)
CMD ["<可执行文件或命令>","" ,"" ,...]
# 3、该写法是为ENTRYPOINT指令指定的程序提供默认参数
CMD ["" ,"" ,...]
注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 ["" ,... "" ]
注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 ...
COPY ["" ,... "" ]
注1:与ADD的区别,COPY只能复制本地文件,其他一样
(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 ["" , "" , ...]
注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来查看
# 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
参考文章:
Dockerfile镜像构建命令1
Dockerfile镜像构建命令2
docker dockerfile详解
Dockerfile实战
Docker镜像构建实例-推荐
docker-hub官网
created by shuaixio, 2022.05.14
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)