如何将 Nginx 反向代理到本地托管(在具有 ssh 访问权限的服务器上)docker-compose

Posted

技术标签:

【中文标题】如何将 Nginx 反向代理到本地托管(在具有 ssh 访问权限的服务器上)docker-compose【英文标题】:How to Nginx reverse Proxy to a locally hosted (on a server with ssh access) docker-compose 【发布时间】:2022-01-19 00:12:07 【问题描述】:

我不能完全确定如何在这种状态下让它工作,并且我喜欢如果可能的话,不必以不同的方式重做所有事情。

我有一个运行 nginx 服务器的数字海洋水滴以及一个 docker-compose,其中运行着客户端、服务器和数据库映像。

我的设想是通过 NGINX 保护流量并将其路由到服务器,该 NGINX 将代理到从 compose 公开的客户端应用程序。

so (internet) -> DNS(NGINX) -> 客户端 -> 服务器 -> DB

现在,当连接到 docker 中公开的 ip:port 时,这可以正常工作,因为我在 droplet 上使用 uwp 打开了它,很好的是它的 http 而不是 https。

我可以从 NGINX 代理到 ip:port,这很好,据我了解,这是从互联网到 nginx,再到互联网,再到客户端应用程序,但它可以工作。

现在我保护并设置了一个 DNS 并通过 NGINX 路由它,并收到“无效的主机标头”响应。

它是一个有角度的应用程序,所以我可以禁用主机头检查,它可能会很时髦,但我的下一步是关闭我暴露的端口,以便所有流量都必须通过 NGINX 代理,但我认为甚至代理也在使用 droplet 上的暴露端口来路由流量。

问:

我可以将来自 NGINX 的流量路由到服务器中的 docker-compose 地址,而不是使用服务器 ip 和端口组合来访问客户端站点,以便我可以关闭我暴露的端口吗?

或者,我是否只需要在 compose 中运行 NGINX 容器,以便我可以使用 compose 网络来管理流量?我不喜欢这样,因为我将不得不改变服务器上的东西,而且它对我来说有点脆弱。

TLDR:

工作 Internet -> http://ip:port(NGINX) -> http://ip:port docker-compose(客户端端口)== App Served! Internet -> http://ip:port docker-compose(客户端端口)== App Served 不工作 Internet -> https://DNS:port:80/443(NGINX) -> http://ip:port docker-compose (client port) == "Invalid Host Header" 想工作 Internet -> https://DNS:port:80/443(NGINX) -> 本地 compose not over http == App Served

sites-enabled # 这是我手动配置最多的地方 这个 conf 和许多其他 nginx 文件都在 etc/nginx 中

server 

  listen 80;
  server_name <dns>.net;

  index index.html index.htm index.nginx-debian.html;
  location / 
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Host $host;
    proxy_set_header Connection 'upgrade';
    proxy_http_version 1.1;
    proxy_cache_bypass $http_upgrade;
    proxy_pass http://<ip>:<port>;
  
  
  listen 443 ssl;
  ssl_certificate <server filepath>;
  ssl_certificate_key <filepath>;
  include <letsencrypt nginx conf path>;
  ssl_dhparam <letsencrypt pem path>;



server 
  if ($host = <dns>.net) 
    return 301 https://$host$request_uri;
  
    listen 80;
    server_name <dns>.net;
    listen 443 ssl default_server;
    server_name _;
  return 404; 
  

码头工人撰写

networks:
  client:
  server:

services:
  client:
    container_name: clientName
    image: "repoImage"
    ports: 
       - 1:1
    environment:
       - VIRTUAL_HOST=SERVERIPADDRESS
       - LETSENCRYPT_HOST=SERVERIPADDRESS
    networks:
       - client
    restart: always
 
  server:
    container_name: serverName
    networks:
      - client
      - server
    image: "repoImage"
    command npm run startProd
    ports:
      - 2:2
    restart: always
    env_file:
      - <envfilepath>
  
  database:
    container_name: dbInstance
    networks:
      - server
    restart: always
    image: dbimage
    ports:
      - 3:3
      - 4:4
    volumes:
      - many
    environment
      - envVars
    

【问题讨论】:

你能发布你的 compose 文件和 NGINX conf 吗? @MrDiggles 感谢您的回复 文件已添加,请告诉我是否需要添加任何其他内容以使其更清晰 【参考方案1】:

如果您对整个系统使用docker-compose,它往往会简化事情,特别是如果它们都在同一台机器上运行。这样,您就可以利用 Docker 的网络并最大限度地减少需要公开的端口数量。

例如,你可以这样设置

NGINX 是“前门”,根据主机名或路径将流量引导至 clientserver 服务通过服务名+端口相互引用

docker-compose.yml

networks:
  db-net:
  proxy-net:

services:
  nginx:
    networks:
      proxy-net:
    ports:
      # These are the only ports that will be open on your machine
      - 80:80
      - 443:443

  database:
    networks:
      db-net:
    # no ports exposed
    command: <run on port 3306>

  server:
    networks:
      db-net:
      proxy-net:
    # no ports exposed
    command: <run on port 3000>
    environment:
      - DATABASE_URL=database:3306

  client:
    networks:
      proxy-net:
    # no ports exposed
    command: <run on port 3000>

nginx.conf

server 
  ...
  location /client 
    ...
    proxy_pass http://client:3000;
  
  ...
  location /server 
    ...
    proxy_pass http://server:3000;
  
  ...

如果您有任何问题或我误解了您的问题,请告诉我。

【讨论】:

这绝对是理想的状态,也是我想要的状态!但是,当在 docker-compose 中使用时,让letsencrypt 和 certbot 运行并没有提供太多的教程方式。如果我不需要在 https 上运行,我现在会这样做,但是因为它可以更容易地在服务器上运行 NGINX 并连接加密服务,因为我可以访问代码。我确实认为我可能拥有它,在代理通行证中我可以只定位本地主机,如果我没有弄错这个路由直接到服务而不希望通过网络

以上是关于如何将 Nginx 反向代理到本地托管(在具有 ssh 访问权限的服务器上)docker-compose的主要内容,如果未能解决你的问题,请参考以下文章

Nginx 反向代理重定向到帐户/登录

用Nginx做端口转发(反向代理)

用Nginx做端口转发(反向代理)

如何强制更新/防止在 Linux 上运行并由 nginx 反向代理服务器托管的 .NET Core Web 应用程序的 HTML 缓存

nginx:nginx反向代理在服务器上工作,但在本地主机上不工作

设置好 NGINX 反向代理后,如何在引入 NGINX 反向代理的 NGINX 上配置 SSL 直通? [复制]