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

24.07.2019

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

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

Настройка Apache:

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

1
mcedit /etc/httpd/conf/httpd.conf

Заменяем:

1
Listen 80

На:

1
Listen 8080

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

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

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

На:

1
<VirtualHost *:8080>

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

1
systemctl restart httpd

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

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

1
2
3
4
5
6
7
8
9
from flask import Flask
app = Flask(__name__)
 
@app.route("/")
def hello():
    return "Hello World!"
 
if __name__ == "__main__":
    app.run()

1
python main.py

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

1
2
3
4
5
6
* 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.

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

1
2
3
4
5
6
7
8
9
10
11
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)

1
2
3
yum -y install python-pip
pip install flask
pip install gunicorn

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

1
gunicorn main:app

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

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

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

1
yum -y install nginx

Настройка Nginx:

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

1
mcedit /etc/nginx/nginx.conf

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# 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 набора правил:

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

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

  • 1
    2
    listen  80;
    server_name test3.local;

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

  • 1
    2
    listen       80;
    server_name  test4.local;

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

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

1
systemctl restart nginx

На этом все.

Еще по теме

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


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