一、前言

  Nginx官方安装包下载地址:
  http://nginx.org/en/download.html

 
  Docker Hub官方网址:
  https://hub.docker.com/

 
  如果需要了解Centos7下Docker的安装部署,可参考教程【最新Docker在Centos7下安装部署(参考官方教程文档)】。
 
  拉取Nginx Docker版镜像的最简单的命令是:docker pull nginx ,麻烦一点写法是 docker pull nginx:1.22.1 ,后面带一个版本号,拉取指定版本的镜像。如果看一些博文,教程里面就是这么写的,难道有错?没错,这样写是可以的,但是,那些博主可不会告知你们,如何区分版本,Docker Hub中Nginx是有很多版本类型的,他们也未必研究过Docker中Nginx各版本的区别,只是照搬官方的写法而已!
 
  本教程除了详细指导在Docker中安装最新稳定版Nginx过程,还分析一些版本选择问题,网上基本很少或没有相关博文讨论过Docker中Nginx版本的选择问题。最后还有踩坑过程也分享出来。如果各位读者有更好的见解,可以关注 @大白有点菜 或在评论中交流,互相学习进步。
 

  本文由 @大白有点菜 原创,请勿盗用,转载请说明出处!如果觉得文章还不错,请点点赞,加关注,谢谢!
 

二、版本选择问题分析

 

1、先来分析Docker中Nginx各版本选择问题。读者如果觉得这部分没意思,可跳过,直接看后面的安装步骤。【 跳转到安装部署部分

(1)浏览Docker Hub网址,即Docker的仓库,搜索关键字 nginx 查找Nginx的版本(和官方Nginx的版本是同步的)。
 
浏览Docker Hub网址并搜索nginx内容
 
(2)点击第一个,进入到 Nginx 相关页面,包括一些 版本介绍安装教程在页面的下半部分)。

https://hub.docker.com/_/nginx

 
点击第一个 
Nginx 相关页面包括一些版本介绍和安装教程

 
(3)怎么这么多版本啊,有纯数字的,有纯英文单词的,有几个单词拼接一起的,也有数字拼单词的,看得眼花缭乱,如何选择?先关注两个关键词语:mainlinestable

  • mainline主线版,即开发版,学习环境可以使用,生产环境建议不要使用
  • stable稳定版,学习环境和生产环境都可使用

(4)切换到“Tags”标签,看看Nginx的具体版本,按最新版本排序。
 
切换到“Tags”标签
 
Nginx的具体版本1 
Nginx的具体版本2 
(5)本教程的核心是安装最新稳定版Nginx,mainline版不过多介绍,主要介绍stable版。目前官网上有四个稳定版本:stable-perlstable-alpine-perlstable-alpinestable 。它们有什么区别呢?从稳定版本名称分解得到两个单词:alpineperl ,这两个单词又代表什么意思呢?

  • alpine:即 Alpine Linux,是一个轻量级Linux发行版系统。
  • perl:计算机编程语言,内部集成了正则表达式的功能,以及巨大的第三方代码库CPAN。

【百度百科解释 Alpine Linux】
百度百科解释 Alpine Linux 
【维基百科解释 Alpine Linux】
维基百科解释 Alpine Linux 
【百度百科解释 Perl】
百度百科解释 Perl
 
【维基百科解释 Perl】
维基百科解释 Perl1 
维基百科解释 Perl2
 
维基百科解释 Perl3 
  从上面的专业解释可以作出以下猜测

  • stable-perl:包含最新的perl模块的稳定版,适合安装在Centos上。
  • stable-alpine-perl:包含最新的perl模块的稳定版,适合安装在Alpine Linux上。
  • stable-alpine:不包含perl模块的稳定版,适合安装在Alpine Linux上。
  • stable:包含最新的perl模块的稳定版,适合安装在Centos上。

  猜测是正确的吗?查阅资料可知,perl模块是默认安装在Centos系统上的,如下,版本为 v5.16.3 。
 
perl工具是默认安装在Centos系统上的
 

2、创建四个stable版本容器。

