MAATRIX / Блог / Taiga в Docker Compose: готовый файл

Taiga в Docker Compose: готовый файл

MAATRIX

Если команда переросла Trello, а Jira кажется избыточной по деньгам — Taiga закрывает эту нишу: скрам-доски, спринты, бэклог, канбан и эпики в одном self-hosted инструменте. Разворачивается она не одной командой docker run, а стеком из десятка контейнеров, и собрать рабочий docker-compose.yml с нуля — задача на пару вечеров с граблями по очередям и обратному прокси. Ниже — готовый файл, который можно взять и адаптировать под свой домен за 15 минут.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →

Что такое Taiga и зачем разворачивать её на своём сервере

Taiga — open-source платформа управления проектами для Agile-команд: разработана испанской Kaleidos, используется как альтернатива Jira и YouTrack там, где важны простота интерфейса и отсутствие лицензионных платежей за каждого пользователя. Из коробки есть:

  • скрам-доски со спринтами и бэклогом;
  • канбан-доски для потоковой работы без спринтов;
  • эпики, задачи, баги, вопросы (issues) с настраиваемыми статусами;
  • вики проекта, вложения, теги, кастомные поля;
  • API и webhooks для интеграций с CI/CD и мессенджерами.

Аргумент в пользу самостоятельного хостинга — данные проекта (сроки, оценки, внутренние обсуждения) остаются на вашем сервере, а не в облаке зарубежного SaaS. Второй аргумент — цена: команде из 15-20 человек облачная подписка обходится в разы дороже аренды VPS, на котором Taiga спокойно работает годами.

Минус тоже стоит назвать честно: это не однобинарник, а связка backend на Django, frontend на Angular, очереди на RabbitMQ и отдельные сервисы для realtime-событий и раздачи файлов. Разворачивать её ради одного человека избыточно — для соло-разработчика больше подойдёт что-то полегче, например Focalboard или Wekan.

Из каких контейнеров состоит Taiga: архитектура стека

Официальный способ развёртывания Taiga — docker-compose из нескольких сервисов, каждый отвечает за свою часть системы:

СервисРоль
taiga-dbPostgreSQL — хранилище данных проектов
taiga-backDjango backend, REST API
taiga-asyncCelery-воркер для фоновых задач (импорт/экспорт, письма)
taiga-async-rabbitmqБрокер очередей для taiga-async
taiga-eventsRealtime-уведомления (обновления доски без перезагрузки)
taiga-events-rabbitmqОтдельный брокер очередей для событий
taiga-protectedРаздача приватных вложений с проверкой прав
taiga-frontСобранный Angular-фронтенд
taiga-gatewayNginx, склеивает фронт, API, вебсокеты и файлы в один вход
taiga-manageСлужебный контейнер для manage.py — миграции, суперпользователь

Наружу торчит только taiga-gateway — остальные сервисы общаются между собой во внутренней docker-сети и снаружи недоступны. Внешний обратный прокси на хосте достаточно направить одним proxy_pass на порт gateway, а TLS терминировать уже на нём. Если на сервере уже поднят Traefik для других контейнеров, схема из статьи про Traefik как reverse proxy для Docker ложится сюда без переделок — просто добавьте лейблы на taiga-gateway.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Требования к серверу и подготовка

Стек из десятка контейнеров с PostgreSQL и двумя брокерами RabbitMQ не тяжёлый по CPU, но требователен к памяти — Django, Celery и два экземпляра RabbitMQ держат в резиденте прилично оперативки даже без активных пользователей. Ориентировочно для команды до 20-30 человек хватает:

  • 2 vCPU;
  • 4 ГБ RAM (минимум для стабильной работы, 6-8 ГБ — комфортный запас, если сервер не только под Taiga);
  • 40 ГБ диска SSD/NVMe (Postgres любит быструю дисковую подсистему), дальше рост зависит от объёма вложений;
  • Ubuntu 24.04 или Debian 12 с Docker Engine и Docker Compose plugin;
  • домен (поддомен) с A-записью на IP сервера — Taiga жёстко завязана на домен в конфиге, по голому IP без танцев с бубном не заработает.

Точные цифры потребления зависят от числа активных проектов и подключений через вебсокеты — это ориентир для старта, а не гарантированный потолок; при росте команды смотрите на docker stats.

Перед стартом создайте рабочую директорию и три подпапки под volumes:

mkdir -p ~/taiga/{taiga-static,taiga-media,taiga-db}
cd ~/taiga

Готовый docker-compose.yml и .env-файл

Сначала .env — сюда выносим всё, что нужно поменять под себя (домен, пароли, почту). Секретные значения ниже — примеры, замените на собственные случайные строки.

# .env
TAIGA_SCHEME=https
TAIGA_DOMAIN=taiga.example.com
SUBPATH=
WEBSOCKETS_SCHEME=wss

# случайная строка 50+ символов, например: openssl rand -base64 48
TAIGA_SECRET_KEY=замените-на-случайную-строку

