Nginx Unit
Не так давно от команды 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 -
Создаём файл
/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 -
Устанавливаем unit:
apt-get update apt-get install unit -
Устанавливаем дополнительные пакеты:
apt-get install python2.7 python3
Также подготовлен готовый образ, его можно скачать с Docker Hub:
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-адресе и порту слушать выбранное приложение. Applications указывают, что надо запускать, основываясь на типе приложения и указанном пути.
Конфигурация тестового приложения:
"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]
Добавление Flask-приложения
Добавим приложение, которое слушает порт 8400. Конфигурационный файл:
{
"type": "python",
"workers": 5,
"module": "wsgi",
"user": "root",
"group": "root",
"path": "/apps/flask"
}
Добавляем конфигурацию в Unit:
curl -X PUT -d@/apps/flask_app.json '127.0.0.1:8443/applications/flask_sample'
Приложение использует фреймворк Flask — устанавливаем его вручную:
apt-get install python-pip
pip install flask
Вносим изменения для приложения в 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>
Приложения можно менять на лету. Например, повесить Flask-приложение на порт 8300. Или выключить любое приложение:
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 на данный момент не поддерживает авторизацию, поэтому выставлять его открытым наружу нельзя.
Заключение
В рамках одного Unit можно объединить несколько приложений на разных языках и платформах — работа с ними ничем не отличается от приложений на Python. В целом решение получилось очень перспективным и обязательно найдёт свою нишу в современных веб-проектах.