Unleash в Docker Compose: готовый файл
Каждое включение фичи через полноценный деплой — это лишний риск: минуты простоя, откат всего релиза при проблеме, а если фича сырая — её видят все пользователи сразу. Unleash решает это переключателями, которые живут отдельно от кода и меняются в интерфейсе за секунды. Ниже — рабочий docker-compose.yml для self-hosted Unleash с PostgreSQL, изоляцией сети и TLS через Traefik, плюс на что обратить внимание с точки зрения безопасности — токены API это, по сути, ключи к бизнес-логике вашего продукта.
Содержание
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Что такое Unleash и когда self-hosted оправдан
Unleash — open-source сервер feature flags: приложение спрашивает у него «включена ли функция X для этого пользователя», а логику «кому включать» вы настраиваете в UI, без изменения кода. Есть облачная версия (Unleash.io), но self-hosted вариант имеет смысл, если вам важно:
- Не отдавать карту фич продукта третьей стороне — список флагов и правил таргетинга по сути описывает, какие эксперименты и сегменты пользователей есть в компании;
- Держать API-токены под собственным контролем — они дают доступ на чтение (а админ-токены и на запись) конфигурации флагов, и их утечка через чужую инфраструктуру — не то, что вы можете проконтролировать;
- Не упираться в лимиты бесплатных тарифов SaaS по числу флагов, окружений или проектов;
- Не зависеть от чужого расписания обновлений — self-hosted версию можно держать на нужном релизе сколько угодно.
Минус предсказуем — обслуживание на вас: обновления образа, бэкап базы, мониторинг доступности. Для команды это не более пары часов на первичную настройку и потом периодические docker compose pull.
Требования к серверу и состав стека
Unleash — лёгкий сервис по сравнению с тем же Harbor или GitLab. Стек состоит из двух контейнеров: сам Unleash (Node.js-приложение с UI и API) и PostgreSQL, где хранится вся конфигурация — проекты, флаги, стратегии, токены, история изменений.
| Параметр | Минимум | Комфортно (команда 10-30 человек) |
|---|---|---|
| CPU | 1 vCPU | 2 vCPU |
| RAM | 1 GB | 2 GB |
| Диск | 10 GB SSD | 20 GB SSD |
| ОС | Ubuntu 24.04, Debian 12 | то же |
База не растёт быстро — она хранит не события, а состояние флагов и историю их изменений, это килобайты и мегабайты, а не гигабайты. Единственное, что может раздуть диск — включённый подробный лог событий (event log) при очень активной команде, но и это редко становится проблемой раньше, чем через год-два.
Наружу нужен только один порт — 443/tcp, если вы ставите TLS-прокси перед Unleash (а ставить его нужно всегда, если сервис доступен из интернета: там ходят API-токены). Сам порт 4242, на котором слушает Unleash, наружу торчать не должен вообще — ниже в compose-файле он не пробрасывается на хост.
Docker и Docker Compose plugin ставятся стандартно:
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER
newgrp docker
docker compose version
Если на сервере уже поднят Traefik под другие сервисы — Unleash впишется в существующую внешнюю сеть proxy, конфиг ниже на это и рассчитан. Если Traefik ещё не настроен, механику разворота подробно разбирали в статье про Traefik как reverse proxy для Docker.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверГотовый docker-compose.yml
Структура проекта:
mkdir -p ~/unleash && cd ~/unleash
Файл .env — секреты отдельно от самого compose-файла, чтобы не утекли в git при коммите конфига:
POSTGRES_USER=unleash
POSTGRES_PASSWORD=замените-на-длинный-случайный-пароль
POSTGRES_DB=unleash
ADMIN_API_TOKEN=замените-на-случайную-строку
Пароль и токен генерируются сразу, а не придумываются на ходу:
openssl rand -base64 32
Сам docker-compose.yml:
services:
unleash-db:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB}
volumes:
- unleash-db-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD", "pg_isready", "-U", "${POSTGRES_USER}", "-d", "${POSTGRES_DB}"]
interval: 5s
timeout: 5s
retries: 10
networks:
- unleash-internal
unleash:
image: unleashorg/unleash-server:6
restart: unless-stopped
depends_on:
unleash-db:
condition: service_healthy
environment:
DATABASE_URL: postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@unleash-db:5432/${POSTGRES_DB}
DATABASE_SSL: "false"
LOG_LEVEL: warn
INIT_ADMIN_API_TOKENS: "*:*.${ADMIN_API_TOKEN}"
healthcheck:
test: ["CMD", "wget", "-qO-", "http://localhost:4242/health"]
interval: 10s
timeout: 5s
retries: 5
networks:
- unleash-internal
- proxy
labels:
- "traefik.enable=true"
- "traefik.http.routers.unleash.rule=Host(`flags.вашдомен.ru`)"
- "traefik.http.routers.unleash.entrypoints=websecure"
- "traefik.http.routers.unleash.tls.certresolver=le"
- "traefik.http.services.unleash.loadbalancer.server.port=4242"
networks:
unleash-internal:
internal: true
proxy:
external: true
volumes:
unleash-db-data:
Три момента, которые здесь неслучайны:
unleash-internalсinternal: true— PostgreSQL не имеет выхода наружу и недоступен даже другим контейнерам вне этой сети. Взломанный соседний контейнер на том же хосте не дотянется до базы напрямую.- Порт 4242 нигде не пробрасывается на хост — единственный путь к Unleash снаружи идёт через Traefik по 443 с TLS. Если Traefik ещё не поднят и нужно быстро проверить UI, временно откройте порт SSH-туннелем:
ssh -L 4242:localhost:4242 user@сервер— не открывайте порт вports:ради разовой проверки. INIT_ADMIN_API_TOKENSсоздаёт стартовый admin-токен из переменной.envпри первом запуске — не оставляйте дефолтное значение из документации Unleash, это первое, что проверяют при сканировании открытых сервисов.
Сеть proxy должна существовать заранее (docker network create proxy), если Traefik уже поднят отдельным compose-проектом — это стандартный паттерн для нескольких сервисов за одним прокси.
Поднимаем:
docker compose up -d
docker compose ps
Оба контейнера должны перейти в healthy в течение 20-30 секунд. Если unleash не стартует — почти всегда дело в несовпадении пароля между DATABASE_URL и переменными unleash-db, или в том, что healthcheck базы ещё не прошёл.
Первый запуск: workspace, окружения, токены, SDK
Открываете https://flags.вашдомен.ru (или через SSH-туннель, если TLS ещё не настроен). При первом входе интерфейс попросит создать пароль администратора — стандартные логин/пароль из документации Unleash одноразовые и должны быть сразу заменены на своё.
После входа создаются:
- Проект (Project) — логическая группа флагов, например
mainдля основного приложения. - Окружения (Environments) — по умолчанию
developmentиproduction, можно добавитьstaging. - API-токены в Settings → API access — отдельно для чтения (SDK приложений) и для администрирования.
Для клиентских приложений создавайте токены с типом CLIENT и областью действия на конкретный проект — не раздавайте приложениям admin-токены, полный доступ на запись не нужен коду, который просто спрашивает состояние флага.
Подключение SDK — пример на Node.js:
npm install unleash-client
const { initialize, isEnabled } = require('unleash-client');
const unleash = initialize({
url: 'https://flags.вашдомен.ru/api/',
appName: 'my-app',
customHeaders: { Authorization: 'ваш-client-токен' },
});
unleash.on('synchronized', () => {
if (isEnabled('new-checkout-flow')) {
// новая логика
}
});
SDK опрашивает сервер периодически и кэширует флаги локально: если Unleash временно недоступен, приложение продолжает работать на последнем известном состоянии, а не падает. Это осознанное архитектурное решение самого Unleash — сервер флагов не должен быть точкой отказа продакшена. Для браузерных и мобильных клиентов прямой доступ к Admin API не выдаётся вообще — используется прослойка Unleash Edge/Proxy, которая отдаёт клиенту только вычисленный результат, а не весь список правил.
Роли, ротация токенов и обслуживание
Категория безопасности здесь не формальность — Unleash хранит правила таргетинга (по каким ID, IP, сегментам пользователей включаются функции), а это фактически карта вашей бизнес-логики и экспериментов. Несколько практик, которые стоит закрыть с самого начала:
- Роли вместо общего логина. В open-source версии доступны роли Admin/Editor/Viewer на уровне инстанса и более гранулярные роли на уровне проекта. Не заводите одну учётку админа на всю команду — каждому разработчику отдельный вход с минимально нужной ролью.
- Разные токены для разных приложений. Один client-токен на все сервисы — это одна точка компрометации для всех них сразу. Заводите токен под каждое приложение/окружение, тогда утечка одного не требует ротации всех.
- Ротация токенов по расписанию. Токены создаются и отзываются в Settings → API access без даунтайма — старый продолжает работать, пока не отозван явно, поэтому ротацию можно делать постепенно: выпустить новый, выкатить в приложения, отозвать старый.
- SSO и расширенный аудит-лог — в open-source версии базовая ролевая модель есть из коробки, а SSO/SAML/OIDC, расширенный аудит и change-approval-процессы — это уже функциональность Enterprise-версии Unleash. Если команде принципиально важен единый вход и утверждение изменений флагов вторым человеком — стоит сверить актуальный список фич на официальном сайте перед тем, как закладывать это в архитектуру.
Бэкап — это дамп PostgreSQL, вся конфигурация флагов живёт там:
docker compose exec unleash-db pg_dump -U unleash unleash > unleash_backup_$(date +%Y%m%d).sql
Разумно вынести это в cron и держать копию отдельно от сервера, где крутится сам Unleash — про подходы к бэкапу баз в контейнерах подробно в статье про бэкап и восстановление через BorgBackup. Восстановление:
cat unleash_backup_20260825.sql | docker compose exec -T unleash-db psql -U unleash unleash
Обновление — стандартный docker compose pull && docker compose up -d. Перед мажорным скачком версии (например, между крупными релизами 6.x) стоит свериться с release notes на GitHub проекта: изредка меняется формат хранения стратегий, и накатываются миграции схемы автоматически при старте — со свежим бэкапом под рукой это не страшно, без него может стать неприятным сюрпризом.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Что будет с приложением, если контейнер Unleash упадёт?
Ничего катастрофичного — официальные SDK кэшируют последнее известное состояние флагов локально и продолжают его отдавать даже без связи с сервером. Проблема будет только с флагами, добавленными уже после потери связи, — их приложение не увидит.
Нужен ли отдельный сервер под Unleash?
Нет, стек с PostgreSQL спокойно живёт на том же VPS, где крутится основное приложение, если ресурсов достаточно — в простое он редко съедает больше 300-400 MB RAM. Разносить стоит только при нагрузке в тысячи запросов к API в секунду.
Чем self-hosted Unleash лучше файла флагов в JSON в коде?
Главное отличие — изменение флага без передеплоя, таргетинг по пользователям и процентам, отдельные окружения и история изменений в UI. JSON-файл в репозитории требует пересборки и раскатки на каждое изменение — это убивает саму идею feature flags как инструмента без даунтайма.
Можно ли использовать Unleash для A/B-тестов?
Частично — постепенный раскат (gradual rollout) по проценту пользователей это, по сути, базовый сплит, но встроенной статистики значимости и конверсий в Unleash нет. Для полноценных экспериментов его обычно связывают с внешней аналитикой, а Unleash отвечает только за то, кому какая версия показывается.
Как защитить админку, если в команде нет SSO?
Минимум — не открывать порт 4242 наружу вообще (как в конфиге выше), терминировать TLS на Traefik, а сам вход в UI держать на уникальных паролях и ролях Viewer/Editor/Admin по необходимости, а не общем admin-аккаунте.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →