镜像手动制作
- 启动一个centos容器,安装好常用软件和Nginx
[root@server ~]# docker run -d -it --name centos-1 centos:7 bash[root@server ~]# docker exec -it centos-1 bash[root@0b4f2005a775 /]# yum install epel-release -y[root@0b4f2005a775 ~]# yum install nginx -y[root@0b4f2005a775 ~]# yum install vim wget pcre pcre-devel zlib zlib-devel openssl openssl-devel iproute net-tools iotop -y
- 修改Nginx配置文件,关闭Nginx后台运行,让其在前台运行,这样的话之后构建的镜像容器就不会自动关闭
[root@0b4f2005a775 /]# vim /etc/nginx/nginx.confuser nginx;worker_processes auto;error_log /var/log/nginx/error.log;pid /run/nginx.pid;daemon off;
- 创建web界面
[root@0b4f2005a775 /]# echo "hello nginx" > /usr/share/nginx/html/index.html
- 提交为新镜像
[root@server ~]# docker commit -a "453048472@qq.com" -m "my nginx image v1" centos-1 centos_nginx:v1[root@server ~]# docker imagesREPOSITORY TAG IMAGE ID CREATED SIZEcentos_nginx v1 07f16f7cc1af 8 minutes ago 503MBnginx latest c919045c4c2b 2 weeks ago 142MBcentos 7 eeb6ee3f44bd 6 months ago 204MB
- 从新构建的一个镜像启动容器
[root@server ~]# docker run -d -p 8080:80 --name my_centos_nginx centos_nginx:v1 nginx[root@server ~]# curl 192.168.31.99:8080hello nginx
Docker commit命令说明
语法格式:docker commit [选项] 容器ID/容器名 [新镜像名:标签]
-a:提交的镜像作者-c:使用Dockerfile指令来创建镜像-m:提交时的说明文字-p:在commit时,将容器暂停
举例:
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的端口
EXPOSE 80 443
该指令只是完成了声明作用,不会自动完成端口映射
ENTRYPOINT
指定镜像的默认入口命令,该入口命令会在启动容器时作为根命令执行,所有传入值作为该命令的参数
支持两种格式
ENTRYPOINT ["executable","param1","param2"]exec调用执行ENTRYPOINT command param1 param2shell中执行
此时,CMD指令指定值将作为根命令的参数。
每个Dockerfile中只能有一个ENTRYPOINT,当指定多个时,只有最后一个生效
VOLUME
创建一个数据卷挂载点
作用:
- 避免重要的数据,因为容器重启而丢失
- 避免容器不断变大
VOLUME ["/data"]
WORKDIR
为后续的RUN、CMD、ENTRYPOINT配置工作目录
用 WORKDIR 指定的工作目录,会在构建镜像的每一层中都存在
docker build构建镜像过程中,每一个RUN命令都是新建的一层,只有通过WORKDIR创建的目录才会一直存在
WORKDIR /path/to/workdir
可以使用多个WORKDIR指令,后续命令如果参数是相对路径, 则会基于之前命令指定的路径
WORKDIR /aWORKDIR bWORKDIR cRUN 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 param2CMD command param1 param2在默认的shell中执行,提供给需要交互的应用CMD ["param1","param2"]提供给ENTRYPOINT的默认参数
ADD
添加内容到镜像
ADD <src> <dest>
将复制指定的src路径下的内容到容器中的dest路径下
src可以是Dockerfile所在目录的一个相对路径(文件或目录),也可以是一个URL,还可以是一个tar文件(自动解压文件)
dest可以是镜像内的绝对路径,或者相对于工作目录(WORKDIR)的相对路径
路径支持正则格式
COPY
复制内容到镜像
COPY <src> <dest>
COPY和ADD指令功能类似,但是使用本地目录为源目录时,推荐使用COPY
制作Nginx镜像
- 下载基础镜像
[root@server ~]# docker pull centos:7
- 创建目录环境
[root@server ~]# mkdir -p /docker/nginx/web
- 进入到指定目录
[root@server ~]# cd /docker/web/nginx
- 下载源码包
[root@server nginx]# wget http://nginx.org/download/nginx-1.20.1.tar.gz
- 编写Dockerfile文件
[root@server nginx]# vim Dockerfile# 第一行先定义基础镜像,如果本地没有会从远程仓库下载FROM centos:7# 镜像维护者的信息MAINTAINER Moodye 453048472@qq.com# 安装常用软件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# 上传nginx压缩包ADD nginx-1.20.1.tar.gz /usr/local/src# 将编译安装nginx的步骤执行一遍RUN cd /usr/local/src/nginx-1.20.1 \&& ./configure --prefix=/usr/local/nginx --with-http_sub_module \&& make \&& make install \&& cd /usr/local/nginx# 可以添加自己事先准备的配置文件# ADD nginx.conf /usr/local/nginx/conf/nginx.confRUN useradd -s /sbin/nologin nginx \&& ln -sv /usr/local/nginx/sbin/nginx /usr/sbin/nginx \&& echo 'test nginx' > /usr/local/nginx/html/index.html# 声明端口号EXPOSE 80 443# -g代表从配置文件中设置全局指令,daemon off代表守护进程关闭,即前台启动CMD ["nginx","-g","daemon off;"]
- 构建镜像
[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
- 启动容器,访问测试
[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成一个镜像,最后删除这个临时的容器
构建过程中:
构建完成之后:


