【问题标题】:Serving static files via Nginx proxying HTTPS to gunicorn django in docker-compose通过 Nginx 代理 HTTPS 向 docker-compose 中的 gunicorn django 提供静态文件
【发布时间】:2023-04-01 03:09:01
【问题描述】:

我正在使用 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,然后 docker-compose pull 并在 EC2 实例上使用 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)。

有人知道我做错了什么吗?

【问题讨论】:

  • 所以把这个location /static/移动到443 conf部分。
  • 错误消息是说 nginx 无法连接到您的应用程序。这与其他位置定义无关。
  • 这是什么意思?

标签: django docker nginx docker-compose


【解决方案1】:

使用nginx -T 检查您的配置文件 - 您看到正确的配置了吗?您的构建过程是否引入了正确的配置?

在远程机器上调试它会很有帮助 - docker-compose exec nginx sh 进入内部并从那里调整 conf 和 nginx -s reload。这将加快您调试 SSL 问题的迭代周期。

【讨论】:

  • 问题实际上是在构建链中!拍摄了错误的图像。将 location /static/ 块移动到 SSL 服务器配置上下文就可以了。
猜你喜欢
  • 2023-03-05
  • 2015-11-30
  • 2019-05-31
  • 2019-07-21
  • 2013-06-27
  • 2017-05-31
  • 2011-01-27
  • 2016-07-17
  • 2021-07-18
相关资源
最近更新 更多