docker部署nginx反向代理多个web应用

正向代理和反向代理

正向代理 是client的代理,它隐藏了client。
反向代理 是server的代理,它隐藏了server。

正向代理

正向代理 与我们通常理解的代理(proxy)含义一致,例如某幕后老板为了隐藏自己的身份找了一个工具人替他办事,大家都以为这个工具人才是老板,却全然不知幕后大佬的存在。另一个经典的例子是2018年张艺谋的电影《影》,影片中替身境州就是沛国大都督子虞的工具人,或者叫傀儡,文雅一点叫 代理

在互联网中,代理最早是用来帮助内网客户端访问外网服务器的,例如FQ。所谓的“代理”就是一个中间服务器,由于客户端不能直接访问目标服务器,于是客户端将请求发送给中间服务器,由中间服务器向目标服务器发起请求,并将请求到的数据返回给客户端。在这个过程中,目标服务器并不知道客户端姓甚名谁,因为它收到的只是中间服务器的请求。此时,客户端和代理服务器是一个整体,客户端对目标服务器是隐藏的。

正向代理 代理的是客户端,客户端相对于服务器来说是不可见的,客户端通过代理完成一系列请求。

反向代理

反向代理 与正想代理刚好相反:

上面这张图很好的解释了什么是反向代理:我们想吃外卖却又不知道哪一家店有卖的,我们可以在外卖平台上请求我们想吃的种类例如热干面,外卖平台按照它聚合的商家内容为我们自动筛选并展示可以下单的商家,我们不必知道商家的具体位置(这不代表我们不能获取),我们也不用亲自跑到店里去买饭。相反的,商家或者外卖小哥必须知道我们地址,不然外卖往哪里送呢?

在上面这个情景中,我们相当于client,平台相当于proxy,商家相当于server。我们不必知道商家的位置也不用和商家直接联系,只需要向平台发出请求,平台按照我们的需要自动匹配符合条件的商家并帮助我们下单。

在互联网中,反向代理服务器也起到了类似的作用:它对用户隐藏了服务真正所在的服务器地址,而是通过反向代理服务器来处理用户的请求。代理服务器接收到用户的请求后,按照预先定义的规则访问不同的服务,并将请求的结果转发给用户。通过定义不同的规则,代理也可以区分不同的请求并且访问不同的web服务。

反向代理能够将真正的web服务放置于内网服务器中,保证内网服务器的安全,有效组织web攻击。同时,反向代理服务器能够优化网站的负载。

总之,反向代理 代理的是服务端,服务端相对于客户端来说是不可见的,服务端任何时候都不能直接请求。客户端只能请求代理服务器。

以上图片来自于 https://www.cnblogs.com/taostaryu/p/10547132.html

Nginx

关于 Nginx:8分钟带你深入浅出搞懂Nginx

Nginx 是一款用于反向代理的 web 应用,由于其内存占用少、启动速度快、高并发能力强,在互联网项目中被广泛应用。

反向代理多个web应用

Nginx 功能强大,这里用于代理部署在服务器上的多个web应用,通过不同的域名访问不同的web应用。

这里需要两个前提:

  1. 已经实现内网穿透的公网服务器
  2. 大陆的公网服务器的话域名需要备案

大陆公网服务器需要对备案域名,这是个很恼火的事情,如果不备案的话,估计能用几天,然后就被封掉,sad~

因为我已经用 frp 将内网服务器的 web 应用转发到了公网服务器的不同端口。如果能够配置 nginx 反向代理,可以选择 http 协议,否则尝试使用 tcp 协议也是可以访问的。

因为设置了端口转发,nginx 反向代理应该部署在公网服务器上。

初始化nginx容器

拉取镜像资源:

$ docker pull nginx

设置挂载目录:

$ export NGINX=~/dockerv/nginx
$ mkdir -p $NGINX

启动一个容器获取配置文件:

$ docker run -d --name nginx -p 80:80 nginx
$ docker cp nginx:/etc/nginx/nginx.conf $NGINX/

移除容器:

$ docker rm -f nginx

挂载并初始化容器:

$ docker run -d --name nginx -p 80:80 \
-v $NGINX/html:/usr/share/nginx/html \
-v $NGINX/log:/var/log/nginx \
-v $NGINX/nginx.conf:/etc/nginx/nginx.conf \
nginx

这里需要让nginx容器的80端口代理宿主机的80端口(http服务),这样我们对宿主机80端口的请求会被自动转发给nginx服务。

配置nginx

配置nginx使它能通过不同的域名识别不同的web服务,nginx将不同请求转发到宿主机的不同端口,然后frp将请求再次转发到内网服务器上的不同web应用。

注意:在此之前,应该在域名控制台将待使用的域名或者二级域名解析到公网服务器的IP。

在nginx.conf文件中添加以下内容:

server {
    listen 80;
    server_name xxx.top *.xxx.top;
    location / {
        proxy_pass http://49.232.231.46:10080;
        proxy_redirect http://$host/ http://$http_host/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

需要注意的几个地方:

listen 80;

容器内nginx服务监听的端口,默认即可。在启动容器是它被绑定到了宿主机的80端口。

server_name xxx.top *.xxx.top;

需要转发给nginx处理的域名。当用户请求指定域名时,公网服务器会将请求交给nginx处理。

proxy_pass http://49.234.232.46:10080;

frps设置了宿主机的10080端口为内网服务器的代理http端口,这里nginx将指定域名的请求转发给宿主机的10080端口,再由frp转发给内网服务器的frpc进行处理。

因为这里nginx容器是用的是bridge网络模式,IP地址需要写宿主机的公网IP地址,否则nginx找不到宿主机的地址。如果是直接在宿主机上部署或者使用host网络模式部署的nginx容器,可以直接写127.0.0.1或者localhost。

重启nginx服务

$ docker restart nginx

其它

因为反向代理时将指定域名集合一股脑的转发给了内网服务器,frpc并不知道将哪个域名交给哪个web服务处理。所以frpc还需要配置web应用的转发信息。下面是frpc.ini的部分转发配置:

[omv]
type = http
local_ip = 127.0.0.1
local_port = 80
custom_domains = omv.xxx.top

[halo]
type = http
local_ip = 127.0.0.1
local_port = 8090
custom_domains = blog.xxx.top

[emby]
[jellyfin]
type = http
local_ip = 127.0.0.1
local_port = 8096
custom_domains = emby.xxx.top

[qbittorrent]
type = http
local_ip = 127.0.0.1
local_port = 6996
custom_domains = qb.xxx.top

[tinyMediaManager]
type = http
local_ip = 127.0.0.1
local_port = 9800
custom_domains = tmm.xxx.top

[filebrowser]
type = http
local_ip = 127.0.0.1
local_port = 8888
custom_domains = file.xxx.top
posted @ 2020-12-18 09:11  barwe  阅读(3909)  评论(0编辑  收藏  举报