(1)在Docker Hub官网对应的Nginx页面,有个描述是关于 nginx:<version>-perlnginx:<version>-alpine-perlnginx:<version>-alpine 的,截图如下,顺便附上谷歌翻译后的截图:
 
Docker Hub官网对应的Nginx页面某些版本的描述
 
Docker Hub官网对应的Nginx页面某些版本的描述(翻译) 
(2)按官方说法,版本名称不带后缀“-perl”的,默认镜像从Nginx-v1.13.0(主线版)和Nginx-v1.12.0(稳定版)开始移除了 perl 模块,是这样吗?后缀带有“-alpine”的版本适用于 Alpine Linux ,但在Centos7下能用吗?两者都验证一下吧。
 
1)拉取4个稳定版本的镜像。

docker pull nginx:stable
docker pull nginx:stable-perl
docker pull nginx:stable-alpine
docker pull nginx:stable-alpine-perl

2)查看下载的镜像。

docker images

查看下载的镜像
 
3)创建 stable 版的容器 nginx-s,映射端口设置为 8111,进入容器查看 perl 模块是否存在。发现 perl 模块是存在的,版本为 v5.32.1
 
后台(-d)方式运行一个容器(nginx-s),将端口 8111 映射到容器的 80 端口:

docker run --name nginx-s -p 8111:80 -d nginx:stable

查看容器运行情况:

docker ps

进入到容器中(/bin/bash):

docker exec -it 732 /bin/bash

查看 perl 模块版本:

perl -v

命令 exit 退出容器:

exit

创建端口8111的容器nginx-s 
4)创建 stable-perl 版的容器 nginx-sp,映射端口设置为 8222,进入容器查看 perl 模块是否存在。发现 perl 模块是存在的,版本也为 v5.32.1
 
后台(-d)方式运行一个容器(nginx-sp),将端口 8222 映射到容器的 80 端口:

docker run --name nginx-sp -p 8222:80 -d nginx:stable-perl

查看容器运行情况:

docker ps

进入到容器中(/bin/bash):

docker exec -it 840 /bin/bash

查看 perl 模块版本:

perl -v

命令 exit 退出容器:

exit

创建端口8222的容器nginx-sp 
5)可以创建 stable-alpine 版的容器 nginx-sa 并运行吗?那就试试,映射端口设置为 8333 ,可以运行的话就进入容器查看 perl 模块是否存在。经验证,此版本的Docker容器可以在Centos7运行。发现 perl 模块是不存在的,镜像中移除了 perl 模块。
 
后台(-d)方式运行一个容器(nginx-sa),将端口 8333 映射到容器的 80 端口:

docker run --name nginx-sa -p 8333:80 -d nginx:stable-alpine

查看容器运行情况:

docker ps

进入到容器中(/bin/sh),此处和 stable、stable-perl 进入容器的方式不一样

docker exec -it 907 /bin/sh

查看 perl 模块版本:

perl -v

命令 exit 退出容器:

exit

创建端口8333的容器nginx-sa
 
6)创建 stable-alpine-perl 版的容器 nginx-sap ,映射端口设置为 8444 ,进入容器查看 perl 模块是否存在。发现 perl 模块是存在的,版本为 v5.34.1
 
后台(-d)方式运行一个容器(nginx-sap),将端口 8444 映射到容器的 80 端口:

docker run --name nginx-sap -p 8444:80 -d nginx:stable-alpine-perl

查看容器运行情况:

docker ps

进入到容器中(/bin/sh),此处和 stable、stable-perl 进入容器的方式不一样

docker exec -it 0ec /bin/sh

查看 perl 模块版本:

perl -v

命令 exit 退出容器:

exit

创建端口8444的容器nginx-sap
 

3、大概对比Nginx这四个stable版本的差异。

总结如下:
 
(1)笔者专业技能有限,无法看出 stable 版 和 stable-perl 版有什么区别,官方说好的 stable 版从 v1.12.0 开始,在默认镜像中移除了 perl 模块,怎么 stable 版的还存在?是笔者误读了官方的说法吗?
 
(2)stable-alpine 版确实移除perl 模块。
 
(3)stable-alpine-perl 版存在 perl 模块,且版本很新。
 
(4)stable-alpine 版和 stable-alpine-perl 版都可以运行在Centos7上,常不常用,笔者阅历有限,无法给出专业说法。
 

4、版本选择(求稳不求新)。

  无论是生产环境,还是工作、学习环境,都尽量使用稳定版去开发!Java开发中使用很多中间件,不求新(最新版),只求稳(稳定版),不然容易出现问题,排查困难。
 
  当然,旧版本也是存在问题的,有些bug会很致命,尽量跨小版本升级,主要是修复bug。跨大版本升级可能导致各种问题,不建议这么做。什么是大小版本?例如,MySQL5.7有很多版本MySQL5.7.x,属于跨小版本;从MySQL5升级到MySQL8,就是跨大版本。
 
  可以去Nginx官网查看最新的稳定版本(Stable version),使用 docker pull nginx:1.22.1 命令拉取最新稳定版镜像,也可以使用 docker pull nginx:stable 拉取,不用考虑输入版本号。
 
Nginx官网 

5、分析镜像各版本名称。

(1)Docker Hub上,Nginx的版本名称这么多,难道都是不同的版本?其实不是,官方页面展示出一些规律,同一个镜像ID的,都放在同一行,就像 1.23.2, mainline, 1, 1.23, latest ,看起来名称都不一样,其实镜像就是同一个的。不信?那就验证呗!
Nginx的版本多
 
(2)依次拉取不同版本号的镜像,以拉取 1.23.2 系列为例。如果nginx后面不跟版本号,默认拉取的是最新的版本,即 latest 版本。镜像ID(IMAGE ID)都一样,说明就是同一个版本

docker pull nginx
docker pull nginx:1.23.2
docker pull nginx:mainline
docker pull nginx:1
docker pull nginx:1.23
docker pull nginx:latest

如果nginx后面不跟版本号,默认拉取的是latest版本 
镜像版本一样
 

三、安装部署

 
  前面的版本选择问题分析好无聊啊,还是直接安装部署更过瘾。
 

1、创建三个目录,用作容器的卷(Volume),这步骤不能少。什么是卷?后面会说明。
mkdir -p /mydata/nginx/conf
mkdir -p /mydata/nginx/log
mkdir -p /mydata/nginx/html

创建三个目录
 

2、笔者当时也是看了一些博文教程,操作过程中踩了坑,特来分享踩坑过程,如下步骤是错误的操作,先演示看效果,再来分析问题。

(1)创建一个简单的容器运行,映射端口为 8099 ,看看有没有报错或者网络问题。

docker run --name nginx -p 8099:80 -d nginx:stable

映射端口为 8099的简单容器 
(2)浏览器输入 192.168.56.10:8099 并回车,这是虚拟机Centos7的IP地址。正常访问到 Nginx 。
 
正常访问到Nginx 
(3)停止容器后,再删除这个简单的容器,因为下一步要重新创建一个容器,把第一步新建的三个目录配置为容器的卷去运行。想要优雅地删除容器,可参考教程【如何优雅地删除Docker镜像和容器(超详细)】。创建的容器的映射端口为 8066

docker run --name nginx -v /mydata/nginx/conf:/etc/nginx/conf.d -v /mydata/nginx/log:/var/log/nginx -v /mydata/nginx/html:/usr/share/nginx/html -p 8066:80 -d nginx:stable

运行新的容器
 
(4)nginx:stable 容器能正常运行,在浏览器输入 192.168.56.10:8066 并回车,发现居然报错了,什么情况???
 
nginx:stable 容器能正常运行 nginx丢失页面 
(4)查看 /mydata/nginx/html 目录下有没有 index.html 文件,同时进入到容器中看看 /usr/share/nginx/html/ 目录有没有对应的 index.html 文件。发现两者都没有 index.html 文件。
 
/mydata/nginx/html
 
/usr/share/nginx/html/

 

3、前面操作中,运行一个配置有卷(Volume)的容器为什么会访问不到页面呢,而运行简单的容器却可以访问呢?