POSTGRES_DB=taiga
POSTGRES_USER=taiga
POSTGRES_PASSWORD=замените-на-сложный-пароль

RABBITMQ_USER=taiga
RABBITMQ_PASS=замените-на-сложный-пароль
RABBITMQ_ERLANG_COOKIE=замените-на-случайную-строку

# почта нужна для приглашений участников и уведомлений
EMAIL_BACKEND=django.core.mail.backends.smtp.EmailBackend
EMAIL_HOST=smtp.example.com
EMAIL_PORT=587
EMAIL_HOST_USER=taiga@example.com
EMAIL_HOST_PASSWORD=замените-на-пароль-почты
EMAIL_USE_TLS=True
EMAIL_DEFAULT_FROM=taiga@example.com

ENABLE_TELEMETRY=False

Теперь сам docker-compose.yml. Тэги образов ниже — рабочие на момент подготовки статьи (конец августа 2026), но перед запуском стоит свериться с актуальными тегами на Docker Hub в репозиториях taigaio/* — проект развивается, и разумно закрепить конкретную версию, а не гнаться за latest на проде.

services:
  taiga-db:
    image: postgres:15-alpine
    environment:
      POSTGRES_DB: ${POSTGRES_DB}
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    volumes: ["./taiga-db:/var/lib/postgresql/data"]
    restart: unless-stopped

  taiga-async-rabbitmq:
    image: rabbitmq:3-management-alpine
    environment: &rabbit-env
      RABBITMQ_ERLANG_COOKIE: ${RABBITMQ_ERLANG_COOKIE}
      RABBITMQ_DEFAULT_USER: ${RABBITMQ_USER}
      RABBITMQ_DEFAULT_PASS: ${RABBITMQ_PASS}
      RABBITMQ_DEFAULT_VHOST: taiga
    restart: unless-stopped

  taiga-events-rabbitmq:
    image: rabbitmq:3-management-alpine
    environment: *rabbit-env
    restart: unless-stopped

  taiga-back:
    image: taigaio/taiga-back:latest
    environment: &back-env
      TAIGA_SECRET_KEY: ${TAIGA_SECRET_KEY}
      TAIGA_SITES_SCHEME: ${TAIGA_SCHEME}
      TAIGA_SITES_DOMAIN: ${TAIGA_DOMAIN}
      TAIGA_SUBPATH: ${SUBPATH}
      POSTGRES_DB: ${POSTGRES_DB}
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_HOST: taiga-db
      RABBITMQ_USER: ${RABBITMQ_USER}
      RABBITMQ_PASS: ${RABBITMQ_PASS}
      EMAIL_BACKEND: ${EMAIL_BACKEND}
      EMAIL_HOST: ${EMAIL_HOST}
      EMAIL_PORT: ${EMAIL_PORT}
      EMAIL_HOST_USER: ${EMAIL_HOST_USER}
      EMAIL_HOST_PASSWORD: ${EMAIL_HOST_PASSWORD}
      EMAIL_USE_TLS: ${EMAIL_USE_TLS}
      EMAIL_DEFAULT_FROM: ${EMAIL_DEFAULT_FROM}
      ENABLE_TELEMETRY: ${ENABLE_TELEMETRY}
    volumes: &back-volumes ["./taiga-static:/taiga-back/static", "./taiga-media:/taiga-back/media"]
    depends_on: [taiga-db, taiga-async-rabbitmq]
    restart: unless-stopped

  taiga-async:
    image: taigaio/taiga-back:latest
    entrypoint: ["/taiga-back/docker/async_entrypoint.sh"]
    environment: *back-env
    volumes: *back-volumes
    depends_on: [taiga-db, taiga-async-rabbitmq]
    restart: unless-stopped

  taiga-manage:
    image: taigaio/taiga-back:latest
    entrypoint: ["/taiga-back/docker/manage_entrypoint.sh"]
    environment: *back-env
    volumes: *back-volumes
    profiles: ["manage"]

  taiga-events:
    image: taigaio/taiga-events:latest
    environment:
      RABBITMQ_USER: ${RABBITMQ_USER}
      RABBITMQ_PASS: ${RABBITMQ_PASS}
      TAIGA_SECRET_KEY: ${TAIGA_SECRET_KEY}
    depends_on: [taiga-events-rabbitmq]
    restart: unless-stopped

  taiga-protected:
    image: taigaio/taiga-protected:latest
    environment:
      MAX_AGE: 360
      SECRET_KEY: ${TAIGA_SECRET_KEY}
    restart: unless-stopped

  taiga-front:
    image: taigaio/taiga-front:latest
    environment:
      TAIGA_URL: "${TAIGA_SCHEME}://${TAIGA_DOMAIN}"
      TAIGA_WEBSOCKETS_URL: "${WEBSOCKETS_SCHEME}://${TAIGA_DOMAIN}"
      TAIGA_SUBPATH: ${SUBPATH}
    restart: unless-stopped

  taiga-gateway:
    image: nginx:1.27-alpine
    ports: ["8080:80"]
    volumes:
      - ./taiga-gateway.conf:/etc/nginx/conf.d/default.conf:ro
      - ./taiga-static:/taiga/static
      - ./taiga-media:/taiga/media
    depends_on: [taiga-back, taiga-front, taiga-events, taiga-protected]
    restart: unless-stopped

Отдельная секция networks не нужна — compose создаёт общую сеть по умолчанию, и сервисы файла видят друг друга по имени. Наружу торчит только порт 8080:80 у taiga-gateway — на него внешний nginx/Traefik и проксирует HTTPS-трафик. Конфиг taiga-gateway.conf (склейка /api, /events, /media на разные upstream) в минимальном виде можно взять из официального репозитория kaleidos-ventures/taiga-docker — переизобретать его с нуля смысла нет, там нет ничего специфичного для конкретного хостинга.

Запуск, миграции и создание администратора

Когда .env, docker-compose.yml и конфиг gateway на месте:

docker compose up -d

Первый запуск поднимет все сервисы, но база данных будет пустой — нужно прогнать миграции и создать администратора через служебный контейнер taiga-manage:

docker compose --profile manage run --rm taiga-manage migrate
docker compose --profile manage run --rm taiga-manage createsuperuser
docker compose --profile manage run --rm taiga-manage loaddata initial_user
docker compose --profile manage run --rm taiga-manage loaddata initial_project_templates

Первая команда — миграции схемы Postgres, вторая — интерактивное создание администратора (спросит логин, e-mail, пароль), третья и четвёртая — базовые фикстуры (демо-пользователь и шаблоны Scrum/Kanban), без них список шаблонов при создании проекта будет пустым.

Если что-то не поднялось, смотрите статус и логи backend: docker compose ps и docker compose logs -f taiga-back. Частая причина падения taiga-back на первом старте — Postgres ещё не готов принимать соединения; Docker сам перезапустит контейнер по политике restart: unless-stopped, обычно достаточно подождать 10-15 секунд и перезапустить вручную: docker compose restart taiga-back.

HTTPS, бэкапы и обновление

Taiga сама TLS не терминирует — этим занимается внешний обратный прокси. Если на сервере ещё нет nginx с сертификатами, разверните его по инструкции Let's Encrypt SSL на VPS и добавьте виртуальный хост, проксирующий на 127.0.0.1:8080 (порт taiga-gateway):

server {
    listen 443 ssl http2;
    server_name taiga.example.com;

    ssl_certificate     /etc/letsencrypt/live/taiga.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/taiga.example.com/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    location /events {
        proxy_pass http://127.0.0.1:8080;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

Блок /events нужен для вебсокетов — без правильного апгрейда соединения realtime-обновления доски (карточка коллеги двигается у вас без перезагрузки страницы) работать не будут, хотя остальной интерфейс будет выглядеть исправным.

Бэкап сводится к двум вещам: дамп базы и файлы вложений.

# дамп Postgres
docker compose exec -T taiga-db pg_dump -U taiga taiga | gzip > taiga-db-$(date +%F).sql.gz

# архив медиа и статики
tar czf taiga-media-$(date +%F).tar.gz taiga-media taiga-static

Общий подход к регулярному резервному копированию Docker-томов — в статье бэкап Docker volume на VPS, логику оттуда несложно применить к папкам taiga-db/taiga-media.

Обновление — стандартное: docker compose pull && docker compose up -d, затем повторно прогнать migrate через taiga-manage (если менять нечего, команда завершится мгновенно без ошибок). Перед обновлением на проде снимите свежий бэкап — откат миграций Django назад не всегда тривиален.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Можно ли обойтись без RabbitMQ, чтобы упростить стек?

Async-очередь формально заменяется синхронным режимом для теста, но taiga-events без брокера не заработает — для рабочей установки проще оставить оба RabbitMQ как есть, ресурсов они едят немного.

Работает ли Taiga без домена, по IP-адресу?

Нет — конфигурация жёстко завязана на TAIGA_DOMAIN, без DNS-записи фронтенд будет генерировать неверные ссылки на API. Заведите хотя бы поддомен и направьте его A-записью на IP сервера.

Как перенести Taiga на другой сервер?

Остановите стек (docker compose down), скопируйте папки taiga-db, taiga-media, taiga-static и файлы .env/docker-compose.yml, поднимите docker compose up -d — данные подхватятся автоматически, миграции повторно гонять не нужно.

Почему не приходят письма-приглашения участникам?

Проверьте блок EMAIL_* в .env — частая ошибка — обычный пароль от ящика вместо пароля приложения у провайдеров с обязательной двухфакторной аутентификацией (Gmail, Яндекс.Почта для бизнеса).

Сколько ОЗУ реально ест Taiga при 20+ активных пользователях?

Зависит от интенсивности вебсокетов и сессий — точных цифр без замеров на вашем сценарии не даст никто; ориентируйтесь на 4-6 ГБ как стартовую точку и смотрите docker stats в первую неделю.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →