一篇文章带你入门Docker + Nginx.

Posted 小马教你写Bug

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一篇文章带你入门Docker + Nginx.相关的知识,希望对你有一定的参考价值。

👨‍🏫 Docker And nginx.

简单学习Docker。

先理解一个问题:什么是容器?

我以前简单学Docker的时候,用Docker部署Redis和mysql的时候,我以为容器仅仅只是一个容器,在这里我首先要纠正一点就是,不要把容器想成简单的容器,可以把每一个容器想象成一个Linux环境,我认为这一点也是Docker比较牛的地方.

🔖 一、Docker学习。

参考:Docker 教程 | 菜鸟教程 (runoob.com)

💡 1.1 什么是Docker.

Docker 是一个开源的应用容器引擎,基于Go实现,遵从Apache2.0协议开源。Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的Linux机器上,这里所说的容器和上面我提到的容器是一个容器,容器是完全使用沙箱机制,可以这么理解就是,一台Linux部署了5个Docker容器,那么这一台电脑可以相当于6台电脑去使用,容器可以比作是Linux中的Linux,这个我也是在学习过程中才理解的.

不幸的是Docker开始收费了,但是幸运的是Docker提供社区版本来供我们学习.

💡 1.2 Docker 有什么优点.

现在,各个大厂都在使用Docker和K8S来进行上云,既然这么多大公司都在用,那么就说明,Docker肯定是有其非常亮眼的优势的,现在我们就来分析一下。

Docker 使您能够将应用程序与基础架构分开,从而可以快速交付软件。借助Docker可以以管理应用程序的方式来管理基础架构。通过利用Docker的方法来快速交付、测试、部署代码。

💡 1.3 Docker 整体将架构.

参考:[Docker] Docker整体架构图 - dhcn - 博客园 (cnblogs.com)

Docker 是基于C/S 模式的架构的,其通过 DocekrClient 和 与 Docker Daemon 建立通信,使用远程API来管理和创建Docker容器. 其可以通过HTTP API 形式通信也可以通过Socket方式进行通信.

Docker Client 通过发送请求到 Docker Server中,Docker Server 根据路由以及请求来调用Engine中的各个不同的Job来完成本次请求操作,而之后各个Job完成自己的任务向Engine返回即可.

💡 1.4 Docker安装.

因为DEV-CLOUD内部集成了Docker,所以这里省略. 如果想要在自己服务器上安装docker的话,参考上面 Docker 教程

💡 1.5 Docker 中容器和镜像的关系.

Docker中容器和镜像之间的关系就相当于操作系统中的进程和程序的关系。

💡 1.5 Docker命令.

下面是一些基本的Docker命令,一些高级的Docker命令没有列出来.

  • docker search nginx 搜索某个镜像.
  • docker pull nginx 下载nginx@latest.
  • docker images : 查看当前Docker中存在的镜像.
  • docker ps:查看当前未关闭的容器.
  • docker ps -a:查看所有容器.
  • docekr rm imagname 删除指定容器.
  • docker rmi imgid 删除指定镜像.
  • docker run --name 容器名字 -p 18088:18088 -d 镜像名字 , 关于docker run 的命令参数可以通过命令: docker run --help 去查看该命令参数的使用详解.
  • 使用 docker run 命令启动容器之后,可以通过 docker ps 查看当前正在运行的容器,如果发现当前没有正在运行的容器,那么可以使用 docker ps -a去查看所有的容器,包含已经关闭的容器.
  • docker exec -it 容器名字 bash:进入该容器内部,每一个容器都相当于是一个Linux环境。
  • docker strop 容器名字|容器ID 可以停掉该容器.
  • docker start 容器名字|容器ID 启动该容器,重新启动这个容器,可能该容器内部的配置文件已经改变.
  • docker restart 容器名字|容器ID 重启该容器.

💡 1.6 DockerFile 非常重要.

参考文档:Dockerfile详解

  • DockerFile的功能:我们可以利用DockerFIle来构建我们自己的Docker镜像,然后可以进行发布等,但是我们要进行构建镜像的话,前提是我们必须要依赖一个基础镜像. 而Dockerfile的第一行不能是注释,只能是FROM命令,表示该镜像的基础镜像是什么,docker build 在执行的时候从上乡下执行构建镜像,没执行一行命令就构建一个镜像,整个构建过程就相当于在基础镜像上层层叠加.

  • Dockerfile 命令形式.

    • Dockerfile 整体就两类语句组成:
    • ## 开头的注释信息.
    • instruction args 指令 + 参数.
    • Dockerfile 文件名字必须首字母大写.
    • Dockerfile 指令不区分大小写,但是为了方便和参数做区分,通常指令使用大写.
    • Dockerfile 指令按顺序从上至下依次执行.
    • Dockerfile 中第一个非注释行必须是FROM指令,用来指定当前镜像依据的是那个基础镜像.
    • Dockerfile 中需要调用的文件必须跟Dockerfile文件在同一目录下,或者在其子目录下,父目录或者其他路径将会失效.
  • Docker 命令.

    • FROM指令:
      • FROM 指令用于指定构建镜像所使用的基础镜像,后续的指令运行都要依靠此基础镜像上所提供的环境,也就是Dockerfile中是没有提供mkdir命令的。实际使用中,如果没有指定仓库,会先在本机查看是否有该基础镜像,没有则会去Docker Hub 上拉取.
      • 实例:FROM nginx
    • MAINTAINER
      • 用于让Dockerfile的作者提供个人信息,Dockerfile 并不限制MAINTAINER指令的位置,但是建议放在FROM指令之后,在比较新的版本中已经被LABEL指令替代.
      • 实例:MAINTAINER "zhenxinma@tencent.com"
    • COPY :用于复制宿主机上的文件到镜像上.
      • Demo : COPY "src" "dest" src 表示的是宿主主机上的文件 dest表示的是镜像上文件的位置.
      • 实例:COPY "./index.html" "/root/dockermapping/" 这样的话启动镜像之后,在镜像上位置/root/dockermapping/ 就有 ./index.html文件了.
      • 规则:
        • src 必须是build上下文中的目录,不能是其父目录中的文件.
        • 如果src是文件,则内部的文件或者子目录会被递归复制,DNAsrc目录本身不会被复制.
        • 如果指定了多个src,或者src中使用了通配符,则dest必须是一个目录,且必须以/结尾.
        • 如果dest不存在,那么会自动创建.
    • LABEL :让用户镜像指定各种元数据.
      • 类似 docker run -l 等,让用户镜像指定各种元数据,键值对的形式.
      • 实例:LABEL K1=V1 K2=V2
    • ADD :类 COPY
      • 作用:ADD和COPY指令类似,不过ADD支持使用tar文件和URL路径文件. 当拷贝的源文件是tar文件时,会自动展开为一个目录并拷贝进新的镜像中,而通过URL获取到的tar文件不会自动展开,宿主机可以联网的情况下,docker build 可以将网络上的某文件引用下载并打包到新的镜像中.
      • 实例:ADD "src" "dest"
    • WORKDIR:指定工作目录. 不是很清楚.
    • VOLUME :docker run -v 简化版. 也不是很懂.
      • 用于在镜像中创建一个挂载的目录, 在dockerfile中支持docker管理的卷,也就是说只能指定容器内部的路径,不能指定宿主机的路径.
      • 实例: VOLUME “moutpoint”
    • EXPOSE :同docker run --expost
      • 指定容器中待暴露的端口。比如容器提供的是一个https服务并且需要对外提供访问,那就需要指定暴露443端口,然后在使用此镜像启动容器时通过-P的参数才能将待暴露的状态转换为真正暴露的端口.
      • 实例:EXPOSE "port/tcp"
    • ENV :为镜像定义所需要的环境变量,这里定义的变量应该可以通过go里面的os.GetEnv获取到.
      • ENV k v 这种只能一次定义一个,ENV k=v k=v 可以定义多个.

🔖 二、Nginx.

文档:Nginx中文文档

💡 2.1 什么是Nginx?

Nginx是一款自由的、开源的、高性能的HTTP服务器和反向代理服务器,同时也是一个IMAP、POP3、SMTP代理服务器,Nginx 可以作为一个HTTP服务器进行网站的发布,另外Nginx可以作为反向代理进行负载均衡的实现.

  • 正向代理:服务端不知道客户端.
  • 反向代理:客户端不知道服务端.

💡 2.2 Nginx 能用来做什么.

  • 静态 HTTP 服务器:Nginx 是一个 HTTP 服务器,可以将服务器上的静态文件(HTML、图片)通过HTTP协议展现给客户端.
  • 反向代理服务器:反向代理是Nginx做的最多的一件事情,客户端不知道服务端的地址,客户端去请求该Nginx,Nginx通过配置的的路由规则将路由分发到不同的机器上,这个过程客户端是不知道服务端的地址的,只知道Nginx的地址.
  • 负载均衡:当网站访问量非常大的时候,可以通过Nginx + 反向代理实现负载均衡 .

💡 2.3 应该怎么用呢?

简单来说就是先配置好路由规则以及域名、监听端口,然后启动Nginx,启动之后,根据HTTP请求去访问Nginx监听的端口,Nginx会根据URI去匹配指定的资源文件.

💡 2.4 Nginx工作原理.

参考文档:Nginx工作原理和优化总结

  • Nginx 进程模型:

Nginx采用异步非阻塞的方式来处理网络事件,具体过程:

  • 接收请求:每个Worker都是从master进程fork过来的,在master进程建立好需要listen的socket之后,然后带上这个socketfork出多个进程,所有worker进程的socket会在新链接到来时变得可读,每个work进程都可以去accept这个socket,当一个请求到来时,所有可accept的work进程都会感受到通知,为了保证只有一个accept成功,Nginx提供了一个共享锁来保证同一时刻只有一个work进程accept链接。所有worker进程在注册socket读事件前抢accept_mutex,抢到互斥锁的那个进程可以注册socket读事件,在读事件里面调用accept接收该链接.
  • 处理请求:当一个worker进程在accept这个链接之后,就开始读取请求、解析请求、处理请求、产生数据之后,再返回给客户端之后才断开链接。

💡 2.5 Nginx 配置详解.

参考博客:最全Nginx 配置文件详解

由于我们这里是用Docker启动的Nginx,所以我们只需要关注Nginx内部配置文件即可,如果不是通过Docker安装的Nginx的话,我们可以通过去Nginx安装目录下面的sbin文件中去启动Nginx.

  • Nginx 整体配置.
...              #全局块

events {         #events块
   ...
}

http      #http块
{
    ...   #http全局块
    server        #server块
    { 
        ...       #server全局块
        location [PATTERN]   #location块
        {
            ...
        }
        location [PATTERN] 
        {
            ...
        }
    }
    server
    {
      ...
    }
    ...     #http全局块
}
  1. 全局快:配置影响Nginx全局的指令,一般有运行Nginx服务器的用户组,Nginx进程PID存放路径、日志存放路基、配置文件引入、允许生成Worker的个数等.
  2. events快:配置影响Nginx服务器或者与用户的网络连接,有每个进程的最大连接数,选取那种事件驱动模型处理链接请求,是否允许同时接收多个网络连接,开启多个网络序列化等。
  3. http快:可以嵌套多个server,配置代理、缓存,日志定义等绝大多数功能和第三方模块的配置、链接超时时间、单链接请求数等.
  4. server快:配置虚拟主机的相关参数,比如域名、编码规则等.
  5. location块:配置请求路由、以及各种页面处理情况等,比较核心.
  • Nginx 详细配置.
