前文我们使用官方提供的hello world镜像作为验证例子,本文我们将基于Nginx+Ubuntu,根据我们的需求定制Docker镜像,并将其上传到DockerHub上,供以后多次使用。
准备文件
在开始构建镜像之前,我们首先看下构建一个基于Nginx+Ubuntu的Docker镜像,所需要的基本文件。文件目录结构,是按我的习惯布置的,读者可自行修改。如下文档可以访问Github仓库 [ mancodenet/images/docker-nginx-ubuntu ] 下载。
对文件 Dockefile 的说明
其中Dockerfile文件是构建镜像的核心文件,基于该文件,我们使用docker build命令来构建镜像。我们看下它的内容:
1 | # Nginx 服务镜像 |
这里简单描述下该文件的具体含义:
No.1 ~ No.3 | 是注释行,这里我分别写了构建指令以及运行指令,供读者使用。 |
No.5 | 我们特别注意,此命令表明我们使用名为“ubuntu:22.04”的Docker镜像作为基础镜像,来构建我们的镜像。 构建时,系统会从hub.docker.com自动下载到本地。 |
No.7 | 镜像运行时默认的当前工作目录 |
No.15 | 将本地的nginx源码包拷贝到镜像中:/opt/app/nginx/nginx-1.25.4.tar.gz。 |
No.17 | 将本地的nginx静态页面拷贝到镜像:/usr/local/nginx/www/index.html。该文件作为测试nginx的默认静态页面。 |
No.19 | 由于编译Nginx需要第三方库的支撑,使用apt安装在镜像中编译nginx所需要的第三方库。 |
No.21 | 解压Nginx源代码包。 |
No.22 ~ No.34 | 配置Nginx,从而产生Makefile文件。 |
No.35 | 编译Nginx,并进行安装。 |
No.36 | 创建镜像中nginx日志目录。 |
No.37 | 创建镜像中nginx所需http-client-body-temp-path等临时目录。 |
No.39 | 将本地nginx配置文件拷贝到镜像:/etc/nginx/nginx.conf、/etc/nginx/conf.d/default.conf。该配置文件将作为nginx容器的启动配置文件。 |
No.41 | 指定容器的入口地址,作为第一个执行的程序,也是pid=1的进程。 |
注意!!注意!!
Nginx的镜像,务必在ENTRYPOINT的入口或者nginx.conf配置文件中 指定 daemon off 属性,表明不让Nginx自动进入后台守护进程。如果不指定该属性,你会发现启动镜像,容器就会马上退出!
这是因为:Docker默认将容器内部的第一个进程,亦即pid=1的程序作为容器是否存活的判断条件,如果容器中pid=1的进程挂掉了,该容器便会自动直接退出。
对nginx配置文件的说明
对nginx的配置与其他配置没什么区别,我们使用如下的配置文件内容。
/etc/nginx/nginx.conf 配置文件内容:
1 | user nginx; |
/etc/nginx/conf.d/default.conf 配置文件内容:
1 | server { |
用户可以根据的需要进行调整。
对文件 nginx-1.25.4.tar.gz 的说明
该文件是nginx的源代码包,我们可以点击该下载链接:nginx-1.25.4.tar.gz。
或者到官网 https://nginx.org/en/download.html 下载其他的版本:
构建镜像
将上述文件准备妥当之后,我们使用如下命令开始构建镜像:
1
$ sudo docker build --build-arg VERSION=1.0.0 -t nginx-ubuntu:1.0.0 .
命令执行过程如下所示:
可见上述构建命令执行完毕之后,我们使用 sudo docker images
命令可以看到本地已经生成了我们的镜像 nginx-ubuntu。
启动容器
nginx-ubuntu:1.0.0镜像成功生成之后,我们开始测试下启动容器,看看该容器是否能够正确的完成我们预设的功能。使用如下命令启动容器:
1
$ sudo docker run -p 80:80 -d nginx-ubuntu:1.0.0
通过上图可以看到,我们定制的nginx-ubuntu镜像成功启动了,并且可以在宿主机上正常访问容器中的Nginx服务。
发布镜像
至此,我们已经成功制作了我们所需的镜像,并且顺利运行起来了。下面的工作是我们将其打包发布到DockerHub网站上,供我们后续下载使用。
第一步,你需要在 https://hub.docker.com 网站注册自己的账号。如下图所示:
第二步,注册成功之后,在构建服务器上登录该账号。如下图所示:
第三步,在构建服务器上为镜像打tag。
1
2$ sudo docker image tag nginx-ubuntu:1.0.0 mancodenet/nginx-ubuntu:1.0.0
$ sudo docker image tag nginx-ubuntu:1.0.0 mancodenet/nginx-ubuntu:latest
注意:mancodenet是我在hub.docker.com网站的账号,这里需要换成你自己的账号。
执行过程如下图所示:
第四步,推送镜像到DockerHub服务器。
1
2$ sudo docker push mancodenet/nginx-ubuntu:1.0.0
$ sudo docker push mancodenet/nginx-ubuntu:latest
执行过程如下图所示:
第五步,我们看下DockerHub上我们推送的镜像。如下图所示:
我们点击进去,看下该镜像的详细情况。如下图所示:
清空本地所有容器、镜像、缓存,然后测试从DockerHub拉取nginx-ubuntu镜像
上述所有完成之后,我们来个实战测试,就是清空当前构建服务器Docker的所有缓存数据后(或者在一个新的服务器上),从DockerHub拉取 nginx-ubuntu 镜像,然后运行。
首先,我们使用如下命令,清空本地所有容器、镜像、缓存:
1
2
3
4
5
6
7
8
9
10
11# 停止所有运行的容器
$ sudo docker stop $(sudo docker ps -aq)
# 删除所有的容器
$ sudo docker rm $(sudo docker ps -aq)
# 删除所有的镜像
$ sudo docker rmi -f $(sudo docker images -q)
# 清空本地的缓存
$ sudo docker system prune -a
执行过程如下图所示:
清理前后的数据缓存对比,下图是执行之前:
下图是执行之后:
然后,我们使用如下命令从DockerHub拉取镜像,然后运行:
1 | $ sudo docker pull mancodenet/nginx-ubuntu:1.0.0 |
执行过程如下图所示: