Установка
Dispatch работает на нескольких сервисах, и всеми ими управляет Docker Compose.
Требования
- Docker 17.05.0+
- Docker Compose 1.19.0+
- Отдельный (под)домен для Dispatch (например, dispatch.yourcompany.com).
- Не менее 2400 МБ памяти
- 2 ядра CPU
Установка сервера Dispatch
Мы настоятельно рекомендуем устанавливать Dispatch и все его сервисы через Docker. Если вам нужно что-то нестандартное, возьмите этот репозиторий за основу своей установки. Если не хотите использовать наши Docker-образы, Dispatch по-прежнему есть на PyPI, но этот способ мы не рекомендуем: вам придётся восстанавливать всю сборку по основному образу Dispatch. Это не слишком сложно, но времени уйдёт заметно больше, и без шишек не обойдётся.
Чтобы установить Dispatch из репозитория, склонируйте его локально:
git clone https://github.com/Jamyn/dispatch-docker.git
Перед установкой настоятельно советуем прочитать, как настроить экземпляр Dispatch: при изменении настроек образы придётся пересобирать (docker-compose build). Вы можете скопировать и отредактировать примеры конфигов из репозитория. Если конфигов нет, скрипт установки возьмёт эти примеры как рабочие конфигурации.
Примечание: Dispatch не запустится без нескольких обязательных переменных конфигурации. См. пример конфигурационного файла .env.
Для начала запустите скрипт установки:
./install.sh
Примечание: Docker-сервис core больше не нужен после того, как собраны зависящие от него сервисы web и schedule.
Проблема «первого» пользователя
В новой установке Dispatch пользователи должны регистрироваться сами через адрес /auth/register в интерфейсе Dispatch. По умолчанию пользователи, зарегистрировавшиеся таким способом, получают обычные права «пользователя» («user»). Получить роль «Владелец» (Owner) через интерфейс напрямую нельзя: других владельцев, которые могли бы выдать доступ, ещё нет.
Для таких пользователей есть команда CLI, которая назначает пользователю нужную роль:
docker exec -it dispatch-web-1 bash
dispatch user update --role owner --organization <name-of-the-organization> <email-address-of-registered-user>
В файле с тестовыми данными организация по умолчанию называется «default».
Как только появится один пользователь с ролью «Владелец», он сможет выдавать эту роль другим через интерфейс.
Выход в продакшен
Прежде чем разворачивать Dispatch в продакшене, стоит учесть несколько моментов и сделать несколько шагов.
Основы
Dispatch хранит и обрабатывает чувствительную информацию, поэтому соблюдайте стандартные практики защиты хоста:
- Запускайте Dispatch от пользователя с ограниченными правами
- Отключите ненужные сервисы
- Включите удалённое логирование
- Ограничьте доступ к хосту
Управление учётными данными
Плагинам Dispatch нужны API-токены для работы со сторонними ресурсами. Эти токены хранятся либо в переменной окружения, либо в файле .env Dispatch.
По умолчанию эти строки лежат в открытом виде, но в Dispatch есть хуки, которые позволяют расшифровывать учётные данные при старте сервера. См. параметр конфигурации Secret Provider.
Аутентификация
Чтобы быстро начать работу, Dispatch предоставляет провайдер аутентификации «Basic», который управляет доступом по паре логин-пароль. По умолчанию этот провайдер разрешает открытую регистрацию: учётную запись Dispatch сможет создать любой, у кого есть сетевой доступ к вашему серверу.
Для более надёжной аутентификации Dispatch предлагает метод «PKCE», через который можно подключить существующие, более серьёзные решения SSO. См. Провайдер аутентификации
TLS/SSL
Nginx
Nginx — популярный выбор для обслуживания Python-проекта:
- Он быстрый.
- Он лёгкий.
- Конфигурационные файлы простые.
Nginx не запускает никаких процессов Python; он лишь передаёт внешние запросы серверу на Python.
Поэтому шага два:
- Запустить процесс Python.
- Запустить Nginx.
Что вы получите:
- Несколько проектов могут слушать порт 80;
- Процессы вашего сайта не будут работать с правами администратора, даже если – пользователь не работает в вашей ОС; -Возможность управлять процессом Python, не трогая Nginx и другие процессы. Это удобно при обновлениях.
Вам нужно создать конфигурационный файл Nginx для Dispatch. В GNU/Linux такие файлы обычно лежат в /etc/nginx/conf.d/. Назовите его dispatch.conf.
proxy_pass передаёт внешний запрос процессу Python. Порт должен совпадать с тем, который использует процесс Dispatch.
Несколько настроек помогут сделать работу с сайтом удобнее:
server_tokens off;
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
server {
listen 80;
return 301 https://$host$request_uri;
}
server {
listen 443;
access_log /var/log/nginx/log/dispatch.access.log;
error_log /var/log/nginx/log/dispatch.error.log;
location /api {
proxy_pass http://127.0.0.1:8000;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_redirect off;
proxy_buffering off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
}
location / {
root /path/to/dispatch/static/dist;
include mime.types;
index index.html;
}
}
Nginx будет отдавать favicon и статические файлы — он справляется с этим куда лучше, чем Python.
Мы рекомендуем включать TLS при развёртывании Dispatch. С учётом назначения Dispatch это, возможно, и так очевидно, но чувствительность данных и того, чем он управляет, делает TLS обязательным. Пример конфига Dispatch, который к тому же терминирует TLS:
Некоторые пути придётся подправить в зависимости от того, куда вы установили Dispatch.
server_tokens off;
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
server {
listen 80;
return 301 https://$host$request_uri;
}
server {
listen 443;
access_log /var/log/nginx/log/dispatch.access.log;
error_log /var/log/nginx/log/dispatch.error.log;
# certs sent to the client in SERVER HELLO are concatenated in ssl_certificate
ssl_certificate /path/to/signed_cert_plus_intermediates;
ssl_certificate_key /path/to/private_key;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
# Diffie-Hellman parameter for DHE cipher suites, recommended 2048 bits
ssl_dhparam /path/to/dhparam.pem;
# modern configuration. tweak to your needs.
ssl_protocols TLSv1.1 TLSv1.2;
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK';
ssl_prefer_server_ciphers on;
# HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)
add_header Strict-Transport-Security max-age=15768000;
# OCSP Stapling ---
# fetch OCSP records from URL in ssl_certificate and cache them
ssl_stapling on;
ssl_stapling_verify on;
## verify chain of trust of OCSP response using Root CA and Intermediate certs
ssl_trusted_certificate /path/to/root_CA_cert_plus_intermediates;
resolver <IP DNS resolver>;
location /api {
proxy_pass http://127.0.0.1:8000;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_redirect off;
proxy_buffering off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
}
location / {
root /path/to/dispatch/static/dist;
include mime.types;
index index.html;
}
}
Apache Пример конфига apache:
<VirtualHost \*:443>
...
SSLEngine on
SSLCertificateFile /path/to/signed_certificate
SSLCertificateChainFile /path/to/intermediate_certificate
SSLCertificateKeyFile /path/to/private/key
SSLCACertificateFile /path/to/all_ca_certs
# intermediate configuration, tweak to your needs
SSLProtocol all -SSLv2 -SSLv3
SSLCipherSuite ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA
SSLHonorCipherOrder on
# HSTS (mod_headers is required) (15768000 seconds = 6 months)
Header always set Strict-Transport-Security "max-age=15768000"
...
# Set the dispatch DocumentRoot to static/dist
DocumentRoot /www/dispatch/dispatch/static/dist
# Uncomment to force http 1.0 connections to proxy
# SetEnv force-proxy-request-1.0 1
#Don't keep proxy connections alive
SetEnv proxy-nokeepalive 1
# Only need to do reverse proxy
ProxyRequests Off
# Proxy requests to the API to the dispatch service (and sanitize redirects from it)
ProxyPass "/api" "http://127.0.0.1:8000/api"
ProxyPassReverse "/api" "http://127.0.0.1:8000/api"
</VirtualHost>
Этот конфиг не совсем полный. Если у вас есть рабочий конфиг apache, дайте нам знать!
В конфигурациях выше заложено и несколько лучших практик развёртывания TLS. Включить HSTS, отключить уязвимые шифры — всё это отличные идеи для развёртывания Dispatch в продакшене.
Другие варианты настройки SSL: Mozilla SSL Configuration Generator