(1)什么是卷(Volume)?命令 docker -v 中的“-v”就是这个卷,“-v”只是“--volume”的简写。
 
  Docker官方文档解释的含义:https://docs.docker.com/storage/volumes/
 
  来几张原文截图,并附上谷歌翻译后的截图
 
Volume1 
Volume2
 
Volume3
 
Volume4
 
Volume5
 
Volume6
 
Volume7 
Volume8
 
(2)从官方文档对 卷(Volume) 的介绍可以看出,是有别于常见的 绑定挂载(bind mounts) 的,两者作用类似,只是使用卷(Volume)会更好,官方更推荐使用“-v”方式而不是“--mount”。前面创建的Nginx三个目录 confloghtml 分别与Nginx容器中:/etc/nginx/conf.d/var/log/nginx/usr/share/nginx/html 作为 的方式关联在一起,可以理解为挂载在一起了,达到共享文件的目的。卷的默认权限是读写,如果在后面加上“:ro”,代表只读,即容器对卷的权限只能读取文件。
 
(3)前面的运行的容器为什么找不到网页呢?因为本地的创建的 html 目录里面没有任何文件啊,作为共享目录,容器里面 /usr/share/nginx/html 肯定也是空目录啊! 有解决方法吗?那当然,下面的步骤就是正确操作。
 

4、正确地创建Nginx容器。

(1)创建一个更简单的容器,不用映射端口,因为后面还要删除该容器,只是临时有用。

docker run --name nginx -d nginx:stable

创建一个更简单的容器,不用映射端口 
(2)进入到容器中,看看 /etc/nginx/ 、/var/log/ 、/usr/share/nginx/html/ 这三个目录都有些什么文件,因为要关联本地创建的Nginx相关的 conf、log、html 三个目录。
 
容器相关目录 

  • /etc/nginx:conf.dnginx.conf
  • /var/log/:nginx
  • /usr/share/nginx/html/:50x.htmlindex.html
  • /etc/nginx/conf.d:default.conf

 
(3)从容器中复制 /usr/share/nginx/html 目录所有文件到 /mydata/nginx 目录下,复制配置文件 /etc/nginx/nginx.conf/mydata/nginx/conf 目录下,复制 /etc/nginx/conf.d 目录所有文件到 /mydata/nginx/conf 目录下。

docker cp nginx:/usr/share/nginx/html /mydata/nginx
docker cp nginx:/etc/nginx/nginx.conf /mydata/nginx/conf
docker cp nginx:/etc/nginx/conf.d /mydata/nginx/conf

从容器中复制指定文件

 
(4)删除那个简单的容器。先停止,后删除。想要优雅地删除容器,可参考教程【如何优雅地删除Docker镜像和容器(超详细)】。
 
删除那个简单的容器。先停止,后删除。
 
(5)创建新的容器,配置指定目录和文件为卷。配置文件 nginx.conf 和目录 html 都是只读权限 :ro。发现容器是能正常运行的。

docker run --name nginx -v /mydata/nginx/conf/nginx.conf:/etc/nginx/nginx.conf:ro -v /mydata/nginx/conf/conf.d:/etc/nginx/conf.d -v /mydata/nginx/log:/var/log/nginx -v /mydata/nginx/html:/usr/share/nginx/html:ro -p 80:80 -d nginx:stable

创建新的容器,配置指定目录和文件为卷 
(6)浏览器输入 192.168.56.10 并回车,熟悉的页面回来了!
 
正常访问到nginx 

5、设置容器自启动。
docker update --restart=always nginx

设置容器自启动 

6、容器的启动、停止、删除、重新启动、查看运行状态。

(1)启动容器

docker start nginx

docker start 容器ID

(2)停止容器

docker stop nginx

docker stop 容器ID

(3)删除容器

docker rm nginx

docker rm 容器ID

(4)重新启动容器

docker restart nginx

docker restart 容器ID

(5)查看容器运行状态
 
查看所有容器的运行状态,包括运行的和停止的

docker ps -a

查看所有运行中的容器的状态,不包括停止的

docker ps

 

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