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

Docker中Nginx反向代理访问静态站点错误加载Appwrite服务

问题成因

两个核心配置错误导致请求被错误转发到Appwrite服务:

  • Nginx默认虚拟主机匹配逻辑问题:Nginx对同一监听端口的请求,会优先匹配server_name和请求Host头一致的server块;如果没有匹配项,会直接把请求发给该端口下第一个定义的server块作为默认响应。你的配置中第一个server块(Appwrite反代配置)同时监听了80、443端口,而两个静态站点的server块仅配置了80端口监听:
    • 所有HTTPS协议(443端口)访问domain1.com、domain2.com的请求,没有对应匹配的server块,直接命中默认的Appwrite反代逻辑
    • 如果请求带了www前缀、或者Host头和配置的server_name不完全匹配,80端口的请求也会落到默认的反代块返回Appwrite内容
  • Docker卷挂载路径错误:Compose配置里把本地./domain1.com、./domain2.com两个目录都直接挂载到容器内/var/www路径,后挂载的目录会覆盖前一个,且容器内根本不存在Nginx配置中写的/var/www/domain1.com、/var/www/domain2.com路径,就算请求命中静态站点的server块,也会因为找不到静态文件触发错误,进一步兜底到反代逻辑。
修复步骤
  • 修正Compose文件的卷挂载配置,把静态目录挂载到和Nginx配置对应的子路径,修改后nginx服务的volumes段如下:
volumes:
  - ./config:/etc/nginx
  - appwrite-certificates:/etc/ssl/private
  - ./domain2.com:/var/www/domain2.com
  - ./domain1.com:/var/www/domain1.com
  • 调整Nginx配置,修正默认主机规则、补全匹配逻辑:

    1. 移除废弃的ssl on;写法,改用listen 443 ssl;的标准配置,同时移除不安全的TLSv1、TLSv1.1协议支持
    2. 显式添加80、443端口的默认兜底server块,把未匹配到对应域名的请求直接返回404/444,避免落到Appwrite反代块
    3. 为两个静态站点补全常见域名别名(比如www前缀),避免Host不匹配导致的错误转发

    参考修改后的完整Nginx配置:

events {
    worker_connections 1024;
}

http {
    # 443端口兜底,非api域名的HTTPS请求直接断开连接
    server {
        listen 443 ssl default_server;
        ssl_certificate           /etc/ssl/private/api.domain.com/cert.pem;
        ssl_certificate_key       /etc/ssl/private/api.domain.com/privkey.pem;
        return 444;
    }

    # Appwrite反代配置
    server {
        listen 80;
        listen 443 ssl;
        ssl_certificate           /etc/ssl/private/api.domain.com/cert.pem;
        ssl_certificate_key       /etc/ssl/private/api.domain.com/privkey.pem;
        ssl_session_cache  builtin:1000  shared:SSL:10m;
        ssl_protocols  TLSv1.2 TLSv1.3;
        ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
        ssl_prefer_server_ciphers on;
        server_name api.domain.com;

        location / {
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_set_header Host $host;
            proxy_set_header X-Forwarded-Host $host;
            proxy_set_header X-Forwarded-Port $server_port;
            proxy_pass http://appwrite;
        }

        location /v1/realtime {
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_set_header Host $host;
            proxy_set_header X-Forwarded-Host $host;
            proxy_set_header X-Forwarded-Port $server_port;
            proxy_pass http://appwrite-realtime;
            proxy_http_version 1.1;
            proxy_connect_timeout 7d;
            proxy_send_timeout 7d;
            proxy_read_timeout 7d;
        }
    }

    # 80端口兜底,未匹配域名直接返回404
    server {
        listen 80 default_server;
        return 404;
    }

    server {
        listen 80;
        root /var/www/domain1.com;
        server_name domain1.com www.domain1.com;
        index index.html index.htm index.nginx-debian.html;
        location / {
            try_files $uri $uri/ =404;
        }
    }

    server {
        listen 80;
        root /var/www/domain2.com;
        server_name domain2.com www.domain2.com;
        index index.html index.htm index.nginx-debian.html;
        location / {
            try_files $uri $uri/ =404;
        }
    }
}
  • 重载配置生效,在Compose文件所在目录执行以下命令:
docker compose up -d
docker compose exec nginx nginx -t
docker compose exec nginx nginx -s reload

执行nginx -t是为了提前校验配置语法有没有错误,避免重载失败导致Nginx挂掉。如果后续需要给两个静态站点开启HTTPS,只需要给对应的server块添加443 ssl监听、配置对应证书路径即可。

内容的提问来源于stack exchange,提问作者StreY

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 10:12:20