Nginx отказывается от подключения к flask приложению, flask приложение без nginx работает нормально - PullRequest
0 голосов
/ 19 января 2020

У меня 2 docker контейнера, развернутого с использованием docker compose.

Один - nginx, а другой - мое flask приложение. Я только использую nginx в качестве сервера c для шифрования сертификации.

Если я разверну свое приложение flask без nginx, я смогу успешно свернуть / пинговать свой сервер. Однако, когда введен nginx, я не могу подключиться.

То, что я хочу сделать, это, по крайней мере, получить доступ к моему серверу через числовой c внешний ip, например, xx.xx.xx.xx, а затем мой домен, который указывает на тот же ip. (Мой домен на самом деле является поддоменом, например, api.domain.com)

Мой docker состав:

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;
}

1 Ответ

1 голос
/ 20 января 2020

Я не уверен, почему ваша конфигурация nginx содержит ${DOLLAR} в нескольких местах. Я не думаю, что это правильный синтаксис, и не могу найти никакой документации, относящейся к этому. Строки, как:

proxy_set_header Host ${DOLLAR}host;

На самом деле должно быть:

proxy_set_header Host $host;

Что касается использования ${DOMAIN} в nginx conf, я бы избегал этого и выбрал бы более простая конфигурация Просто укажите домен в файле конфигурации nginx:

server_name www.example.com example.com;

Я бы ознакомился с официальным документом nginx image в разделе "Сложная конфигурация", в котором показано, как скопируйте рабочую конфигурацию из работающего контейнера, затем измените ее в соответствии с вашими потребностями.

Если у вас все получилось, если вы действительно хотите указать домен в файле docker -compose, и обработайте свой nginx config как шаблон, который изменяется во время запуска контейнера, вы можете перейти к разделу «Использование переменных среды в конфигурации nginx», в котором показан обходной путь использования envsubst для достижения этой цели. Однако, вероятно, это не требуется для развертываний на одном сайте.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...