django - 通过 Nginx 代理 HTTPS 向 docker-compose 中的 gunicorn django 提供静态文件
问题描述
我正在使用 docker-compose 将我的 Django/Nginx/Gunicorn webapp 部署到 EC2 实例。EC2 实例具有mywebapp.com
/www.mywebapp.com
指向的静态 IP,并且我已经完成了certbot
验证(站点通过 HTTP 在端口 80 上工作),但现在正试图通过 SSL 工作。
现在,HTTP(包括加载静态文件)正在为我工作,HTTPS 动态内容(来自 Django)正在工作,但静态文件不是。我认为我的 nginx 配置很不稳定。
我尝试将location /static/
块复制到 nginx conf 文件中的 SSL 服务器上下文,但这导致 SSL 完全停止工作,而不仅仅是 SSL 上的静态文件。
这是最终的 docker-compose.yml:
services:
certbot:
entrypoint: /bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h &
wait $${!}; done;'
image: certbot/certbot
volumes:
- /home/ec2-user/certbot/conf:/etc/letsencrypt:rw
- /home/ec2-user/certbot/www:/var/www/certbot:rw
nginx:
command: /bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done
& nginx -g "daemon off;"'
depends_on:
- web
image: xxxxxxxx.dkr.ecr.us-east-1.amazonaws.com/xxxxxxxx:latest
ports:
- 80:80/tcp
- 443:443/tcp
volumes:
- /home/ec2-user/certbot/conf:/etc/letsencrypt:rw
- static_volume:/usr/src/app/public:rw
- /home/ec2-user/certbot/www:/var/www/certbot:rw
web:
entrypoint: gunicorn mywebapp.wsgi:application --bind 0.0.0.0:7000"
image: xxxxxxxx.dkr.ecr.us-east-1.amazonaws.com/xxxxxxxx:latest
volumes:
- static_volume:/usr/src/app/public:rw
version: '3.0'
volumes:
static_volume: {}
nginx.prod.conf
:
upstream mywebapp {
# web is the name of the service in the docker-compose.yml
# 7000 is the port that gunicorn listens on
server web:7000;
}
server {
listen 80;
server_name mywebapp;
location / {
proxy_pass http://mywebapp;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
location /static/ {
alias /usr/src/app/public/;
}
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
}
server {
# https://github.com/wmnnd/nginx-certbot/blob/master/data/nginx/app.conf
listen 443 ssl;
server_name mywebapp;
server_tokens off;
location / {
proxy_pass http://mywebapp;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
# generated with help of certbot
ssl_certificate /etc/letsencrypt/live/mywebapp.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mywebapp.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
}
最后是 nginx 服务 Dockerfile:
FROM nginx:1.15.12-alpine
RUN rm /etc/nginx/conf.d/default.conf
COPY ./nginx.prod.conf /etc/nginx/conf.d
我只是在本地机器上构建、推送到 ECR,然后在 EC2 实例上docker-compose pull
运行。docker-compose up -d
我看到的错误docker-compose logs
是:
nginx_1 | 2019/05/09 02:30:34 [error] 8#8: *1 connect() failed (111: Connection refused) while connecting to upstream, client: xx.xx.xx.xx, server: mywebapp, request: "GET / HTTP/1.1", upstream: "http://192.168.111.3:7000/", host: "ec2-xxx-xxx-xxx-xxx.compute-1.amazonaws.com"
而且我不确定出了什么问题。我正在尝试使用我生成并验证的证书在 HTTPS 下正确提供动态内容(gunicorn)和静态内容(来自:/usr/src/app/public)。
有谁知道我可能做错了什么?
解决方案
检查您的配置文件nginx -T
- 您看到正确的配置了吗?您的构建过程是否引入了正确的配置?
仅在远程机器上调试它会很有帮助 -docker-compose exec nginx sh
进入内部并从那里调整 conf 和nginx -s reload
. 这将加快您调试 SSL 问题的迭代周期。
推荐阅读
- javascript - Openlayers:防止功能图标覆盖
- javascript - 如何在Angular中过滤和显示关于文本的图像
- swift - 使用 Alamofire 时是否需要创建自己的会话?
- python-3.x - Python:遍历具有不同参数的函数
- powershell - 如何扫描多个主机名以解析 IP 地址 Powershell 脚本
- drools - 触发规则时禁用其他规则
- linux - 使用 sed -i 运行连续命令
- r - 在 pROC 中使用 ROC 曲线打印的 AUC 的小数限制
- facebook-graph-api - 检查用户是否是 Facebook 群组的成员
- azure - Azure 的应用程序洞察力密钥能否破坏整个 Web 应用程序?