Не так давно от команды Nginx была представлена новая разработка Unit. Это Application Server, который позволяет запускать приложения на нескольких языках, при этом предоставляя простую конфигурацию и настройку посредством REST API. На данный момент Unit находится в стадии beta. Посмотрим же на основные возможности, которые предлагает этот продукт.
Установка
Поддерживаются следующие системы
- Linux >= 2.6
- FreeBSD >=9
- Mac Os X
- Solaris 11
Для Ubuntu установка достаточно простая
- Скачиваем ключ
- Добавляем ключ
apt-key add nginx_signing.key
3. Создаем файл /etc/apt/sources.list.d/unit.list следующего содержания
deb http://packages.nginx.org/unit/ubuntu/ xenial unit
deb-src http://packages.nginx.org/unit/ubuntu/ xenial unit
apt-get update
apt-get install unit
apt-get install python2.7 python3
Я подготовил образ, его можно скачать с хаба докера
docker pull miholeus/nginx-unit-python
Настройка
После установки unit пришло время настроить его и запустить наше приложение. Приложение напишем на python. Самый простой пример wsgi приложения:
import sys
def application(environ, start_response):
body = sys.version.encode("utf-8")
status = "200 OK"
headers = [('Content-type','text/plain')]
start_response(status, headers)
return body
Нам надо определить listeners и applications. Applications могут быть на одном из поддерживаемых unit языков. Listener определяет на каком ip-address и порту слушать выбранное приложение. Приложения указывают что надо запускать, основываясь на типе приложения и указанном пути.
Сделаем тестовое приложение такого вида
"test": {
"type": "python",
"workers": 10,
"module": "wsgi",
"user": "root",
"group": "root",
"path": "/apps/py"
}
Запустим наш контейнер
docker run --name nginx_unit_python -v pwd
/demo:/apps -p 8300:8300 miholeus/nginx-unit-python
Выполним конфигурацию
docker exec -ti nginx_unit_python curl -X PUT -d @/apps/python.json '127.0.0.1:8443'
Проверим наше приложение
curl 127.0.0.1:8300
В ответ получим что-то вроде
2.7.12 (default, Nov 20 2017, 18:23:56)
[GCC 5.4.0 20160609]
Давайте теперь добавим приложение, которое слушает порт 8400.
Наш конфигурационный файл будет выглядеть следующим образом
{
"type": "python",
"workers": 5,
"module": "wsgi",
"user": "root",
"group": "root",
"path": "/apps/flask"
}
Добавим эту конфигурацию в наш unit
curl -X PUT [email protected]/apps/flask_app.json '127.0.0.1:8443/applications/flask_sample'
Приложение использует фреймворк Flask. Поэтому придется установить его вручную. Сначала добавим pip в контейнер, а затем установим flask.
apt-get install python-pip
pip install flask
Я не стал добавлять pip на этапе сборки в контейнер, можете сделать это самостоятельно.
И наконец, внесем наши изменения для приложения в unit
curl -X PUT -d '{"application":"flask_sample"}' '127.0.0.1:8443/listeners/*:8400'
Само приложение так же простое
# Файл wsgi.py
from hello import application
if name == "main":
application.run()
# Файл hello.py
from flask import Flask
application = Flask(name)
@application.route("/")
def hello():
return "<h1 style='color:blue'>Hello From Flask!</h1>"
if name == "main":
application.run(host='0.0.0.0')
Проверим наше приложение
curl 127.0.0.1:8400
Получим
<h1 style='color:blue'>Hello From Flask!</h1>
Мы легко можем менять наши приложения на лету. К примеру, на порт 8300 может повесить приложение с Flask. Или можно выключить какое-либо приложение
curl -X DELETE '127.0.0.1:8443/listeners/*:8300'
При этом все текущие сессии останутся активными, а новые запросы на 8300-й порт уже проходить не будут.
Интеграция с Nginx
Интеграция выполняется очень просто. Сначала создается upstream для нашего приложения
upstream unit_backend {
server 127.0.0.1:8300;
}
А затем основная конфигурация сервера
server {
location /static {
root /var/www/files;
}
location / {
proxy_pass http://unit_backend;
proxy_set_header Host $host;
}
}
Сам Unit на данный момент не поддерживает авторизацию, поэтому выставлять его открытым наружу нельзя.
Я не рассматривал работу с другими типами приложений. Она ничем не отличается от приложений на python. Можно в рамках одного юнита объединить несколько приложений на разных языках (платформах).
В целом решение получилось очень перспективным и оно обязательно найдет свою нишу в современных веб проектах.
Ссылки:
Привет. Сейчас хочу настроить сервер приложений для питона и вот nginx unit не хочет запускать flask-приложение из wsgi-файла. В чем проблема – не ясно. Flask установлен. В логах unit пишет:
2018/04/03 18:22:36 [info] 20579#20579 “sample_flask” application started
2018/04/03 18:22:36 [alert] 20579#20579 Python failed to import module “wsgi”
2018/04/03 18:22:36 [notice] 15925#15925 process 20579 exited with code 1
2018/04/03 18:22:36 [warn] 15928#15928 failed to start application “sample_flask”
2018/04/03 18:22:36 [alert] 15928#15928 failed to apply new conf
2018/04/03 18:23:57 [info] 20665#20665 “sample_flask” application started
2018/04/03 18:23:57 [alert] 20665#20665 Python failed to import module “wsgi”
2018/04/03 18:23:57 [notice] 15925#15925 process 20665 exited with code 1
2018/04/03 18:23:57 [warn] 15928#15928 failed to start application “sample_flask”
2018/04/03 18:23:57 [alert] 15928#15928 failed to apply new conf
Проблема, скорее всего, в неправильном указании пути к wsgi файлу