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

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

MAATRIX

Когда команда вырастает за десяток человек, а задачи ведутся в смеси из Trello, Google Sheets и переписки в чате, начинается хаос: непонятно, кто чем занят, сроки съезжают, а руководителю нечего показать на планёрке кроме "вроде работаем". OpenProject закрывает этот разрыв — это зрелая open-source система управления проектами с диаграммами Ганта, бэклогом в духе Scrum, трекером задач, вики и учётом времени, которую можно развернуть на своём сервере и не платить за место в команде. Ниже — рабочий docker-compose.yml, переменные окружения и разбор мест, где self-host отличается от SaaS-версии на openproject.org.

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

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

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

Что такое OpenProject и кому он подходит

OpenProject — это открытый (community edition под GPL) аналог Jira и MS Project, написанный на Ruby on Rails. В отличие от лёгких канбан-досок вроде Wekan или Focalboard, у него есть то, что обычно ищут в крупных командах и на подрядах с фиксированными дедлайнами:

  • диаграммы Ганта с зависимостями задач и критическим путём;
  • бэклог продукта и спринты в стиле Scrum/Agile;
  • иерархия work packages (эпик → фича → задача → баг) с кастомными полями;
  • вики проекта, учёт времени и бюджета, роли и права по проектам;
  • REST API и интеграция с BIM-инструментами (это у OpenProject исторически сильная сторона — используется в строительной отрасли).

Если вам достаточно простой канбан-доски на 3-5 человек — присмотритесь к Wekan или Focalboard, они легче и быстрее ставятся. OpenProject имеет смысл, когда нужен именно Гантт с зависимостями, учёт времени и бюджета, или когда команда переросла 15-20 человек и без чёткой иерархии проектов начинается путаница.

Минус self-host у любого такого инструмента один и тот же: обновления, бэкапы и SSL — теперь ваша забота, а не забота вендора. Взамен — данные проекта (включая, возможно, коммерческую тайну по срокам и бюджетам клиента) не покидают ваш сервер, и нет лимита на число пользователей или проектов, за который в облаке просят доплату.

Требования к серверу

OpenProject — Rails-приложение с полноценной базой PostgreSQL, Memcached для кэша и фоновыми воркерами (Sidekiq или delayed_job) для писем и импорта. Это не Wekan на Node.js — по ресурсам он ощутимо тяжелее.

СценарийRAMCPUДиск
Тест / команда до 10 человек4 ГБ2 ядра20 ГБ SSD
Рабочая команда 10-40 человек6-8 ГБ4 ядра40 ГБ SSD
Крупная команда, много вложений/BIM16 ГБ+4-8 ядер80 ГБ+ NVMe

Цифры ориентировочные — конкретное потребление зависит от числа одновременных пользователей, размера вложений (скриншоты, BIM-модели) и глубины истории задач. На старте разумно брать VPS с 4 ГБ RAM и следить за docker stats первую неделю — если память упирается в лимит, апгрейд тарифа без даунтайма занимает пару минут.

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

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

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

Готовый docker-compose.yml

Официальный образ openproject/openproject — так называемый all-in-one контейнер: внутри уже упакованы Postgres, Memcached, веб-сервер, worker и cron. Это самый простой способ поднять инстанс на одном VPS без десятка отдельных сервисов в compose-файле. Создайте директорию проекта и файл docker-compose.yml:

services:
  openproject:
    image: openproject/openproject:15
    restart: unless-stopped
    ports:
      - "8080:80"
    environment:
      OPENPROJECT_HTTPS: "false"
      OPENPROJECT_HOST__NAME: "project.example.com"
      OPENPROJECT_DEFAULT__LANGUAGE: "ru"
      OPENPROJECT_SECRET_KEY_BASE: "${SECRET_KEY_BASE}"
      OPENPROJECT_RAILS__RELATIVE__URL__ROOT: ""
      OPENPROJECT_EMAIL__DELIVERY__METHOD: "smtp"
      OPENPROJECT_SMTP__ADDRESS: "smtp.example.com"
      OPENPROJECT_SMTP__PORT: "587"
      OPENPROJECT_SMTP__DOMAIN: "example.com"
      OPENPROJECT_SMTP__AUTHENTICATION: "login"
      OPENPROJECT_SMTP__USER__NAME: "no-reply@example.com"
      OPENPROJECT_SMTP__PASSWORD: "${SMTP_PASSWORD}"
      OPENPROJECT_SMTP__ENABLE__STARTTLS__AUTO: "true"
    volumes:
      - opdata:/var/openproject/assets
      - pgdata:/var/openproject/pgdata
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost/health_checks/default"]
      interval: 30s
      timeout: 10s
      retries: 5

volumes:
  opdata:
  pgdata:

Рядом создайте .env с секретами (в compose-файл они не попадают, только имя переменной):

SECRET_KEY_BASE=замените_на_случайную_строку_64+_символов
SMTP_PASSWORD=пароль_от_почтового_ящика

OPENPROJECT_SECRET_KEY_BASE генерируется один раз и не должен меняться после первого запуска — иначе слетят сессии и зашифрованные данные в БД. Сгенерировать длинную случайную строку проще всего так:

openssl rand -hex 64

Тег образа стоит проверить перед установкой на странице openproject/openproject в Docker Hub — фиксируйте конкретную мажорную версию (например, :15, а не :latest), чтобы обновление происходило осознанно, а не при случайном docker compose pull.

