【问题标题】:Nginx refuses connections to flask app, flask app without nginx works fineNginx 拒绝连接到烧瓶应用程序,没有 nginx 的烧瓶应用程序工作正常
【发布时间】:2020-01-20 07:25:03
【问题描述】:

我使用 docker compose 部署了 2 个 docker 容器。

一个是 nginx,另一个是我的烧瓶应用程序。我只是使用 nginx 作为静态服务器来进行加密认证。

如果我在没有 nginx 的情况下部署我的烧瓶应用程序,我可以成功地 curl / ping 我的服务器。但是,在引入 nginx 的那一刻,我无法连接。

我想要做的是至少通过数字外部 ip 访问我的服务器,例如xx.xx.xx.xx 然后我的域指向相同的 ip。 (我的域实际上是一个子域,例如 api.domain.com)

我的 docker compose 是:

services:
  nginx:
    build:
      context: ./nginx
      dockerfile: Dockerfile
      args:
        DOMAIN: ${DOMAIN}
        FLASK: application
    ports:
      - 80:80
      - 443:443
    volumes:
      - /etc/letsencrypt:/etc/letsencrypt
    depends_on:
      - application

  application:
    build:
      context: ./flask_app
      dockerfile: Dockerfile
    ports:
      - 5000:5000

nginx.conf

user nginx;

worker_processes auto;
worker_rlimit_nofile 8192;

error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

events {
    worker_connections 1024;
}

http {
    charset utf-8;
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    server_tokens off;
    log_not_found off;
    types_hash_max_size 2048;
    client_max_body_size 16M;

    include mime.types;
    default_type application/octet-stream;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ecdh_curve X25519:sect571r1:secp521r1:secp384r1;
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;
    ssl_session_tickets off;
    ssl_ciphers 'TLS13+AESGCM+AES128:TLS13+AESGCM+AES256:TLS13+CHACHA20:EECDH+AESGCM:EECDH+CHACHA20';
    ssl_stapling on;
    ssl_stapling_verify on;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log /var/log/nginx/access.log main;

    include conf.d/*.conf;
}

flask_app.conf

server {
    listen 80;
    listen [::]:80;
    server_name www.${DOMAIN} ${DOMAIN};

    location ^~ /.well-known/acme-challenge/ {
        root /var/www/_letsencrypt;
    }

    location / {
        return 301 https://${DOMAIN}${DOLLAR}request_uri;
    }
}

server {
    listen 443 ssl http2 default_server;
    listen [::]:443 ssl http2 default_server;
    server_name www.${DOMAIN} ${DOMAIN};

    ssl_certificate /etc/letsencrypt/live/${DOMAIN}/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/${DOMAIN}/privkey.pem;
    ssl_trusted_certificate /etc/letsencrypt/live/${DOMAIN}/chain.pem;

    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header Referrer-Policy "no-referrer-when-downgrade" always;

    # You might want to change the CSP policy to fit your needs - see https://content-security-policy.com/
    add_header Content-Security-Policy "default-src 'self'; script-src 'self'; connect-src 'self'; img-src 'self'; style-src 'self';";

    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
    add_header Allow "GET, POST, HEAD" always;

    access_log /var/log/nginx/${DOMAIN}.access.log;
    error_log /var/log/nginx/${DOMAIN}.error.log warn;

    location / {
        proxy_http_version 1.1;
        proxy_cache_bypass ${DOLLAR}http_upgrade;

        proxy_hide_header X-Powered-By;
        proxy_hide_header Server;
        proxy_hide_header X-AspNetMvc-Version;
        proxy_hide_header X-AspNet-Version;

        proxy_set_header Proxy "";
        proxy_set_header Upgrade ${DOLLAR}http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host ${DOLLAR}host;
        proxy_set_header X-Real-IP ${DOLLAR}remote_addr;
        proxy_set_header X-Forwarded-For ${DOLLAR}proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto ${DOLLAR}scheme;
        proxy_set_header X-Forwarded-Host ${DOLLAR}host;
        proxy_set_header X-Forwarded-Port ${DOLLAR}server_port;

        proxy_pass http://application:5000;
    }

    location ~* \.(?:css|cur|js|jpe?g|gif|htc|ico|png|html|xml|otf|ttf|eot|woff|woff2|svg)${DOLLAR} {
        expires 7d;
        add_header Pragma public;
        add_header Cache-Control public;

        proxy_pass http://application:5000;
    }

    if ( ${DOLLAR}request_method !~ ^(GET|POST|HEAD)${DOLLAR} ) {
        return 405;
    }

    if (${DOLLAR}http_user_agent ~* LWP::Simple|BBBike|wget) {
        return 403;
    }

    location ~ /\.(?!well-known) {
        deny all;
    }

    gzip on;
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_types text/plain text/css text/xml application/json application/javascript application/rss+xml application/atom+xml image/svg+xml;
}

【问题讨论】:

  • I am not able to connect => 您在浏览器中输入的 fqdn 是什么?是否与用于在 nginx conf 中选择虚拟服务器的$DOMAIN 相同?你检查你的 nginx/flask 访问/错误日志了吗?他们怎么说?
  • nginx 在容器内运行。 docker logs container-nginx 什么也没给我。我正在输入 api.domain.com,这正是 $DOMAIN 参数。 Flask 没有收到来自 nginx 的请求。
  • 你试过docker exec container-nginx tail -f /var/log/nginx/error.log 吗?这是您在 conf.xml 中找到错误日志的位置。 api.domain.com 是否正确地针对您的本地计算机(通过 dns 或主机条目)?
  • 当我删除 nginx 并且只使用烧瓶和 gunicorn 时,我的域正确解析。 docker exec container-nginx tail -f /var/log/nginx/error.log 悬挂 CLI。它不产生任何输出,不允许我在冻结时执行另一个命令。唯一的出路是 C^D。
  • 对我来说,似乎我也应该有域级别的日志,因为我定义了access_log /var/log/nginx/${DOMAIN}.access.log;error_log /var/log/nginx/${DOMAIN}.error.log warn;。但是,在运行ls /var/log/nginx 时,我只看到access.logerror.log。我都打不开

标签: docker nginx


【解决方案1】:

我不确定为什么您的 nginx 配置在多个位置包含 ${DOLLAR}。我不认为这是有效的语法,也找不到与此相关的任何文档。像这样的行:

proxy_set_header Host ${DOLLAR}host;

实际上应该是:

proxy_set_header Host $host;

至于在 nginx conf 中使用${DOMAIN},我会避免这种情况并选择更简单的配置。只需在 nginx 配置文件中指定域:

server_name www.example.com example.com;

我会熟悉“复杂配置”下的官方nginx image docs,它向您展示了如何从正在运行的容器中复制工作配置,然后根据您的需要进行修改。

一旦你有了这个工作,如果你真的想在你的 docker-compose 文件中指定域,并将你的 nginx 配置视为在容器启动时修改的模板,你可以继续阅读“使用nginx 配置中的环境变量”,它显示了使用envsubst 来实现这一点的解决方法。然而,这对于单站点部署可能不是必需的。

【讨论】:

    猜你喜欢
    • 2021-01-20
    • 2013-09-01
    • 2017-11-01
    • 2021-01-27
    • 1970-01-01
    • 1970-01-01
    • 2014-05-08
    • 2012-11-19
    • 2018-05-27
    相关资源
    最近更新 更多