В рамках разработки Nginx Platform компания Nginx занимается созданием динамического сервера приложений Nginx Unit. Unit поддерживает полностью динамическую реконфигурацию с использованием JSON API в архитектуре REST, несколько языков приложений и одновременную работу версий. Сейчас Unit поддерживает Python, PHP и Go; в планах — JavaScript / Node.js, Java и Ruby.

NGINX Unit — это динамический сервер веб-приложений, предназначенный для запуска приложений на нескольких языках. Unit — легкий, многоязычный сервер, динамически настраиваемый через API. Структура сервера позволяет реконфигурировать конкретные параметры приложения по мере необходимости при разработке или уже в работе.

На данный момент доступна бета-версия NGINX Unit. Поэтому сервер подходит для использования с тестовой среде, но не рекомендован для полноценной эксплуатации.

Поскольку пока есть только бета-версия, я решил начать поэкспериментировать с ним на PHP-приложениях. Можете изучить мой репозиторий с демо-проектом Nginx Unit, который запускает приложение Laravel с помощью Nginx Unit в Docker.

Изучив все возможности, я решил упростить себе задачу и использовать образ ubuntu:xenial вместо того, чтобы собирать Nginx из исходный файлов. Вот мой Dockerfile:

FROM ubuntu:xenial

RUN set -xe \
&& apt-get -y update \
&& apt-get -y install --no-install-recommends curl php \
&& curl http://nginx.org/keys/nginx_signing.key | apt-key add - \
&& echo "deb http://nginx.org/packages/mainline/ubuntu/ xenial nginx"  | tee -a /etc/apt/sources.list \
&& echo "deb-src http://nginx.org/packages/mainline/ubuntu/ xenial nginx" | tee -a /etc/apt/sources.list \
&& apt-get -y update \
&& apt-get -y install unit \
&& unitd --version

WORKDIR /www/laravel

COPY ./src /www/laravel

RUN chown -R www-data:www-data /www/laravel

CMD ["unitd", "--no-daemon"]

Что мне нравится в Unit, так это возможность запускать несколько языковых конфигураций (например, приложения Golang и PHP) и определять объекты конфигурации через API. Как видно из моего репозитория, после запуска контейнера Docker я запускаю следующий процесс, чтобы определить PHP-приложение:

#!/usr/bin/env bash
container=$(docker run --rm -d -v $(pwd)/src:/www/laravel -p 8300:8300 nginx-unit)
docker exec -ti $container curl -X PUT -d @/www/laravel/app.json --unix-socket /var/run/control.unit.sock http://localhost

echo "Container running @ $container"
echo "Here's the complete configuration object:"
docker exec -ti $container curl --unix-socket /var/run/control.unit.sock http://localhost

Вот пример объекта конфигурации для Laravel, который получился у меня:

app.json:

{
    "listeners": {
        "*:8300": {
            "application": "laravel-demo"
        }
    },
    "applications": {
        "laravel-demo": {
            "type": "php",
            "workers": 20,
            "user": "www-data",
            "group": "www-data",
            "root": "/www/laravel/public",
            "index": "index.php"
        }
    }
}

Попробуйте самостоятельно развернуть проект из репозитория и напишите, что думаете в твиттер @xcepshn!

Перевод статьи «Nginx Unit with Docker, PHP, and Laravel» by Paul Redmond