EC2私有子网Django-NGINX无法通过AWS ALB访问的问题求助
看起来你遇到了典型的负载均衡到后端服务的连通性问题,504(网关超时)和502(坏网关)分别指向不同的故障点,咱们一步步拆解排查:
首先明确错误对应的故障方向
- 504网关超时:ALB无法从后端EC2实例获得响应(大概率是ALB到EC2的网络不通,或者EC2上的服务根本没在处理请求)
- 502坏网关:Nginx已经收到了ALB的请求,但无法连接到后端的Django服务(比如socket权限问题、Django没运行、Nginx配置错误)
第一步:先确认Django服务与Unix Socket的状态
这是502错误的核心排查点:
检查Django的WSGI服务器(比如Gunicorn)是否在运行:
ps aux | grep gunicorn要确保进程存在,且启动命令中明确指定了监听
/home/ubuntu/Desktop/star/star.sock。检查Socket文件的权限:
ls -l /home/ubuntu/Desktop/star/star.sockNginx默认以
www-data用户运行,这个用户必须对socket文件有读写权限。如果权限不对,可以:- 调整Gunicorn的启动参数,添加
--umask 007让socket自动开放组权限 - 手动修改权限:
sudo chown www-data:www-data /home/ubuntu/Desktop/star/star.sock
- 调整Gunicorn的启动参数,添加
测试Nginx用户能否连接到Socket:
sudo -u www-data curl --unix-socket /home/ubuntu/Desktop/star/star.sock http://localhost如果能返回Django的页面内容,说明Socket连通正常;如果报错,直接定位到Django服务的问题。
第二步:修复Nginx配置中的明显错误
你的配置里有几个致命问题,直接导致了502和配置冲突:
1. 缺失HTSSL证书配置(443端口必备)
443端口必须启用SSL并指定证书,否则Nginx无法处理HTTPS请求,ALB转发过来的HTTPS流量会直接失败返回502。
2. 重复的Server块冲突
第二个Server块重复监听443端口,并且逻辑冗余,会导致Nginx启动异常或请求匹配混乱。
3. 静态文件路径错误
当前/static/的root指向/home/ubuntu/Desktop/star/dashboard/static/,这会导致访问/static/css/style.css时,Nginx去查找/home/ubuntu/Desktop/star/dashboard/static/static/css/style.css,明显路径错误。
4. Proxy_pass直接写Socket路径不够规范
修改后的参考配置:
upstream my_server { server unix:/home/ubuntu/Desktop/star/star.sock fail_timeout=0; } # 处理HTTP请求,重定向到HTTPS server { listen 80; server_name _; # 匹配所有请求,也可以写ALB的访问域名/EC2内网IP return 301 https://$host$request_uri; } # 处理HTTPS请求 server { listen 443 ssl; server_name _; # 替换成你的SSL证书路径(AWS ACM证书需要导出到EC2,或用certbot生成) ssl_certificate /path/to/your/certificate.pem; ssl_certificate_key /path/to/your/private-key.pem; client_max_body_size 4G; access_log /home/ubuntu/Desktop/star/logs/nginx-access.log; error_log /home/ubuntu/Desktop/star/logs/nginx-error.log; # 修复静态文件路径:root指向dashboard目录,/static/会自动映射到static子目录 location /static/ { root /home/ubuntu/Desktop/star/dashboard/; expires 30d; add_header Cache-Control "public, immutable"; } location / { proxy_hide_header X-Frame-Options; include proxy_params; proxy_pass http://my_server; # 使用upstream别名,更易维护 # 补充必要的代理头部,确保Django能正确获取客户端信息 proxy_set_header Host $host; 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; } error_page 500 502 503 504 /500.html; location = /500.html { root /home/ubuntu/Desktop/star/dashboard/static/; } # 原有的css/js location可以合并到/static/,无需单独配置 }
修改后验证配置合法性并重启Nginx:
sudo nginx -t sudo systemctl restart nginx
第三步:检查ALB与网络配置(解决504超时)
目标组健康检查:
- 确保目标组的健康检查路径是Django能正常响应的地址(比如
/或专门的/health接口) - 检查目标组的状态:如果EC2实例显示
不健康,ALB会停止转发流量,直接返回504。
- 确保目标组的健康检查路径是Django能正常响应的地址(比如
安全组配置:
- EC2的安全组必须允许来自ALB安全组的对应端口流量(80或443)
- ALB的安全组必须允许客户端的HTTP/HTTPS流量(通常是0.0.0.0/0)
私有子网路由:
- 确保私有子网的路由表允许与ALB所在的公有子网通信(内网流量无需NAT网关,只要路由表指向VPC内部即可)
第四步:通过日志定位剩余问题
如果上面的步骤没解决问题,查看日志找细节:
- Nginx错误日志:
tail -f /home/ubuntu/Desktop/star/logs/nginx-error.log,看是否有连接Socket失败、证书错误等信息 - ALB访问日志:在AWS控制台开启ALB访问日志,查看具体的错误原因(比如目标实例无响应)
- Django日志:检查应用本身是否有报错,比如数据库连接失败、依赖缺失等
内容的提问来源于stack exchange,提问作者Kunal Rathod

