镜像手动制作

  1. 启动一个centos容器,安装好常用软件和Nginx
  1. [root@server ~]# docker run -d -it --name centos-1 centos:7 bash
  2. [root@server ~]# docker exec -it centos-1 bash
  3. [root@0b4f2005a775 /]# yum install epel-release -y
  4. [root@0b4f2005a775 ~]# yum install nginx -y
  5. [root@0b4f2005a775 ~]# yum install vim wget pcre pcre-devel zlib zlib-devel openssl openssl-devel iproute net-tools iotop -y
  1. 修改Nginx配置文件,关闭Nginx后台运行,让其在前台运行,这样的话之后构建的镜像容器就不会自动关闭
  1. [root@0b4f2005a775 /]# vim /etc/nginx/nginx.conf
  2. user nginx;
  3. worker_processes auto;
  4. error_log /var/log/nginx/error.log;
  5. pid /run/nginx.pid;
  6. daemon off;
  1. 创建web界面
  1. [root@0b4f2005a775 /]# echo "hello nginx" > /usr/share/nginx/html/index.html
  1. 提交为新镜像
  1. [root@server ~]# docker commit -a "453048472@qq.com" -m "my nginx image v1" centos-1 centos_nginx:v1
  2. [root@server ~]# docker images
  3. REPOSITORY TAG IMAGE ID CREATED SIZE
  4. centos_nginx v1 07f16f7cc1af 8 minutes ago 503MB
  5. nginx latest c919045c4c2b 2 weeks ago 142MB
  6. centos 7 eeb6ee3f44bd 6 months ago 204MB
  1. 从新构建的一个镜像启动容器
  1. [root@server ~]# docker run -d -p 8080:80 --name my_centos_nginx centos_nginx:v1 nginx
  2. [root@server ~]# curl 192.168.31.99:8080
  3. hello nginx

Docker commit命令说明

语法格式:docker commit [选项] 容器ID/容器名 [新镜像名:标签]

  • -a :提交的镜像作者
  • -c :使用Dockerfile指令来创建镜像
  • -m :提交时的说明文字
  • -p :在commit时,将容器暂停

举例:

  1. docker commit -a "453048472@qq.com" -m "my nginx image v1" centos-1 centos_nginx:v1

DockerFile制作镜像

Dockerfile是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明

Docker程序读取DockerFile并根据指令生成Docker镜像,相比手动制作镜像的方式,DockerFile更能直观地展示镜像是怎么产生的,有了写好的各种各样的DockerFIle文件,当后期某个镜像有额外的需求时,只要在之前的DockerFile添加或者修改相应的操作即可重新生成新的Docker镜像,避免了重复手动制作镜像的麻烦

特别注意:编写的Dockerfile文件名必须为Dockerfile,否则就会无法构建

指令说明

配置指令

指令 说明
ARG 定义创建镜像过程中使用的变量
FROM 指定创建镜像的基础镜像
LABEL 为生成的镜像添加元数据标签信息
EXPOSE 声明镜像内服务监听的端口
ENV 指定环境变量
ENTRYPOINT 指定镜像的默认入口命令
VOLUME 创建一个数据卷挂载点
USER 指定运行容器时的用户名或UID
WORKDIR 配置工作目录
ONBUILD 创建子镜像时指定自动执行的操作指令
STOPSIGNAL 指定退出的信号值
HEALTHCHECK 配置所启动容器如何进行健康检查
SHELL 指定默认shell类型

操作指令

指令 说明
RUN 运行指令
CMD 启动容器时指定默认执行的指令
ADD 添加内容到镜像
COPY 复制内容到镜像

指令详解

ARG

定义创建镜像过程中使用的变量

比如:HTTP_PROXY 、HTTPS_PROXY 、FTP_PROXY 、NO_PROXY不区分大小写

FROM

指定所创建镜像的基础镜像

FROM指令开始一个新的构建阶段,设置后续构建依赖的基础镜像,镜像可以是任意的有效镜像。

EXPOSE

声明镜像内服务监听的端口

作用:

  • 帮助镜像使用者理解这个镜像服务的守护端口,方便配置映射
  • 在运行时使用随机端口映射,也就是docker run -P时,会自动随机映射EXPOSE的端口
  1. EXPOSE 80 443

该指令只是完成了声明作用,不会自动完成端口映射

ENTRYPOINT

指定镜像的默认入口命令,该入口命令会在启动容器时作为根命令执行,所有传入值作为该命令的参数

支持两种格式

  • ENTRYPOINT ["executable","param1","param2"]exec调用执行
  • ENTRYPOINT command param1 param2shell中执行

此时,CMD指令指定值将作为根命令的参数。

每个Dockerfile中只能有一个ENTRYPOINT,当指定多个时,只有最后一个生效

VOLUME

创建一个数据卷挂载点

作用:

  • 避免重要的数据,因为容器重启而丢失
  • 避免容器不断变大
  1. VOLUME ["/data"]

WORKDIR

