Использование Nginx как прокси для разных веб интерфейсов на одном сервере (Centos 7)

24.07.2019

Итак задача:
Есть сервер с уже установленным и настроенным Apache, при запросе по определенному доменному имени нужно запускать скрипт, сделанный на Python фреймворке Flask.

Т.е. нужно чтобы Nginx разделял запросы пришедшие на 80 порт и в зависимости от адреса передавал запрос или Apache или Python.

Настройка Apache:

Меняем основной порт, который слушает служба httpd

 
mcedit /etc/httpd/conf/httpd.conf

Заменяем:

 
Listen 80

На:

 
Listen 8080

Также нужно перенастроить все виртуальные хосты. По очереди перебираем все файлы:

 
mcedit /etc/httpd/conf.d/SITE_NAME.conf

Меняем:
 
<VirtualHost *:80>

На:

 
<VirtualHost *:8080>

Не забываем перезагрузить сервис:

 
systemctl restart httpd

Настройка Python + Flask + WSGI

Сам Flask позволяет запускать мини web сервер просто выполнив скрипт:

 
from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello World!"

if __name__ == "__main__":
    app.run()

 
python main.py

И сам же предупреждает, что делать так стоит только в тестовом окружении:

 
 * Serving Flask app "main" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

Поэтому как вебсервер будем использовать WSGI.

Сразу внесем пару правок в скрипт:

 
from flask import Flask
from werkzeug.contrib.fixers import ProxyFix
app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello World!"

app.wsgi_app = ProxyFix(app.wsgi_app)
if __name__ == "__main__":
    app.run()

Устанавливаем pip, сам Flask и WSGI (gunicorn)

 
yum -y install python-pip
pip install flask
pip install gunicorn

Запускаем наш скрипт:

 
gunicorn main:app

По умолчанию он запуститься на порту 8000 (Listening at: http://127.0.0.1:8000)

Установка Nginx на Centos:

Тут все стандартно:

 
yum -y install nginx

Настройка Nginx:

Редактируем конфигурационный файл Nginx:

 
mcedit /etc/nginx/nginx.conf

Вот готовый конфиг:

 
# For more information on configuration, see:
#   * Official English Documentation: http://nginx.org/en/docs/
#   * Official Russian Documentation: http://nginx.org/ru/docs/

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

http {
    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;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 2048;

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

    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    include /etc/nginx/conf.d/*.conf;

    server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  _;
        root         /usr/share/nginx/html;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location / {
            proxy_pass http://127.0.0.1:8080/;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $remote_addr;
            proxy_connect_timeout 120;
            proxy_send_timeout 120;
            proxy_read_timeout 180;
        }

        error_page 404 /404.html;
            location = /40x.html {
        }

        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    }
    
    
    server {
        listen  80;
        server_name test3.local;
        location / {
            root  /home/public/test3.local/www;
            index  index.html index.htm;
            try_files $uri $uri/ =404;
        }
        error_page  500 502 503 504  /50x.html;
        location = /50x.html {
            root  /usr/share/nginx/html;
        }
    }
    
    server {
        listen       80;
        server_name  test4.local;
        root         /usr/share/nginx/html;

        location / {
            proxy_pass http://127.0.0.1:8000/;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $remote_addr;
            proxy_connect_timeout 120;
            proxy_send_timeout 120;
            proxy_read_timeout 180;
        }

        error_page 404 /404.html;
            location = /40x.html {
        }

        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    }

# Settings for a TLS enabled server.
#
#    server {
#        listen       443 ssl http2 default_server;
#        listen       [::]:443 ssl http2 default_server;
#        server_name  _;
#        root         /usr/share/nginx/html;
#
#        ssl_certificate "/etc/pki/nginx/server.crt";
#        ssl_certificate_key "/etc/pki/nginx/private/server.key";
#        ssl_session_cache shared:SSL:1m;
#        ssl_session_timeout  10m;
#        ssl_ciphers HIGH:!aNULL:!MD5;
#        ssl_prefer_server_ciphers on;
#
#        # Load configuration files for the default server block.
#        include /etc/nginx/default.d/*.conf;
#
#        location / {
#        }
#
#        error_page 404 /404.html;
#            location = /40x.html {
#        }
#
#        error_page 500 502 503 504 /50x.html;
#            location = /50x.html {
#        }
#    }

}

Тут 3 набора правил:

  •  
            listen       80 default_server;
            listen       [::]:80 default_server;
    

    - отправляет все запросы, не обработанные другим правилом, на Apache (http://127.0.0.1:8080/ - данный порт, указывали при настроке Apache)

  •  
            listen  80;
            server_name test3.local;
    

    - это тестовый домен, который будет обрабатывать сам Nginx (Присутствует только для примера)

  •  
            listen       80;
            server_name  test4.local;
    

    - отправляет все запросы, у которых доменное имя test4.local на WSGI (http://127.0.0.1:8000/ - это стандартный порт WSGI

Далее перезагружаем Nginx

 
systemctl restart nginx

На этом все.

Еще по теме

Также можно не устанавливать Python и Flask на хостовую машину, а поднять ее через Docker конетйнер: Как сделать и запустить образ Docker с Python Flask на борту. Соответственно в настройках b>Nginx нужно будет указать тот порт (http://127.0.0.1:8000/), который будет указан при запуске контейнера.


Категории: Linux, Docker, Centos
Яндекс.Метрика