Vikunja в Docker Compose: готовый файл
Если вы устали от Todoist с ограничениями бесплатного тарифа или не хотите держать рабочие списки задач на чужом сервере — Vikunja решает обе проблемы. Это лёгкий self-hosted менеджер задач со списками, метками, напоминаниями и Kanban-досками, который поднимается одним docker compose up и не требует вечной подписки. Ниже — рабочий compose-файл, разбор переменных окружения и то, что обычно упускают при первом запуске: HTTPS, бэкапы и обновления.
Содержание
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Что такое Vikunja и зачем она нужна
Vikunja — open-source альтернатива Todoist, Things и Microsoft To Do. Из коробки есть:
- списки задач с подзадачами, дедлайнами и повторами;
- метки (labels) и приоритеты;
- Kanban-доски и представление в виде таблицы/Ганта;
- напоминания и уведомления по email;
- общие проекты и права доступа для команды;
- мобильные приложения и веб-интерфейс, плюс REST API для интеграций.
По ощущениям это ближе к личному и небольшому командному таск-менеджеру, а не к полноценной системе управления проектами вроде Jira. Если нужна доска в духе Trello без задач-списков — присмотритесь к Wekan или Focalboard; они устроены проще и заточены именно под канбан.
Ресурсы Vikunja просит скромные: 1 CPU и 512 МБ–1 ГБ RAM хватает с запасом для команды в 5–20 человек. На VPS с 1–2 vCPU и 2 ГБ RAM сервис работает без нагрузки на систему даже вместе с базой данных.
Готовый docker-compose.yml
Актуальная схема развёртывания Vikunja — единый образ vikunja/vikunja, который отдаёт и API, и веб-интерфейс на одном порту (3456). База — PostgreSQL: она надёжнее SQLite при параллельной работе нескольких пользователей и проще в бэкапе, чем MySQL, который Vikunja тоже поддерживает.
Создайте директорию проекта и файл docker-compose.yml:
mkdir -p ~/vikunja/data/{db,files}
cd ~/vikunja
services:
db:
image: postgres:16-alpine
container_name: vikunja-db
restart: unless-stopped
environment:
POSTGRES_USER: vikunja
POSTGRES_PASSWORD: change_me_strong_password
POSTGRES_DB: vikunja
volumes:
- ./data/db:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U vikunja"]
interval: 10s
timeout: 5s
retries: 5
vikunja:
image: vikunja/vikunja:latest
container_name: vikunja
restart: unless-stopped
depends_on:
db:
condition: service_healthy
environment:
VIKUNJA_DATABASE_TYPE: postgres
VIKUNJA_DATABASE_HOST: db
VIKUNJA_DATABASE_USER: vikunja
VIKUNJA_DATABASE_PASSWORD: change_me_strong_password
VIKUNJA_DATABASE_DATABASE: vikunja
VIKUNJA_SERVICE_JWTSECRET: replace_with_random_32char_string
VIKUNJA_SERVICE_FRONTENDURL: "https://tasks.example.com/"
VIKUNJA_SERVICE_ENABLEREGISTRATION: "false"
VIKUNJA_SERVICE_TIMEZONE: "Europe/Moscow"
ports:
- "127.0.0.1:3456:3456"
volumes:
- ./data/files:/app/vikunja/files
Перед запуском обязательно замените change_me_strong_password и VIKUNJA_SERVICE_JWTSECRET — второй параметр подписывает сессионные токены, и генерировать его нужно случайно:
openssl rand -hex 32
Тег latest удобен для первого знакомства, но для продакшена лучше зафиксировать конкретную версию образа (посмотрите актуальный тег на Docker Hub перед деплоем) — так обновления происходят осознанно, а не при каждом docker compose pull.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверПервый запуск и настройка
Поднимите стек и проверьте логи:
docker compose up -d
docker compose logs -f vikunja
Если всё стартовало штатно, API отвечает на http://127.0.0.1:3456/api/v1/info. Порт специально пробрасывается только на localhost — наружу сервис отдаёт reverse-proxy, о нём ниже.
Первого пользователя Vikunja создаёт через веб-интерфейс при регистрации — если оставить VIKUNJA_SERVICE_ENABLEREGISTRATION: "true" на момент первого входа, зарегистрируйтесь сами, затем верните значение в "false" и перезапустите контейнер (docker compose up -d), чтобы закрыть самостоятельную регистрацию для посторонних.
Полезные переменные, которые стоит проверить сразу:
| Переменная | Назначение |
|---|---|
VIKUNJA_SERVICE_FRONTENDURL | должен точно совпадать с итоговым адресом (с https:// и слэшем в конце) — иначе будут проблемы с редиректами и CORS |
VIKUNJA_SERVICE_ENABLEREGISTRATION | false после создания первого аккаунта — иначе может зарегистрироваться кто угодно |
VIKUNJA_MAILER_HOST / VIKUNJA_MAILER_USER | нужны, если хотите email-напоминания и восстановление пароля |
VIKUNJA_SERVICE_MAXITEMSPERPAGE | лимит выдачи в API, если у вас много задач и клиент подтормаживает |
Настройки email через SMTP добавляются отдельным блоком VIKUNJA_MAILER_* в тот же environment: — без них сервис работает, просто не будет писем-напоминаний о дедлайнах.
HTTPS и reverse-proxy
Наружу пускать Vikunja без TLS не стоит — вы вводите пароль и работаете с личными задачами. Проще всего добавить Traefik с автоматическим Let's Encrypt. Если Traefik уже развёрнут на сервере (см. Traefik как reverse-proxy для Docker), достаточно добавить лейблы к сервису vikunja:
vikunja:
# ...остальные настройки как выше
labels:
- "traefik.enable=true"
- "traefik.http.routers.vikunja.rule=Host(`tasks.example.com`)"
- "traefik.http.routers.vikunja.entrypoints=websecure"
- "traefik.http.routers.vikunja.tls.certresolver=letsencrypt"
- "traefik.http.services.vikunja.loadbalancer.server.port=3456"
networks:
- traefik-network
networks:
traefik-network:
external: true
Уберите проброс ports: 3456:3456 наружу — трафик пойдёт через Traefik, а прямой доступ к контейнеру снаружи не нужен.
Если предпочитаете более простую конфигурацию без отдельного docker-сетевого слоя, Caddy с автоматическим SSL — тоже рабочий вариант (см. установку Caddy с авто-SSL на VPS): достаточно одного блока в Caddyfile:
tasks.example.com {
reverse_proxy 127.0.0.1:3456
}
Caddy сам получит и продлит сертификат, дополнительно ничего настраивать не придётся.
Резервное копирование данных
У Vikunja два места, где живут данные: база PostgreSQL (задачи, пользователи, метки) и директория с файлами (вложения к задачам). Бэкапить нужно оба.
Дамп базы:
docker compose exec db pg_dump -U vikunja vikunja | gzip > vikunja_db_$(date +%F).sql.gz
Файлы вложений — это обычная папка на хосте, ./data/files, её достаточно копировать штатным rsync или tar:
tar -czf vikunja_files_$(date +%F).tar.gz ./data/files
Для регулярного автоматического бэкапа с ротацией и шифрованием удобнее не изобретать cron-скрипты вручную, а поднять BorgBackup — там же есть готовый разбор BorgBackup в Docker Compose с шифрованием и дедупликацией, что для вложений (фото, документы) особенно полезно — экономит место при частых бэкапах.
Восстановление в обратную сторону:
gunzip -c vikunja_db_2026-08-20.sql.gz | docker compose exec -T db psql -U vikunja vikunja
tar -xzf vikunja_files_2026-08-20.tar.gz -C ./
Перед восстановлением базы контейнер vikunja лучше остановить (docker compose stop vikunja), чтобы он не писал в базу во время импорта.
Обновление и типичные проблемы
Обновление — стандартная процедура для Compose-стека:
docker compose pull
docker compose up -d
docker compose logs -f vikunja
Перед обновлением на новую мажорную версию сделайте дамп базы — миграции схемы Vikunja применяет автоматически при старте, и откатить их проще из бэкапа, чем вручную.
Частые проблемы, с которыми сталкиваются при первом деплое:
- Белый экран или ошибки CORS в консоли браузера. Обычно причина —
VIKUNJA_SERVICE_FRONTENDURLне совпадает с реальным адресом (например, забыт слэш в конце или указанhttpвместоhttps). Проверьте значение и перезапустите контейнер. - 502/504 от reverse-proxy. Контейнер
vikunjaещё не готов принимать соединения — дайте ему 10-15 секунд после старта, особенно если это первый запуск с применением миграций базы. - Не приходят email-напоминания. Без блока
VIKUNJA_MAILER_*почта просто не настроена — это не баг, а отсутствующая конфигурация. - Не сохраняются вложения после пересоздания контейнера. Проверьте, что volume
./data/filesдействительно смонтирован, а не потерян при правке compose-файла — без явного тома Docker приdownс флагом-vможет удалить анонимный volume вместе с данными.
Для более базовой настройки Docker Compose на сервере — сети, healthchecks, порядок запуска сервисов — пригодится статья про Docker Compose для продакшена, там разобраны общие принципы, которые применимы не только к Vikunja.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Можно ли использовать SQLite вместо PostgreSQL?
Да, Vikunja поддерживает SQLite — достаточно указать VIKUNJA_DATABASE_TYPE: sqlite и путь к файлу базы. Это проще для личного использования на одном пользователе, но при параллельной работе нескольких людей PostgreSQL надёжнее.
Есть ли мобильное приложение?
Да, официальные клиенты для iOS и Android подключаются к вашему серверу по API — в приложении просто укажите адрес вашего инстанса вместо облачного сервиса Vikunja.
Можно ли импортировать задачи из Todoist или Trello?
Да, у Vikunja есть встроенный импорт из нескольких сервисов через раздел настроек — набор поддерживаемых источников меняется от версии к версии, проверьте актуальный список в вашем инстансе.
Сколько нужно ресурсов сервера для команды из 10-15 человек?
Как правило хватает 1-2 vCPU и 2 ГБ RAM с запасом — сама Vikunja лёгкая, основное потребление даёт PostgreSQL при активной работе.
Нужен ли отдельный домен под Vikunja?
Необязательно — можно использовать поддомен (tasks.example.com) на том же сервере, где крутятся другие self-hosted сервисы, если у каждого свой reverse-proxy маршрут.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →