Nginx反向代理到多个Docker 笔记!

前言

现在我有一台CentOS8.2 外网IP地址是 119.28.135.102 的测试服务器。

我希望在里面运行3个Docker容器,分别用来运行vue编写的网站前端页面,网站后台静态页面和.NET 5 WebAPI。

当用户访问 http://119.28.135.102 可以打开网站前端页面,当用户访问 http://119.28.135.102/admin 可以打开网站后台页面。

前后端页面都调用 WebApi http://119.28.135.102:8280 获取数据。

思考了一番后大致流程如下图所示,用户请求Centos服务器上的Nginx服务器,然后该Nginx服务器通过对用户请求的路径进行匹配并反向代理到不同的Docker中。

当匹配到用户请求URL是 / 时,反向代理到Docker容器1,当请求URL为 /admin 时,反向代理到 Docker容器2 ,当请求URL端口为8082时,反向代理到 Docker容器3.

Docker容器1和Docker容器2里面也需要安装nginx,作为前端和后台页面的web服务器。Docker容器3需要安装.NET5运行时,用来运行WebApi。

 

 

 

 

操作开始前首先确保系统已经正确安装了Docker,参考链接:https://www.cnblogs.com/fuhua/p/15043177.html#%E5%AE%89%E8%A3%85Docker

 

 

一、制作网站前端页面的Docker镜像

 

pc文件夹目录结构

 

dist文件夹里就是vue项目build之后的静态页面。

 

 

Dockerfile内容:

# Base Image设置基础镜像
FROM nginx
 
# 将dist目录复制到 Docker容器中的/usr/share/nginx/html/目录下
COPY dist/  /usr/share/nginx/html/

# 将nginx.conf文件复制到/etc/nginx/nginx.conf
COPY nginx.conf /etc/nginx/nginx.conf

 

nginx.conf内容:

user  nginx;
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;

    #注意这句话一定要注释掉,否则vue history路由会导致刷新的时候提示404页面找不到
    #include /etc/nginx/conf.d/*.conf;

   server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;
        access_log  /var/log/nginx/host.access.log ;
        error_log  /var/log/nginx/error.log;

        location / {
           root /usr/share/nginx/html; #配置Vue项目根路径,与
           index index.html index.html; #配置首页
           #vue history模式专用
           try_files $uri $uri/ /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;
        }
 }
}

 

 

接下来用 FileZilla Client 远程连接到服务器

 

连接成功后把pc目录拷贝到 /home 目录下,然后进入到/home/pc目录,执行命令 【docker build -t pc .】构建PC前端页面的docker镜像。

 

镜像构建完成后

【docker images】:查看镜像

【docker run -d -p 127.0.0.1:3000:80  -v /home/pc/nginx_log:/var/log/nginx  pc】:启动一个容器

-d:后台运行

-p 127.0.0.1:3000:80  以内网方式运行,并且把宿主机的3000端口映射到容器的80端口上

-v /home/pc/nginx_log:/var/log/nginx:将宿主机的/home/pc/nginx_log路径映射到容器的/var/log/nginx,因为docker不保存数据,所以日志文件需要挂载到本机存储。

pc:镜像名

【curl http://127.0.0.1:3000】:测试网页是否能访问,可以看到,页面已经能返回正确数据了。

 

二、制作网站后台页面的Docker镜像

 

后台镜像的制作和前端镜像制作流程是一样的,最重要的区别就是vue项目编译之前必须设置为相对路径,否则会出现CSS和js等资源文件找不到。

设置相对路径的方法是给项目根目录增加 vue.config.js 文件。并设置  publicPath的值为 './' 。

 

我们来看看设置相对路径之前和之后的代码有什么区别:

设置相对路径之前:

我们可以看到,样式文件默认是从网站根目录下去加载,也就是http://119.28.135.102/css/xxxx,而后台页面实际目录应该是在 http://119.28.135.102/admin/,所以需要修改成相对路径。

 

设置了相对路径:

 

 

将admin文件夹上传到服务器 /home目录下,Dockerfile和nginx.conf内容和前端页面的一样。

     

 

 

进入到服务器的 /home/admin输入命令【docker build -t admin .】

 

制作完成镜像后输入命令 【docker run -d -p 127.0.0.1:4000:80  -v /home/admin/nginx_log:/var/log/nginx -t admin】启动一个容器。

此时docker ps可以看到有两个正在运行的容器,并且输入命令【curl http://127.0.0.1:4000】可以正确返回网页数据。

 

 

三、制作WebApi的Docker镜像。

 WebApi发布在名字叫webapi的文件夹里,webapi文件目录如下:

 

Dockerfile内容如下:

#基于 microsoft/dotnet:5.0.0-core 来构建我们的镜像
FROM mcr.microsoft.com/dotnet/sdk:5.0

#创建项目在docker容器内的工作目录,容器启动时执行的命令会在该目录下执行
#WORKDIR 命令为后续的RUN、CMD、COPY、ADD等命令配置工作目录。设置后,接下来的COPY和ADD命令中的相对路径就是相对于WORKDIR指定的路径
WORKDIR /app
#EXPOSE 是声明运行时容器提供服务端口,将在docker run -p <宿主端口>:<容器端口>时用到
EXPOSE 5000
#点并不是指本机目录下的文件,而是 docker引擎中展开的构建上下文中的文件
#即当前执行docker build构建时的所在目录,即在目录testah目录
#将当前上文下的文件复制到容器内的当前目录下
COPY . .
#使用dotnet webapi.dll来运行应用程序
CMD ["dotnet", "CollectionTools.Web.Entry.dll"]

 

把webapi文件夹上传到 /home 路径下

 

进入 /home/webapi 目录 执行命令【docker build -t webapi .】构建完成镜像

再执行【docker run -d -p 127.0.0.1:8080:5000  -t webapi】运行容器。

可以通过命令【docker logs 容器id】查看容器shell数据

 

执行【curl http://127.0.0.1:8080/api/system/system/list】可以看到接口调用成功返回了数据。

 

四、配置宿主机的nginx 

1.执行命令【yum -y install gcc-c++ pcre pcre-devel zlib zlib-devel openssl openssl-devel】安装nginx编译需要的工具

 

2.到http://nginx.org/en/download.html nginx的官网找到稳定版本nginx-1.20.1,并复制其链接。【cd /home】到home目录下执行 【wget -c http://nginx.org/download/nginx-1.20.1.tar.gz】下载安装包。

 

 

执行命令【tar -zxvf nginx-1.20.1.tar.gz】解压安装包

 

执行【cd nginx-1.20.1/】进入到文件夹后,执行命令【./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-http_v2_module --with-http_sub_module --with-http_gzip_static_module --with-pcre】配置模块

#--prefix 指定安装路径

#--with-http_stub_status_module    允许查看nginx状态的模块

# --with-http_ssl_module     支持https的模块

 

 

 执行【make && make install】进行安装。安装完成后,在可以看到 /usr/local/nginx 这个目录。

 

 

下面将nginx配置到环境变量

执行【vim /etc/profile】编辑文件

在最后一行添加,然后:wq保存文件

PATH=$PATH:/usr/local/nginx/sbin

export PATH

 

 

然后执行【source /etc/profile】让设置立即生效。

输入【nginx -v】即可看到nginx的版本。至此Nginx已经安装完成。

 

 

下面开始配置Nginx反向代理,分别代理到不同的Docker

修改 /usr/local/nginx/conf/nginx.conf 的内容:

worker_processes  1;

events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;

    keepalive_timeout  65;


    server {
        listen       80;
        server_name  119.28.135.102;

       location / {
              proxy_pass         http://127.0.0.1:3000; 
        }

      location /admin/ {
               proxy_pass          http://127.0.0.1:4000/; 
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }


   server {
        listen       8082;
        server_name  119.28.135.102;

       location / {
              proxy_pass         http://127.0.0.1:8080; 
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }

}

 

 

之后执行 【nginx -s reload】重新加载nginx的配置。此时有可能会报错,nginx: [error] open() "/usr/local/nginx/logs/nginx.pid" failed (2: No such file or directory),参考链接:https://blog.csdn.net/weixin_44352609/article/details/93242894

 

当reload执行完成后,发布就算完成了,此时从外网已经能正常访问了。

 

 

 

 

总结:

nginx反向代理到多个docker容器最重要的是一定要处理好路径,前端要写成相对路径。以及nginx的斜杠问题一定要特别注意。

 

posted @ 2021-07-27 12:12  凉游浅笔深画眉  阅读(2634)  评论(2编辑  收藏  举报