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

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

MAATRIX

Trello хорош, пока команда маленькая и не против того, что все доски и карточки лежат на чужих серверах в США. Как только заходит речь о корпоративных данных, лимитах бесплатного плана или банальном «а что если Trello поднимет цены» — начинаются поиски self-hosted альтернативы. Wekan закрывает этот запрос: тот же визуальный язык, что и в Trello, но код открыт, данные — на вашем сервере, а карточек можно заводить сколько угодно. Ниже — рабочий docker-compose.yml, с которым Wekan поднимается на VPS за один заход, и разбор нюансов, которые на голом файле не видны.

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

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

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

Чем Wekan отличается от Trello и похожих досок

Wekan — открытый проект (MIT-лицензия), написанный на Meteor.js с MongoDB в качестве хранилища. Внешне интерфейс узнаваем сразу: доски, списки, карточки, drag&drop между колонками — если команда привыкла к Trello, переучиваться почти не придётся.

Ключевые отличия от оригинала:

TrelloWekan
Где хранятся данныесерверы Atlassianваш сервер
Лимит бесплатных досок10 на рабочее пространствоне ограничено
WIP-лимиты на спискитолько в Premiumвстроены бесплатно
Кастомные поляPremiumвстроены бесплатно
Webhooks / APIограниченно на бесплатном планеполный REST API без ограничений
Импорт из Trelloштатный импорт JSON-экспорта доски

Из похожих self-hosted решений на рынке есть ещё Planka (более минималистичный интерфейс, тоже MongoDB) и Focalboard (легче по ресурсам, но менее гибкий по автоматизации). Wekan выигрывает у обоих зрелостью проекта: он развивается с 2016 года, у него солидное сообщество и стабильный REST API, что важно, если планируете завязывать доски на внешние скрипты или CI.

Минус тоже стоит назвать честно: Wekan требует MongoDB, а не лёгкую SQLite-базу, и на слабом VPS (1 vCPU / 1 ГБ RAM) вместе с базой он будет ощутимо тяжелее, чем условный Focalboard. Для команды до 15-20 человек хватает 2 vCPU / 2 ГБ RAM с запасом.

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

Структура каталогов на сервере:

/opt/wekan/
├── mongo-data/     # данные MongoDB
├── wekan-data/     # загруженные файлы и вложения
└── docker-compose.yml

Создаём каталоги:

mkdir -p /opt/wekan/{mongo-data,wekan-data}
cd /opt/wekan
nano docker-compose.yml

Сам файл. Wekan официально рекомендует поднимать MongoDB как одноузловой replica set — это не про отказоустойчивость, а про то, что Meteor использует oplog для быстрых live-обновлений интерфейса; без replica set Wekan тоже запустится, но будет чаще опрашивать базу вместо подписки на изменения:

services:
  mongo:
    image: mongo:7
    container_name: wekan-mongo
    restart: unless-stopped
    command: mongod --replSet rs0 --oplogSize 128 --bind_ip_all
    volumes:
      - ./mongo-data:/data/db
    networks:
      - wekan-net

  mongo-init:
    image: mongo:7
    depends_on:
      - mongo
    networks:
      - wekan-net
    entrypoint: >
      bash -c "
        sleep 5;
        mongosh --host mongo --eval 'try { rs.status() } catch (e) { rs.initiate() }'
      "
    restart: "no"

  wekan:
    image: quay.io/wekan/wekan:latest
    container_name: wekan
    restart: unless-stopped
    depends_on:
      - mongo
    environment:
      MONGO_URL: "mongodb://mongo:27017/wekan?replicaSet=rs0"
      ROOT_URL: "http://your-domain.example"
      MAIL_URL: ""
      WITH_API: "true"
      WRITABLE_PATH: "/data"
      PORT: "8080"
      BROWSER_POLICY_ENABLED: "true"
    volumes:
      - ./wekan-data:/data
    ports:
      - "127.0.0.1:8080:8080"
    networks:
      - wekan-net

networks:
  wekan-net:
    driver: bridge

Обратите внимание на два момента, которые чаще всего ломают первый запуск:

  • ROOT_URL должен точно совпадать с адресом, по которому пользователи открывают Wekan, включая протокол (http:// или https://). Несовпадение — частая причина, почему drag&drop карточек и live-обновления работают криво: WebSocket-соединение Meteor привязано к этому URL.
  • Порт вынесен на 127.0.0.1:8080, а не наружу — это сделано намеренно, доступ снаружи открываем через реверс-прокси с HTTPS (раздел ниже), напрямую по HTTP отдавать интерфейс с логином/паролем в интернет не стоит.

Контейнер mongo-init запускается один раз, инициализирует replica set и завершается — это нормально, не пересоздавайте его командой restart.

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

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

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

Первый запуск и настройка администратора

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

docker compose up -d
docker compose logs -f wekan

Дождитесь в логах строки вида Wekan started — обычно 15-30 секунд после инициализации replica set. Проверить, что MongoDB подняла реплику, можно так:

docker exec -it wekan-mongo mongosh --eval "rs.status().ok"

Значение 1 означает, что replica set работает.

Дальше открываем http://<IP-сервера>:8080 (или сразу домен, если реверс-прокси уже настроен) и регистрируем первого пользователя. Важный нюанс: первый зарегистрированный пользователь в Wekan не становится администратором автоматически, как это принято в некоторых других self-hosted инструментах. Права нужно выдать вручную через MongoDB:

docker exec -it wekan-mongo mongosh wekan --eval '
  db.users.updateOne(
    { "username": "ваш_логин" },
    { $set: { "isAdmin": true } }
  )
'

После этого в интерфейсе появляется раздел администрирования, где можно:

  • запретить публичную регистрацию (Admin Panel → Settings → Registration) — иначе доски сможет создать кто угодно, кто найдёт адрес сервера;
  • настроить SMTP для приглашений и уведомлений через MAIL_URL в формате smtp://user:password@smtp.example.com:587;
  • включить LDAP/OIDC-авторизацию, если в компании уже есть единый каталог пользователей — Wekan поддерживает оба варианта из коробки, конфигурация задаётся дополнительными переменными окружения (LDAP_ENABLE, OIDC_ENABLED и т.д. — их десятки, полный список стоит смотреть в документации проекта под конкретную версию).

HTTPS и доступ извне через реверс-прокси

Отдавать Wekan напрямую по HTTP наружу не вариант — логин с паролем и токены сессии будут ходить в открытом виде. Проще всего закрыть это связкой с Caddy, который сам выпускает и продлевает сертификат Let's Encrypt:

# /etc/caddy/Caddyfile
wekan.your-domain.example {
    reverse_proxy 127.0.0.1:8080
}

Если Caddy на сервере ещё не настроен, разберитесь в статье про установку Caddy с авто-SSL на VPS — там же описаны нюансы с открытием портов 80/443.

После того как домен заработал по HTTPS, обязательно поправьте ROOT_URL в docker-compose.yml на https://wekan.your-domain.example и пересоздайте контейнер:

docker compose up -d --force-recreate wekan

Без этого шага WebSocket-соединение будет пытаться подключиться к старому http:// адресу, и интерфейс начнёт заметно тормозить — карточки двигаются, но доска не обновляется у других участников в реальном времени, пока не обновишь страницу вручную.

Доски, WIP-лимиты и автоматизация

С точки зрения повседневной работы у Wekan есть несколько вещей, которых в бесплатном Trello просто нет:

  • Свимлейны (горизонтальные дорожки) — можно делить доску не только по колонкам, но и по строкам, например по приоритету или по спринту.
  • WIP-лимиты — на каждый список можно выставить максимум карточек одновременно; при превышении список подсвечивается красным. Настраивается кликом по заголовку списка → Set WIP Limit.
  • Кастомные поля — числа, даты, выпадающие списки, чекбоксы; поле можно привязать к конкретной доске или ко всем доскам сразу.
  • Шаблоны чек-листов — если у команды повторяющийся процесс (ревью кода, релиз, онбординг), шаблон чек-листа накидывается на новую карточку одним кликом, а не набирается заново.

Из Trello доски переносятся штатным способом: Меню доски в Trello → Показать меню → Печать и экспорт → Экспорт JSON, затем в Wekan Admin Panel → Import (или через кнопку импорта на экране создания доски) — карточки, списки, метки и участники (по совпадению email) переносятся автоматически.

Для автоматизации есть два независимых механизма:

  1. Исходящие вебхуки — доска может слать POST-запрос на внешний URL при любом действии (перемещение карточки, комментарий, смена метки). Настраивается в Admin Panel → Webhooks, полезно для интеграции с Mattermost, Slack-совместимым чатом или собственным ботом.
  2. REST API (включён переменной WITH_API=true в файле выше) — полный CRUD по доскам, спискам, карточкам. Пример создания карточки скриптом:
curl -X POST "https://wekan.your-domain.example/api/boards/<boardId>/lists/<listId>/cards" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"title": "Новая задача", "description": "Создана скриптом"}'

Токен получаете через POST /users/login с логином и паролем — подробности эндпоинтов в официальной документации API проекта, она поставляется вместе с исходниками.

Резервное копирование и обновление

Данные Wekan живут в двух местах: MongoDB (доски, карточки, пользователи) и каталог wekan-data (вложенные файлы). Бэкапить нужно оба.

Ручной дамп MongoDB:

docker exec wekan-mongo mongodump --db wekan --archive=/data/db/wekan-$(date +%F).archive
docker cp wekan-mongo:/data/db/wekan-$(date +%F).archive /opt/wekan/backups/

Восстановление из архива:

docker cp /opt/wekan/backups/wekan-2026-08-15.archive wekan-mongo:/tmp/restore.archive
docker exec wekan-mongo mongorestore --db wekan --archive=/tmp/restore.archive --drop

Каталог вложений копируется обычным tar:

tar czf /opt/wekan/backups/wekan-data-$(date +%F).tar.gz -C /opt/wekan wekan-data

Если на сервере уже настроен регулярный бэкап других сервисов, логичнее не городить отдельный cron-скрипт, а включить оба каталога Wekan в общий пайплайн — например, через restic в Docker Compose, направив снапшоты на /opt/wekan/mongo-data и /opt/wekan/wekan-data.

Обновление — стандартный pull + up, но с оговоркой: перед мажорным обновлением Wekan (смена первой цифры версии) стоит прочитать changelog в репозитории проекта — изредка встречаются миграции схемы MongoDB, которые применяются автоматически при первом запуске новой версии, но откатить их назад без бэкапа уже не получится.

docker compose pull wekan
docker compose up -d wekan

Если планируете вообще переносить весь стек на другой сервер (например, при апгрейде тарифа), общий порядок действий с volumes и docker compose описан в статье про перенос Docker-проекта на другой сервер — для Wekan он ничем не отличается от переноса любого другого стека с MongoDB внутри.

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

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

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

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

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

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

Wekan можно связать с MongoDB, вынесенной на отдельный сервер, а не в том же Compose-стеке?

Да, достаточно указать в MONGO_URL адрес внешней базы вместо mongo:27017. Если база тоже собственная, посмотрите статью про установку и настройку MongoDB на VPS — там же про включение authentication, которое стоит добавить, если MongoDB смотрит не только в приватную docker-сеть.

Почему доска не обновляется у коллег в реальном времени, хотя всё вроде работает?

В 90% случаев это ROOT_URL, не совпадающий с реальным адресом, по которому открыт Wekan (см. раздел про HTTPS выше), либо реверс-прокси не пробрасывает WebSocket-заголовки Upgrade/Connection — для Caddy это не требует ручной настройки, а вот в nginx нужно явно прописывать proxy_set_header Upgrade $http_upgrade;.

Можно ли запустить Wekan вообще без replica set MongoDB?

Технически да — уберите --replSet rs0 из команды и ?replicaSet=rs0 из MONGO_URL, интерфейс запустится. Но живые обновления начнут работать через периодический опрос вместо подписки на oplog, что на активных досках заметно на глаз (обновление раз в несколько секунд вместо мгновенного).

Сколько ресурсов реально нужно для команды из 10 человек?

Ориентировочно 2 vCPU и 2 ГБ RAM с запасом покрывают такую нагрузку вместе с MongoDB — но это именно ориентир, а не измеренное значение: реальное потребление зависит от числа досок, вложений и активности одновременных пользователей.

Как перенести доски обратно из Wekan в Trello, если решение не подошло?

Штатного экспорта в формат Trello нет, но REST API отдаёт полный дамп доски в JSON, который можно преобразовать скриптом под структуру Trello-импорта — трудозатратно, но данные не заперты намертво внутри Wekan.

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

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

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