#定义Nginx运行的用户和用户组
# 如果出现403可以将user改为root,那是因为本次请求没有权限访问该路径表示的资源. 
user root;
#
#nginx进程数,建议设置为等于CPU总核心数.也就是上面的worker的数量. 
worker_processes 8;
#
#全局错误日志定义类型,[ debug | info | notice | warn | error | crit ]
error_log /var/log/nginx/error.log info;
#
#进程文件
pid /var/run/nginx.pid;
#
#一个nginx进程打开的最多文件描述符数目,理论值应该是最多打开文件数(系统的值ulimit -n)与nginx进程数相除,但是nginx分配请求并不均匀,所以建议与ulimit -n的值保持一致.
# 不是很懂这个 . 
worker_rlimit_nofile 65535;
#
#工作模式与连接数上限
events
{
    #参考事件模型,use [ kqueue | rtsig | epoll | /dev/poll | select | poll ]; epoll模型是Linux 2.6以上版本内核中的高性能网络I/O模型,如果跑在FreeBSD上面,就用kqueue模型.
    use epoll;
    #单个进程最大连接数(最大连接数=连接数*进程数)
    worker_connections 1024;    #最大连接数,默认为512
}
#
#设定http服务器
http
{
    
    #charset utf-8; #默认编码
    client_header_buffer_size 32k; #上传文件大小限制
    keepalive_timeout 65;  #连接超时时间,默认为75s,可以在http,server,location块。
    # 开启目录列表访问,合适下载服务器,默认关闭.
    autoindex on; # 显示目录
    autoindex_exact_size on; # 显示文件大小 默认为on,显示出文件的确切大小,单位是bytes 改为off后,显示出文件的大概大小,单位是kB或者MB或者GB
    autoindex_localtime on; # 显示文件时间 默认为off,显示的文件时间为GMT时间 改为on后,显示的文件时间为文件的服务器时间
    
    sendfile on; # 开启高效文件传输模式,sendfile指令指定nginx是否调用sendfile函数来输出文件,对于普通应用设为 on,如果用来进行下载等应用磁盘IO重负载应用,可设置为off,以平衡磁盘与网络I/O处理速度,降低系统的负载.注意:如果图片显示不正常把这个改成off.
    tcp_nopush on; # 防止网络阻塞
    tcp_nodelay on; # 防止网络阻塞
    
    # 性能优化的模块. 
    # gzip模块设置 
    gzip on; #开启gzip压缩输出
    gzip_min_length 1k; #允许压缩的页面的最小字节数,页面字节数从header偷得content-length中获取.默认是0,不管页面多大都进行压缩.建议设置成大于1k的字节数,小于1k可能会越压越大
    gzip_buffers 4 16k; #表示申请4个单位为16k的内存作为压缩结果流缓存,默认值是申请与原始数据大小相同的内存空间来存储gzip压缩结果
    gzip_http_version 1.1; #压缩版本(默认1.1,目前大部分浏览器已经支持gzip解压.前端如果是squid2.5请使用1.0)
    gzip_comp_level 2; #压缩等级.1压缩比最小,处理速度快.9压缩比最大,比较消耗cpu资源,处理速度最慢,但是因为压缩比最大,所以包最小,传输速度快
    gzip_types text/plain application/x-javascript text/css application/xml;
    #压缩类型,默认就已经包含text/html,所以下面就不用再写了,写上去也不会有问题,但是会有一个warn.
    gzip_vary on;#选项可以让前端的缓存服务器缓存经过gzip压缩的页面.例如:用squid缓存经过nginx压缩的数据
    
    #开启限制IP连接数的时候需要使用
    #limit_zone crawler $binary_remote_addr 10m;
    
    ##upstream的负载均衡,四种调度算法(下例主讲)##
    
    #虚拟主机的配置
    server
    {
        # 监听端口,如果有请求打到80端口上时,Nginx会处理该请求. 
        listen 80;
        # 域名可以有多个,用空格隔开
        server_name 127.0.0.1;
        # HTTP 自动跳转 HTTPS
        rewrite ^(.*) https://www.baidu.com;
        deny 127.0.0.1;  #拒绝的ip,表示拒绝该IP进行访问. 
        allow 172.18.5.54; #允许的ip 
        
        # 对需要指定的路径的请求解决跨越问题. 
        location /指定路径或者正则/{
            proxy_pass https://localhost:13580/指定路径或者正则/;
            proxy_set_header HOST $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
        
    }

}

在了解了Nginx配置的全局概念之后,我么主要分析下Http模块以及该模块的Server模块.

我们看下面的配置文件,我来主要说一说其主要功能,如果按照下面这样的配置的话,那么当有请求:http://mazhenxin.xyz:18088/index.html 首先,Nginx 匹配到mazhenxin.xyz 之后,将会根据后面的URI进行匹配,Nginx发现 /index.htmllocation /index.html 匹配,那么就会走这个映射规则,然后Nginx就会去服务器找 root+/location-uri这个路径上的资源文件,至于多不多/,Nginx会自动优化,因为我在root后面加不加 / 都可以匹配到。 因为我们的服务器上在路径root + location-uri 上存在着对应的文件,Nginx 在获取到改文件之后将会解析,解析之后,返回给客户端.

server {
    listen       18088;
    listen  [::]:18088;
    server_name  mazhenxin.xyz;
	
	# 下面的index不知道是啥意思.
    location /index.html {
        root   /root/nginxmapping/docker;
        # index  /index.html;
    }

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

}

💡 2.6 upstream 负载均衡详解.

  • 负载均衡算法:

    • 轮询、权重、IP散列是Nginx原生支持的分配方式
    • fail和url_hash为第三方支持的分配方式.
  • 使用.

    • 轮询是upstream默认的分配方式.

    • 权重:在server后面直接配置: server 127.0.0.1:8848 weight=1, 权重的意思就是指定轮询比例,weight和访问成正比率关系,也就是权重越大,访问的次数也越高 .

    • ip_hash 方式:每个请求按照访问ip(Nginx的前置服务器或者客户端IP),这样每个用户会固定访问一个后端服务器,可以解决session一致问题. 具体使用如下.

      upstream test {
      	ip_hash:
      	server....
      }
      

🔖 三、动手实战.

实战:Docker安装Nginx实现静态文件映射.

我这里的动手实战的架构图是这样的:

💡 3.1 安装、启动、进入容器内部.

  • 安装.
// 下面将会拉取Nginx的镜像. 
docker pull nginx 
  • 查看是否拉取成功.
# 查看所有镜像. 
docker images
  • 启动镜像.
# -p Docker虚拟Linux端口映射到母机端口上. 
# -d 该Docker容器在后台启动. 
# nginx 是启动该容器时需要的镜像.
docker run --name 容器名字 -p 18088:18088 -d nginx
  • 然后查看当前是否有容器正在运行Nginx镜像.
// docker ps 查看当前正在运行的容器. 
// docker ps -a 查看当前所有的容器. 
docker ps || docker ps -a

下面是我的运行成功截图.

  • 既然成功运行了,那么我们首先要做的就是去修改Nginx的配置文件,因为Nginx的主要功能都是通过Nginx.conf配置文件来解决的. 那么怎么去修改配置文件呢? 有两种方式,第一种就是通过启动nginx镜像的时候修改它默认去加载的配置文件,这个可以通过命令find / -name "default.conf" 去修改配置文件中的内容. 不过这种方式我不建议用,这里我建议直接去容器内部修改Nginx的配置文件,最后只需要去重启一下即可,这种方式和正常思维是一样的. 下面就来看看如何修改容器内部Nginx的配置文件.

    • 首先进入容器内部.

      docker exec -it 容器名字 bash
      
    • Nginx 默认的配置文件在容器内部 /etc/nginx/下面的。

    • 但是容器内部不支持VIM命令格式,所以我们需要使用下面的命令去增加VIM插件来使用VIM编辑器

      apt-get update
      apt-get install vim 
      

💡 3.2 修改配置文件.

  • 首先我们先修改Nginx的配置文件,因为Nginx容器的启动和安装VIM插件已经学习的差不多了,这里就直接开始修改配置文件.

    申明一点:默认的以Docker方式启动的Ngixn容器,其配置文件Nginx.conf是通过include来指向Server模块的配置文件,其在conf.d目录下. 这里我就以Nginx.conf为配置文件来举例说明.

    // 1. 首先先进入Nginx容器. 
    docker exec -it nginx bash
    // 进入/etc/nginx/下修改文件. 
    cd /etc/nginx
    // 2. 修改Nginx的配置文件如下:
    vim nginx.conf
    ------------Nginx.conf--------------
    user  root;  # 这里需要改成root,否则会出现403错误. 
    worker_processes  1;
    events {
        worker_connections  1024;
    }
    
    
    http {
        include       mime.types;
        default_type  application/octet-stream;
    
        #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
        #                  '$status $body_bytes_sent "$http_referer" '
        #                  '"$http_user_agent" "$http_x_forwarded_for"';
    
        #access_log  logs/access.log  main;
    
        sendfile        on;
        #tcp_nopush     on;
    
        #keepalive_timeout  0;
        keepalive_timeout  65;
    	// 默认负载均衡是轮询方式. 
        upstream proxy_html {
            server mazhenxin.xyz:8088 max_fails=3 fail_timeout=10s;
            server mazhenxin.xyz:8089 max_fails=3 fail_timeout=10s;
        }
    
        #gzip  on;
    
        server {
            listen       18088;
            # 通过域名访问. 
            server_name  mazhenxin.xyz;
    
            #charset koi8-r;
    
            #access_log  logs/host.access.log  main;
    		
    		# 只要URI是index.html的请求,则全部转到proxy_html上. 
    		# 转发之后的路径是 http://proxy_html/index.html
            location /index.html {
                proxy_pass http://proxy_html;
            }
    
            error_page   500 502 503 504  /50x.html;
            location = /50x.html {
                root   html;
            }
        }
    }
    ------------Nginx.conf--------------
    

    其实这样Nginx网关类似就做好了,然后只需要重新启动以下这个Nginx容器.

    # 首先退出当前容器. 
    exit. 
    # 重启容器。 
    docker restart 容器名称|容器ID. 
    

    现在最上面的Nginx网关层已经做好了,现在来配置HTML服务.

  • 修改Server HTML-8088

    这里我是通过以Nginx为基础镜像外加上一个HTML文件的形式打包成一个镜像,名字称为Linux。具体的Dockerfile如下.

    FROM nginx
    MAINTAINER "zhenxinma@tencent.com"
    COPY "./index.html" "/root/dockermapping/"
    

    然后我们可以使用docker build . 来通过当前目录下的Dockerfile来构造一个基于FROM镜像的镜像.

    然后就和上面步骤一样了,启动就OK了.

    还是同样的道理,先启动容器、进入容器、安装 vim 插件,修改配置. 上面已经有过步骤,这里就不在赘述.

    1. 首先先检查下/root/dockermapping/目录下是否有index.html要进行映射的文件. 因为最终请求是要来获取该资源的,所以说这里的资源一定要有.

    2. 然后就是修改配置文件.

      修改如下.

      # 这里是通过包含配置文件的形式来启动配置文件的. 
      # 先来看下nginx.conf配置文件. 
      # 这里的user一定要改为root,否则请求可能没有权限去访问目标资源. 
      user  root;
      worker_processes  auto;
      
      error_log  /var/log/nginx/error.log notice;
      pid        /var/run/nginx.pid;
      
      
      events {
          worker_connections  1024;
      }
      
      
      http {
          include       /etc/nginx/mime.types;
          default_type  application/octet-stream;
          log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                            '$status $body_bytes_sent "$http_referer" '
                            '"$http_user_agent" "$http_x_forwarded_for"';
          access_log  /var/log/nginx/access.log  main;
          sendfile        on;
          keepalive_timeout  65;
      	# 这里说明当前配置文件包含了哪些配置文件. 
          include /etc/nginx/conf.d/*.conf;
      }
      # 全局配置文件。 
      server {
          listen       8088;
          listen  [::]:8088;
          server_name  mazhenxin.xyz;
          location /index.html {
              root   /root/dockermapping;
          }
          error_page   500 502 503 504  /50x.html;
          location = /50x.html {
              root   /usr/share/nginx/html;
          }
      }
      

      当有请求从18088Nginx服务过来之后,其会根据URI来取访问目标资源.

  • 修改Server HTML-8089 配置文件.

    同理,依然利用Nginx为基础镜像,将HTML打包成一个镜像. 具体和上面类似,这里就不在啰嗦了直接上修改好的配置文件即可.

    1. 我们先看下index.html文件是否存在.
    # 下面的命令是在进入容器之后执行的. 
    root@a217d3dd7e75:/# cd /root/dockermapping/
    root@a217d3dd7e75:~/dockermapping# ls
    index.html
    root@a217d3dd7e75:~/dockermapping# cat index.html 
    <b>
    Hello Wrod Docker Nginx Mapping to Html.-8089
     </b>
    root@a217d3dd7e75:~/dockermapping# 
    

    通过上面可以看到,index.html是存在的,且页面内容是8089的.

    1. 修改Nginx的配置文件.
    root@a217d3dd7e75:/etc/nginx/conf.d# cat default.conf 
    server {
        listen       8089;
        listen  [::]:8089;
        # 配置以域名的形式访问. 
        server_name  mazhenxin.xyz;
        location / {
            root   /root/dockermapping;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /usr/share/nginx/html;
        }
    }
    

    重新启动加载配置文件,这里一定要将修改过配置文件的容器重新启动。

来看最后结果:

第一次:

第二次:

OK,大功告成!

欢迎关注下我的公众号(同掘金):小马教你写Bug 一起学习 互相成长!

以上是关于一篇文章带你入门Docker + Nginx.的主要内容,如果未能解决你的问题,请参考以下文章

一篇文章带你吃透 Docker 原理

一篇文章带你吃透 Docker 原理

「Docker入门指北」容器很难理解?带你从头到尾捋一遍

如何做好容器化管理?腾讯架构师一篇文章带你吃透 Docker 原理

技术解析+代码实战,带你入门华为云政务区块链平台

一文带你入门Docker容器服务 #yyds干货盘点#