You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Nginx跨服务器子域名配置异常:vscode.domain.tld请求被跳转到hub.domain.tld问题排查

Nginx跨服务器子域名配置异常:vscode.domain.tld请求被跳转到hub.domain.tld问题排查

嘿,我来帮你捋清楚这个问题——你遇到的其实是跨服务器反向代理里很常见的「请求路由错位」问题,咱们一步步拆解原因和解决方案:

问题根源分析

首先得明确一个关键事实:你的公网DNS和端口转发规则都是指向第一台服务器(192.168.1.216)的。这意味着,不管用户访问的是hub.domain.tld还是vscode.domain.tld,所有发往80/443端口的请求都会先落到第一台服务器的Nginx上,根本没机会到达第二台服务器的Nginx。

而第一台服务器的Nginx里应该有默认的跳转规则(比如默认server块会把未匹配的请求跳转到hub.domain.tld),所以当你访问vscode.domain.tld时,第一台服务器的Nginx找不到对应的配置,就触发了默认跳转——这就是为什么把vscode的配置移到第一台服务器就正常,因为此时它能正确识别这个子域名的请求了。

解决方案(结合你容器化拆分的需求)

根据你想拆分配置、容器化code-server/questdb/grafana的目标,有两个靠谱的方案可选:

方案1:让第二台服务器直接接收公网请求(独立路由)

如果想让第二台服务器单独负责vscode.domain.tld的请求,需要调整网络层面的配置:

  • 要么给第二台服务器分配独立的公网IP,然后把vscode.domain.tld的DNS记录指向这个新IP;
  • 要么在你的路由器/防火墙里,针对vscode.domain.tld的80/443请求单独设置端口转发,把流量导到第二台服务器的内网IP(192.168.1.234);
  • 确保第二台服务器的Nginx配置(就是你现在贴的那段)没有问题,且内网防火墙允许公网转发过来的流量。

方案2:以第一台服务器为统一入口,转发请求到第二台(更适合容器化集群)

这个方案更符合你拆分配置、容器化服务的长期规划——把第一台服务器作为公网反向代理入口,统一处理所有子域名的SSL和路由,第二台服务器专注于容器化服务的内部代理:

步骤1:在第一台服务器的Nginx中添加vscode.domain.tld的路由配置

把原来在第二台服务器的vscode配置迁移到第一台,调整proxy_pass指向第二台服务器的code-server(或者第二台的Nginx):

# top-level http config for websocket headers(和你原来的一致,保留在第一台的主配置里)
map $http_upgrade $connection_upgrade {
  default upgrade;
  ''      close;
}

# HTTP服务器:跳转到HTTPS
server {
  listen 80;
  server_name vscode.domain.tld;
  return 302 https://$host$request_uri;
}

# HTTPS服务器:处理vscode请求,转发到第二台服务器
server {
  listen 443 ssl;
  server_name vscode.domain.tld;

  ssl_certificate /etc/letsencrypt/live/vscode.domain.tld/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/vscode.domain.tld/privkey.pem;
  # 以下SSL配置和你原来的完全一致,直接复制即可
  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  ssl_prefer_server_ciphers on;
  ssl_dhparam /etc/ssl/certs/dhparam.pem;
  ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
  ssl_session_timeout 1d;
  ssl_session_cache shared:SSL:50m;
  ssl_stapling on;
  ssl_stapling_verify on;
  add_header Strict-Transport-Security max-age=15768000;

  # 转发请求到第二台服务器的code-server
  location / {
    proxy_pass http://192.168.1.234:8080;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    # websocket相关配置
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $connection_upgrade;
    proxy_set_header X-Scheme $scheme;
    proxy_buffering off;
  }

  # Let's Encrypt验证路径
  location ~ /.well-known {
    allow all;
  }
}

步骤2:第二台服务器的Nginx专注于容器化服务的内部代理

把第二台的Nginx配置简化,只负责转发容器内的code-server、questdb、grafana请求(可以用Docker Compose把这些服务和Nginx容器放在同一个网络里):

server {
  listen 80;
  server_name localhost;

  # 转发code-server请求(如果直接让第一台连code-server,这部分可以省略)
  location / {
    proxy_pass http://code-server:8080;
    # 对应websocket配置和你原来的一致
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $connection_upgrade;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  }

  # 转发questdb请求
  location /questdb/ {
    proxy_pass http://questdb:9000/;
    proxy_set_header Host $host;
  }

  # 转发grafana请求
  location /grafana/ {
    proxy_pass http://grafana:3000/;
    proxy_set_header Host $host;
  }
}

步骤3:Docker Compose配置参考

在第二台服务器上编写docker-compose.yml,把所有服务放在同一个网络,让Nginx能直接访问:

version: '3.8'

services:
  nginx:
    image: nginx:alpine
    ports:
      - "8080:80" # 或者映射到你需要的端口
    volumes:
      - ./nginx.conf:/etc/nginx/conf.d/default.conf
    networks:
      - app-network

  code-server:
    image: codercom/code-server:latest
    volumes:
      - ./code-server-config:/home/coder/.config/code-server
    networks:
      - app-network

  questdb:
    image: questdb/questdb:latest
    volumes:
      - ./questdb-data:/root/.questdb
    networks:
      - app-network

  grafana:
    image: grafana/grafana:latest
    volumes:
      - ./grafana-data:/var/lib/grafana
    networks:
      - app-network

networks:
  app-network:
    driver: bridge

额外注意事项

  • 确保第一台和第二台服务器之间的内网网络连通,没有防火墙阻挡对应端口(比如8080、80等);
  • Let's Encrypt证书建议统一在第一台服务器申请,这样所有子域名的SSL都由入口代理处理,更易维护;
  • 如果选择方案2,第一台服务器的Nginx可以继续保留hub.domain.tld的配置,实现多子域名的统一路由。

备注:内容来源于stack exchange,提问作者Bouarfa Mahi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.22 10:08:08