MAATRIX / Блог / Бэкап и восстановление Wekan

Бэкап и восстановление Wekan

MAATRIX

Wekan — удобная канбан-доска в духе Trello, но self-hosted и без привязки к чужому облаку: карточки, чек-листы, вложения и вся история команды живут на вашем сервере. Обратная сторона такой независимости — если сервер выйдет из строя без бэкапа, вы теряете не абстрактную подписку, а реальные рабочие доски со всей историей задач. Ниже — рабочая схема бэкапа и восстановления Wekan для типичной установки на Docker Compose.

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

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

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

Что нужно бэкапить в Wekan

Wekan построен на Meteor и хранит всё состояние в MongoDB — это отправная точка любого бэкапа. Но помимо самой базы есть ещё несколько мест, про которые часто забывают:

  • База MongoDB — доски, списки, карточки, чек-листы, комментарии, метки, пользователи, права доступа, настройки уведомлений. Без этого восстановление в принципе невозможно.
  • Вложения и аватары — файлы, которые пользователи прикрепляют к карточкам, и аватарки профилей. Способ хранения зависит от конфигурации: по умолчанию Wekan пишет файлы прямо в MongoDB (пакет ostrio:files использует чанкованное хранение, похожее на классический GridFS), но в docker-compose часто задают переменную WRITABLE_PATH, чтобы файлы лежали на диске отдельным томом, либо настраивают S3-совместимое хранилище через переменные S3*. Проверьте свой docker-compose.yml — от этого зависит, что именно копировать помимо базы.
  • Переменные окружения и docker-compose.ymlMONGO_URL, ROOT_URL, MAIL_URL, WITH_API, настройки OIDC/LDAP, если подключены. Без них поднятый из бэкапа контейнер просто не будет знать, как подключиться к базе и как себя показывать наружу.
  • Кастомные фоны досок и правила автоматизации — физически лежат там же, где вложения (в базе, на диске или в S3), отдельно бэкапить не нужно, если общий бэкап настроен верно.

Если у вас файлы прикреплений хранятся в базе (дефолтный сценарий для небольших и средних команд) — обычный дамп MongoDB закрывает почти всё. Если вынесены на диск или в S3 — потребуется отдельный шаг, разберём его дальше.

Бэкап MongoDB: mongodump без сюрпризов

Найдите имя контейнера с базой — в типовом compose-файле Wekan это что-то вроде wekan-db или wekandb:

docker ps --format '{{.Names}}' | grep -i wekan

Дамп снимается штатным mongodump внутри контейнера базы:

docker exec wekan-db mongodump \
  --db=wekan \
  --gzip --archive=/tmp/wekan-$(date +%F).gz

docker cp wekan-db:/tmp/wekan-$(date +%F).gz \
  /opt/backups/wekan/

Флаг --archive вместе с --gzip даёт один компактный файл вместо дерева BSON-документов — проще переносить, проще хранить версии. Имя базы wekan — значение по умолчанию, но если в MONGO_URL у вас указано другое имя базы данных, используйте его.

В отличие от некоторых Meteor-приложений, которые жёстко требуют replica set (например, Rocket.Chat из-за change streams), Wekan штатно работает и на одиночном инстансе MongoDB — Meteor в этом случае просто использует poll-and-diff вместо oplog tailing. Реплика-сет с MONGO_OPLOG_URL в компоузе Wekan — это опциональная оптимизация под нагрузку, а не обязательное условие для бэкапа: mongodump работает одинаково в обоих случаях.

Для базы, в которую активно пишут (много команд, много карточек в работе одновременно), полезно снимать дамп в часы минимальной активности — ночью или рано утром, чтобы не ловить блокировки на крупных коллекциях.

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

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

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

Бэкап вложений: база, файловая система или S3

Если файлы хранятся в MongoDB (дефолт без WRITABLE_PATH и без S3-переменных) — они уже попали в дамп выше, отдельно ничего копировать не нужно. Это самый простой вариант с точки зрения консистентности: файл и запись о нём в базе снимаются одной командой одновременно. Минус — база пухнет вместе с ростом количества вложений, и на больших объёмах дамп становится тяжелее и дольше снимается.