Если проект растёт и одного контейнера мало, у OpenProject есть и "разложенный" docker-compose (отдельные сервисы db, cache, web, worker, cron, proxy) в официальном репозитории opf/openproject-docker-compose на GitHub — он даёт больше контроля над масштабированием worker'ов отдельно от веб-процесса, но и администрировать его сложнее. Для одного VPS all-in-one образ — разумный компромисс между простотой и надёжностью.

Первый запуск и вход

Поднимаем стек:

docker compose up -d
docker compose logs -f openproject

Первый старт занимает несколько минут — контейнер инициализирует базу, накатывает миграции и сидирует демо-данные. Дождитесь в логах строки о готовности Puma (веб-сервера) и только потом открывайте адрес.

Заходим по http://ваш-ip:8080 (или по домену, если уже настроен прокси). Стандартные учётные данные при первом входе:

Логин:  admin
Пароль: admin

Система сразу потребует сменить пароль — это ожидаемо, пропустить нельзя. После входа зайдите в Administration → Users и удалите или отключите демо-пользователей, если планируете реальную работу, а не тестовый прогон. В Administration → System settings → General сразу выставьте часовой пояс по умолчанию и формат даты — если этого не сделать в начале, потом придётся править задним числом даты во всех задачах.

Домен, HTTPS и почта

Открывать проект-менеджер по IP и HTTP — плохая идея даже для внутреннего использования: логин и пароль будут идти в открытом виде. Проще всего поставить перед OpenProject nginx как реверс-прокси с Let's Encrypt — подробный пошаговый процесс описан в статье про настройку nginx как reverse proxy на VPS и в отдельном разборе установки Let's Encrypt SSL. Общая схема: nginx слушает 443 снаружи и проксирует на 127.0.0.1:8080, где живёт контейнер OpenProject. После того как домен и HTTPS настроены, не забудьте переключить в compose-файле:

OPENPROJECT_HTTPS: "true"

иначе OpenProject будет генерировать ссылки в письмах и API с http://, и часть функций (например, встроенный превью вложений) может некорректно работать за прокси с завершением TLS.

Почта критична не для галочки: OpenProject шлёт уведомления о новых задачах, комментариях и упоминаниях, приглашения новых участников и сброс пароля. Без рабочего SMTP команда либо не узнаёт о новых задачах вовремя, либо вы вручную рассылаете ссылки в мессенджере, теряя весь смысл системы уведомлений. Переменные OPENPROJECT_SMTP__* в примере выше — это как раз базовая настройка через любой SMTP-провайдер (свой почтовый сервер, Yandex 360, SendGrid и подобные — синтаксис одинаковый, меняются только адрес, порт и учётные данные).

Бэкап, восстановление и обновление версии

В all-in-one образе база PostgreSQL хранится внутри volume pgdata, а вложения (файлы задач, аватары, логотип) — в opdata. Бэкап нужен для обоих томов, база и файлы должны сохраняться синхронно, иначе после восстановления в задачах будут "битые" ссылки на вложения. Ручной бэкап через docker exec:

# дамп базы
docker compose exec openproject sh -c \
  "pg_dump -U openproject -h localhost openproject" > openproject_db_$(date +%F).sql

# архив вложений
docker run --rm -v openproject_opdata:/data -v $(pwd):/backup alpine \
  tar czf /backup/openproject_assets_$(date +%F).tar.gz -C /data .

Восстановление — в обратном порядке: сначала поднять пустой контейнер, залить дамп через psql, распаковать архив вложений в volume, перезапустить сервис. Для регулярных автоматических бэкапов Docker-томов (с ротацией и выгрузкой во внешнее хранилище) в блоге есть отдельный разбор — бэкап Docker volume на VPS, схема применима и к pgdata/opdata OpenProject один в один.

Обновление версии — это смена тега образа плюс пересоздание контейнера:

# в docker-compose.yml меняем :15 на нужный тег
docker compose pull
docker compose up -d

При старте контейнер сам применит миграции базы под новую версию — но перед мажорным обновлением (например, с 14.x на 15.x) обязательно снимите свежий бэкап и прочитайте changelog на сайте OpenProject: мажорные релизы иногда меняют формат конфигурации или требуют ручных шагов.

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

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

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

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

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

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

Чем OpenProject отличается от Plane или Taiga?

OpenProject тяжелее по ресурсам, но сильнее в классическом проектном управлении — диаграммы Ганта с зависимостями, бюджеты, учёт времени, BIM-интеграция. Plane и Taiga ближе к Agile-трекерам задач в стиле Linear/Jira — легче ставятся, но без полноценного Ганта и бюджетирования из коробки.

Можно ли работать без SMTP, только через интерфейс?

Технически да, но тогда участники не получат уведомлений о задачах и приглашений по почте — это резко снижает пользу от системы для команды больше 3-4 человек.

Нужен ли отдельный сервер для базы данных?

Для команды до 40-50 человек all-in-one образ с базой в том же контейнере справляется без проблем. Вынос PostgreSQL в отдельный сервис имеет смысл, если вы уже используете общий кластер БД для нескольких приложений или хотите реплику для отказоустойчивости.

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

Тот же принцип, что и для любого Docker-проекта — снять volumes и docker-compose.yml, поднять на новом сервере, восстановить дамп базы. Общий алгоритм переезда описан в статье про перенос Docker-проекта на другой сервер.

Что делать, если контейнер падает сразу после старта?

Чаще всего причина — нехватка памяти на инициализацию базы (нужно от 4 ГБ) или отсутствующий OPENPROJECT_SECRET_KEY_BASE. Смотрите docker compose logs openproject — там обычно явно указана причина падения.

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

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

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