为后续的RUN、CMD、ENTRYPOINT配置工作目录

用 WORKDIR 指定的工作目录,会在构建镜像的每一层中都存在

docker build构建镜像过程中,每一个RUN命令都是新建的一层,只有通过WORKDIR创建的目录才会一直存在

  1. WORKDIR /path/to/workdir

可以使用多个WORKDIR指令,后续命令如果参数是相对路径, 则会基于之前命令指定的路径

  1. WORKDIR /a
  2. WORKDIR b
  3. WORKDIR c
  4. RUN pwd

最终路径为/a/b/c,为了避免出错,推荐WORKDIR指令中只使用绝对路径

RUN

作用:运行指定命令

每条RUN指令将会在当前镜像基础上执行指定命令,并提交为新的镜像层

当命令较长时可以通过\来换行

CMD

用来指定启动容器时默认执行的命令

如果Dockerfile中存在多个CMD指令,仅最后一个生效

类似于RUN指令,用于运行程序,但二者运行的时间点不同:

  • CMD在docker run时运行
  • RUN是在docker build时运行

作用:

  • 为启动的容器指定默认要运行的程序,程序运行结束,容器也就结束
  • CMD指令指定的程序可以被docker run命令行参数中指定要运行的程序所覆盖

格式:

  • CMD ["executable","param1","param2"]相当于执行executable param1 param2
  • CMD command param1 param2在默认的shell中执行,提供给需要交互的应用
  • CMD ["param1","param2"]提供给ENTRYPOINT的默认参数

ADD

添加内容到镜像

  1. ADD <src> <dest>

将复制指定的src路径下的内容到容器中的dest路径下

src可以是Dockerfile所在目录的一个相对路径(文件或目录),也可以是一个URL,还可以是一个tar文件(自动解压文件)

dest可以是镜像内的绝对路径,或者相对于工作目录(WORKDIR)的相对路径

路径支持正则格式

COPY

复制内容到镜像

  1. COPY <src> <dest>

COPY和ADD指令功能类似,但是使用本地目录为源目录时,推荐使用COPY

制作Nginx镜像

  1. 下载基础镜像
  1. [root@server ~]# docker pull centos:7
  1. 创建目录环境
  1. [root@server ~]# mkdir -p /docker/nginx/web
  1. 进入到指定目录
  1. [root@server ~]# cd /docker/web/nginx
  1. 下载源码包
  1. [root@server nginx]# wget http://nginx.org/download/nginx-1.20.1.tar.gz
  1. 编写Dockerfile文件
  1. [root@server nginx]# vim Dockerfile
  2. # 第一行先定义基础镜像,如果本地没有会从远程仓库下载
  3. FROM centos:7
  4. # 镜像维护者的信息
  5. MAINTAINER Moodye 453048472@qq.com
  6. # 安装常用软件
  7. RUN yum install -y vim wget tree lrzsz gcc gcc-c++ automake pcre pcre-devel zlib zlib-devel openssl openssl-devel iproute net-tools iotop
  8. # 上传nginx压缩包
  9. ADD nginx-1.20.1.tar.gz /usr/local/src
  10. # 将编译安装nginx的步骤执行一遍
  11. RUN cd /usr/local/src/nginx-1.20.1 \
  12. && ./configure --prefix=/usr/local/nginx --with-http_sub_module \
  13. && make \
  14. && make install \
  15. && cd /usr/local/nginx
  16. # 可以添加自己事先准备的配置文件
  17. # ADD nginx.conf /usr/local/nginx/conf/nginx.conf
  18. RUN useradd -s /sbin/nologin nginx \
  19. && ln -sv /usr/local/nginx/sbin/nginx /usr/sbin/nginx \
  20. && echo 'test nginx' > /usr/local/nginx/html/index.html
  21. # 声明端口号
  22. EXPOSE 80 443
  23. # -g代表从配置文件中设置全局指令,daemon off代表守护进程关闭,即前台启动
  24. CMD ["nginx","-g","daemon off;"]
  1. 构建镜像
[root@server nginx]# docker build -t nginx:v1 .
[root@server nginx]# docker images
REPOSITORY     TAG     IMAGE ID       CREATED          SIZE
nginx          v1      a9fc51fba39a   17 seconds ago   559MB
  1. 启动容器,访问测试
[root@server nginx]# docker run -d -it -p 8080:80 nginx:v1
6b74fa5972014dfddcb5ad9798a24664c22bb39d22c14c2ba04c6b996ec39934
[root@server nginx]# curl 192.168.31.99:8080
test nginx

当在build镜像的时候,可以查看一下容器列表,此时发现会有一个临时容器出现,其实这就体现了Dockerfile构建镜像的原理,它的本质就是和镜像手动制作的原理一样,先是启动一个基础容器,然后在这个容器里进行一些操作,将这个容器commit成一个镜像,最后删除这个临时的容器

构建过程中:

Docker构建镜像 - 图1

构建完成之后:

Docker构建镜像 - 图2