Если задан WRITABLE_PATH — файлы лежат на диске отдельным томом (обычно смонтированным как /data внутри контейнера Wekan). Бэкапьте его синхронно с дампом базы:

docker cp wekan:/data /opt/backups/wekan/data-$(date +%F)

Или, если это именованный docker-том, а не bind-mount, проще архивировать через временный контейнер:

docker run --rm -v wekan_wekan-files:/data -v /opt/backups/wekan:/backup \
  alpine tar czf /backup/wekan-files-$(date +%F).tar.gz -C /data .

Название тома (wekan_wekan-files в примере) зависит от вашего compose-файла — уточните его через docker volume ls.

Если настроено S3-совместимое хранилище — сам Wekan файлы не хранит, их сохранность обеспечивает бакет. Бэкапить в этом случае нужно только конфиг с ключами доступа, а бэкап самого объектного хранилища — отдельная задача. Для self-hosted MinIO она разобрана в статье про бэкап и восстановление MinIO.

Ключевое правило независимо от способа хранения: бэкап базы и бэкап файлов должны сниматься в рамках одного скрипта, без большого разрыва по времени. Иначе после восстановления возможна ситуация, когда в карточке есть запись о вложении, а самого файла на новом сервере уже нет.

Автоматизация: скрипт и cron

Ручной бэкап неизбежно забывается в самый неудачный момент. Собираем всё в один bash-скрипт, который снимает дамп базы, файлы (если они не в базе) и конфиг, упаковывает и отправляет за пределы сервера:

#!/bin/bash
set -euo pipefail

DATE=$(date +%F)
BACKUP_DIR="/opt/backups/wekan"
mkdir -p "$BACKUP_DIR"

docker exec wekan-db mongodump \
  --db=wekan --gzip --archive=/tmp/wekan-mongo-$DATE.gz
docker cp wekan-db:/tmp/wekan-mongo-$DATE.gz "$BACKUP_DIR/"

# только если WRITABLE_PATH указывает на диск, а не хранение файлов в базе
docker cp wekan:/data "$BACKUP_DIR/data-$DATE" 2>/dev/null || true

cp docker-compose.yml .env "$BACKUP_DIR/" 2>/dev/null || true

tar czf "$BACKUP_DIR/wekan-full-$DATE.tar.gz" \
  -C "$BACKUP_DIR" "wekan-mongo-$DATE.gz" "data-$DATE" docker-compose.yml .env

rclone copy "$BACKUP_DIR/wekan-full-$DATE.tar.gz" remote:wekan-backups/

find "$BACKUP_DIR" -mtime +7 -delete

Добавляем в cron:

0 3 * * * /opt/scripts/backup-wekan.sh >> /var/log/wekan-backup.log 2>&1

Если предпочитаете инструмент с дедупликацией и шифрованием вместо простого tar + rclone — дамп MongoDB и папку с вложениями можно точно так же завернуть в restic, это избавит от ручной ротации старых копий и добавит шифрование "из коробки". Для самой базы MongoDB как таковой, вне контекста Wekan, есть отдельный разбор типичных проблем в статье про бэкап MongoDB на сервере.

Классическое правило трёх копий тут работает так же, как и для любого другого сервиса: локальная копия для быстрого отката, копия на другом сервере или в объектном хранилище на случай проблем с диском, и хотя бы одна копия в другой локации на случай проблем с самим хостером. Про подбор площадки под архивные копии подробнее — в статье про VPS для бэкапов и архива.

Восстановление Wekan из бэкапа

Разворачиваем чистый Wekan + MongoDB тем же docker-compose.yml из бэкапа и дожидаемся, пока контейнеры поднимутся:

docker compose up -d wekandb

Останавливаем сам Wekan, чтобы он не писал в базу поверх восстанавливаемых данных:

docker compose stop wekan

Восстанавливаем дамп:

docker cp wekan-mongo-2026-08-28.gz wekan-db:/tmp/restore.gz
docker exec wekan-db mongorestore \
  --db=wekan --gzip --archive=/tmp/restore.gz --drop

Флаг --drop пересоздаёт коллекции перед восстановлением — без него в свежей инсталляции может остаться "мусор" от первого запуска (дефолтные настройки, тестовый пользователь), перемешанный с восстановленными данными.

Если файлы хранились отдельно на диске — возвращаем их на место до старта сервиса:

docker cp data-2026-08-28/. wekan:/data/

Запускаем Wekan и смотрим логи:

docker compose start wekan
docker compose logs -f wekan

Первый запуск после restore может занять чуть больше времени обычного — Meteor пересобирает индексы. Зайдите в интерфейс, откройте несколько досок и проверьте, что вложения открываются, а не только что доски видны в списке — это единственный надёжный способ убедиться, что восстановление прошло без потерь.

Частые проблемы при восстановлении

  • Wekan запускается, но доски пустые. Чаще всего значит, что дамп восстановился в другую базу данных (проверьте, совпадает ли имя базы в mongorestore --db= с тем, что указано в MONGO_URL контейнера Wekan) или mongorestore отработал без флага --drop поверх уже существующих пустых коллекций с другим _id.
  • Карточки на месте, а вложения не открываются. Классическая рассинхронизация бэкапа базы и бэкапа файлов на диске по времени, либо файлы просто не были скопированы, если хранение настроено через WRITABLE_PATH, а бэкапился только дамп MongoDB. Решение — снимать оба бэкапа в одном скрипте, как показано выше.
  • После восстановления не работает вход через LDAP/OIDC. Если конфигурация авторизации хранится в переменных окружения нового контейнера, а не мигрировала вместе с базой, проверьте, что .env и docker-compose.yml восстановлены и совпадают с оригиналом, а не собраны заново вручную "по памяти".
  • mongorestore падает с ошибкой дублирующихся ключей. Обычно означает, что восстановление запущено на базе, которая уже содержит данные (например, повторный запуск скрипта деплоя создал начальные документы). Используйте --drop или восстанавливайте в полностью чистый инстанс MongoDB.

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

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

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

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

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

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

Можно ли бэкапить Wekan без остановки сервиса?

Да, mongodump штатно снимается на живой базе без остановки Wekan — это обычный сценарий для регулярного cron-бэкапа. Останавливать сервис нужно только на время restore, чтобы он не писал поверх восстанавливаемых данных.

Как узнать, где именно хранятся вложения на моей установке?

Посмотрите переменные окружения контейнера Wekan (docker exec wekan env | grep -E 'WRITABLE_PATH|S3'). Если ни WRITABLE_PATH, ни S3-переменные не заданы — файлы хранятся в MongoDB, и обычного дампа базы достаточно.

Нужен ли отдельный сервер под MongoDB для Wekan?

Для команды до нескольких десятков человек MongoDB и Wekan спокойно живут на одном VPS в связке через Docker Compose. Отдельный сервер имеет смысл, когда база разрастается настолько, что начинает конкурировать с самим приложением за ресурсы, либо когда нужен полноценный replica set для отказоустойчивости.

Чем бэкап Wekan отличается от бэкапа других канбан-инструментов на MongoDB?

Принципиально — почти ничем: логика "дамп базы + файлы + конфиг" универсальна для всех Meteor-приложений на MongoDB. Разница в мелочах — переменных окружения, именах томов и о том, требует ли конкретное приложение обязательный replica set (Wekan — не требует, в отличие, например, от Rocket.Chat).

Стоит ли переносить вложения в S3 при росте базы?

Если база заметно раздулась из-за вложений и дамп стал долгим и тяжёлым — да, вынос файлов в S3-совместимое хранилище (свой MinIO или внешний провайдер) разгружает MongoDB и ускоряет и бэкап, и восстановление, поскольку дамп базы становится в разы легче.

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

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

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