DevOps и Docker 12 мин чтения 2026-10-05

Организация задач и канбан-досок в Vikunja: развертывание на VDS в Docker Compose с CalDAV и интеграцией в календарь

Пошаговое руководство по установке Vikunja в Docker Compose: легкий таск-менеджер на Go и Vue 3 с базой PostgreSQL, Nginx Reverse Proxy, SSL, канбан-досками и нативной синхронизацией по CalDAV со смартфонами и календарями.

Алексей Иванов Проверено инженерами SysKit.ru

1. Архитектура Vikunja: почему сисадмины и команды выбирают self-hosted вместо Trello и Todoist

Централизованные облачные планировщики задач вроде Trello, Asana, Todoist и Notion годами оставались стандартом для ведения проектов. Однако в последние годы зависимость от сторонних SaaS-платформ создала для разработчиков и системных администраторов критические риски: блокировки учетных записей по географическому признаку, внезапные изменения ценовой политики с урезанием бесплатных командных тарифов и хранение конфиденциальных планов компании на чужой инфраструктуре.

Vikunja — это современный open-source таск-менеджер под лицензией AGPLv3, созданный европейским разработчиком Конрадом Коллером (Konrad Koller). В отличие от неповоротливых Java- или Ruby-решений прошлого поколения, Vikunja спроектирована с акцентом на исключительную легковесность и скорость отклика:

  • Скомпилированное ядро на Go: бэкенд написан на языке Go, что обеспечивает околонулевое время запуска и потребление оперативной памяти всего 25–60 МБ RAM в режиме простоя.
  • Реактивный SPA-интерфейс на Vue 3: фронтенд встроен прямо в единый бинарный дистрибутив и Docker-образ, что исключает необходимость запуска отдельных Node.js-серверов или сложных сетей проксирования.
  • Универсальность представлений: поддержка 4 ключевых режимов отображения задач — гибкие Канбан-доски (Kanban), классические древовидные списки (List), диаграммы Ганта (Gantt) и таблицы (Table) с быстрой фильтрацией и тегами.
  • Нативный CalDAV-сервер: встроенный протокол CalDAV (RFC 4791) позволяет синхронизировать задачи и дедлайны со стандартными приложениями «Напоминания» на iPhone/iPad, календарями Android и почтовым клиентом Mozilla Thunderbird без сторонних плагинов.
  • Матрица матриц и гибкие связи: поддержка подзадач неограниченной вложенности, блокирующих связей («Задача А блокирует Задачу Б»), процентных чек-листов и встроенного форматирования Markdown.

Для сравнения накладных расходов ниже приведена сводная таблица популярных решений для управления задачами:

Платформа Стек технологий Потребление RAM Протокол CalDAV Лицензия / Автономия
Vikunja Go + Vue 3 + PostgreSQL ~80–120 МБ (с БД) Да (Встроенный) AGPLv3 / 100% Self-Hosted
Planka Node.js + React + Postgres ~250–350 МБ Нет AGPLv3 / 100% Self-Hosted
Taiga Python (Django) + AngularJS ~1.2–2.0 ГБ Нет MPL 2.0 / Тяжелый деплой
Trello / Todoist Закрытый проприетарный SaaS Облако провайдера Ограниченно (iCal Read-Only) SaaS / Риск блокировок

2. Подготовка VDS и конфигурация Docker Compose: PostgreSQL, тома и переменные окружения

Для комфортной работы сервиса достаточно минимального виртуального сервера с 1 vCPU и 1 ГБ оперативной памяти под управлением Ubuntu 24.04 или Debian 12. Перед началом установки сгенерируйте надежные пароли для базы данных и криптографический ключ сервиса с помощью утилиты генератор безопасных паролей SysKit.

Создадим выделенный каталог для стека Vikunja и сгенерируем файл переменных окружения:

bash
# Создаем системную директорию
sudo mkdir -p /opt/vikunja && cd /opt/vikunja

# Создаем подкаталоги для персистентных данных и вложений
sudo mkdir -p files db

# Генерируем случайный 64-символьный секретный ключ
openssl rand -hex 32

Создайте файл конфигурации переменных окружения .env:

ini (.env)
# Домен, на котором будет работать сервис (с протоколом HTTPS)
VIKUNJA_DOMAIN=tasks.example.com

# Секретный ключ подписи JWT-сессий (вставьте вывод openssl rand -hex 32)
VIKUNJA_SECRET_KEY=9a4f2c8b7e1d5e6a3c9b8d7e4f1a2b3c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a

# Параметры подключения к СУБД PostgreSQL
POSTGRES_USER=vikunja
POSTGRES_PASSWORD=super_secure_pg_password_here
POSTGRES_DB=vikunja

Production-манифест docker-compose.yml

Начиная с современных версий Vikunja, официальный образ объединяет в себе как API, так и легковесный SPA веб-интерфейс на Vue 3. Для production-инсталляций строго рекомендуется фиксировать конкретный стабильный релиз (например, vikunja/vikunja:0.24.6) вместо плавающего тега latest. Это обеспечивает полную воспроизводимость сборки и защищает от уязвимостей сессионного контроля прошлых версий (включая требования по сбросу активных токенов при смене пароля). Контейнер слушает внутренний порт 3456.

Правило изоляции портов от обхода UFW

Никогда не публикуйте порт сервиса в виде 3456:3456, если сервер подключен напрямую к публичной сети. Механизм Docker по умолчанию добавляет правила в цепочку PREROUTING iptables в обход межсетевого экрана UFW. Обязательно привязывайте порт строго к локальной петле: 127.0.0.1:3456:3456. В этом случае сервис будет доступен только локальному веб-серверу Nginx.

yaml (docker-compose.yml)
services:
  vikunja:
    image: vikunja/vikunja:0.24.6
    container_name: vikunja-app
    restart: unless-stopped
    ports:
      # Доступ строго с локального хоста для Nginx Reverse Proxy
      - "127.0.0.1:3456:3456"
    environment:
      VIKUNJA_SERVICE_PUBLICURL: "https://${VIKUNJA_DOMAIN}/"
      VIKUNJA_SERVICE_JWTSECRET: "${VIKUNJA_SECRET_KEY}"
      # Безопасность по умолчанию: запрет публичной регистрации через веб-форму
      VIKUNJA_SERVICE_ENABLEREGISTRATION: "false"
      VIKUNJA_DATABASE_TYPE: "postgres"
      VIKUNJA_DATABASE_HOST: "db"
      VIKUNJA_DATABASE_USER: "${POSTGRES_USER}"
      VIKUNJA_DATABASE_PASSWORD: "${POSTGRES_PASSWORD}"
      VIKUNJA_DATABASE_DATABASE: "${POSTGRES_DB}"
      # Максимальный размер загружаемых вложений (20 МБ)
      VIKUNJA_FILES_MAXSIZE: "20MB"
    volumes:
      - ./files:/app/vikunja/files
    depends_on:
      db:
        condition: service_healthy
    # Лимиты ресурсов для защиты от OOM Killer в Docker Compose
    mem_limit: 384m
    cpus: 1.0
    deploy:
      resources:
        limits:
          cpus: '1.0'
          memory: 384M
        reservations:
          memory: 64M

  db:
    image: postgres:17-alpine
    container_name: vikunja-db
    restart: unless-stopped
    environment:
      POSTGRES_USER: "${POSTGRES_USER}"
      POSTGRES_PASSWORD: "${POSTGRES_PASSWORD}"
      POSTGRES_DB: "${POSTGRES_DB}"
    volumes:
      - ./db:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -h localhost -U $$POSTGRES_USER -d $$POSTGRES_DB"]
      interval: 3s
      timeout: 3s
      retries: 5
      start_period: 10s
    mem_limit: 256m
    cpus: 0.75
    deploy:
      resources:
        limits:
          cpus: '0.75'
          memory: 256M
        reservations:
          memory: 64M

Запустим контейнеры в фоновом режиме, проверим статус инициализации и создадим первую учетную запись администратора:

bash
# Запуск стека сервисов
docker compose up -d

# Проверка статуса запуска и healthcheck СУБД
docker compose ps

# Создание первого пользователя-администратора напрямую через консольную утилиту Vikunja
docker exec -it vikunja-app vikunja user create --email admin@example.com --username admin --password "StrongAdminPassword123!"

3. Настройка Nginx Reverse Proxy и автоматический выпуск SSL Let's Encrypt

Поскольку веб-сервис Vikunja работает внутри контейнера и слушает исключительно локальный адрес 127.0.0.1:3456, он полностью изолирован от прямого доступа из интернета. Вся внешняя нагрузка принимается веб-сервером Nginx с принудительным шифрованием TLS/HTTPS, а проксирование в контейнер выполняется по локальной петле (loopback), что обеспечивает максимальную производительность без накладных расходов на двойное шифрование.

Убедитесь, что порты 80 и 443 открыты в брандмауэре вашего VDS. Быстро проверить доступность портов из внешней сети можно через бесплатную утилиту Порт-чекер SysKit.

Создайте файл конфигурации виртуального хоста в каталоге /etc/nginx/sites-available/:

nginx (/etc/nginx/sites-available/vikunja.conf)
server {
    listen 80;
    listen [::]:80;
    server_name tasks.example.com;

    # Максимальный размер загружаемых файлов и скриншотов задач
    client_max_body_size 25M;

    location / {
        proxy_pass http://127.0.0.1:3456;
        proxy_http_version 1.1;

        # Заголовки проксирования реального IP-адреса клиента
        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;

        # Поддержка WebSocket для мгновенного обновления досок
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

        # Тайм-ауты соединений
        proxy_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;
    }
}

Активируйте виртуальный хост, протестируйте конфигурацию и выпустите бесплатный TLS-сертификат с автоматическим перенаправлением на HTTPS:

bash
# Активация символической ссылки
sudo ln -s /etc/nginx/sites-available/vikunja.conf /etc/nginx/sites-enabled/

# Проверка синтаксиса Nginx
sudo nginx -t

# Перезагрузка веб-сервера
sudo systemctl reload nginx

# Автоматический выпуск доверенного SSL от Let's Encrypt с флагом --redirect
sudo certbot --nginx -d tasks.example.com --redirect

После выпуска сертификата убедитесь в отсутствии проблем с цепочкой доверия и протоколами TLS через SSL-чекер SysKit.

4. Организация рабочего пространства: Канбан-доски, списки, матрица Эйзенхауэра и диаграмма Ганта

После первого входа в веб-интерфейс создайте учетную запись администратора. Структура рабочего пространства Vikunja построена вокруг концепции иерархических Проектов (Projects):

  • Пространства и вложенные подпроекты: проекты можно группировать в родительские папки (например, «Инфраструктура VDS» → «Мониторинг», «Бэкапы», «Безопасность»). У каждого проекта настраивается собственный цветовой акцент и иконка.
  • Канбан-представление (Kanban Board): полноценная доска в стиле Trello. Вы можете создавать произвольные колонки («Бэклог», «В работе», «Код-ревью», «Готово»), устанавливать лимиты задач в колонке (WIP Limits для соблюдения принципов Agile/Kanban) и перемещать карточки перетаскиванием (Drag & Drop).
  • Диаграмма Ганта (Gantt Chart): визуализация длительности задач во времени. Позволяет задавать дату начала, дедлайн и выстраивать зависимости между этапами проекта для наглядного контроля сроков.
  • Матрица Эйзенхауэра (Табличный фильтр): разделение задач на 4 квадранта («Срочно/Важно», «Не срочно/Важно», «Срочно/Не важно», «Не срочно/Не важно») на основе приоритетов и установленных сроков.

Умное добавление задач (Quick Add Magic)

Vikunja поддерживает естественный парсинг атрибутов задачи прямо из строки ввода. Вы можете напечатать:

text
Обновить Nginx на продакшене tomorrow at 18:00 !high *infra #vds ~alex

Интерфейс мгновенно распознает дату (tomorrow at 18:00), высокий приоритет (!high), привязку к проекту (*infra), метку тега (#vds) и исполнителя (~alex). Внутри каждой задачи доступен полноценный редактор описания с поддержкой синтаксиса Markdown, загрузкой изображений из буфера обмена (Ctrl+V) и чек-листами подзадач.

5. Настройка CalDAV: двухсторонняя синхронизация с iOS Reminders, Android DAVx⁵ и Thunderbird

Главное практическое преимущество Vikunja перед большинством веб-трекеров — встроенная нативная реализация протокола CalDAV (RFC 4791). Это превращает Vikunja в полноценный бэкенд для стандартных мобильных и десктопных приложений: вам не требуется держать открытой вкладку браузера или устанавливать сторонние тяжелые клиенты.

Каждый проект и список задач в Vikunja автоматически транслируются в отдельный календарь/коллекцию CalDAV с поддержкой дедлайнов (DUE), напоминаний (VALARM) и правил повторения (RRULE).

Где взять реквизиты подключения CalDAV

Адрес CalDAV-сервера формируется по стандартному шаблону:

url
https://tasks.example.com/api/v1/dav/principals/username/
# или базовый корень для автообнаружения коллекций:
https://tasks.example.com/api/v1/dav/

Начиная с версии Vikunja 0.24+, в разделе Settings → API Tokens можно сгенерировать отдельный токен приложения (App Token) с правами на CalDAV. Это избавляет от необходимости вводить основной пароль учетной записи на смартфонах. Для более ранних сборок или простых клиентов используется стандартный пароль аккаунта.

Синхронизация с iOS Reminders («Напоминания» на iPhone, iPad и macOS)

Штатное приложение Apple Reminders поддерживает CalDAV «из коробки» без установки сторонних утилит:

  1. Откройте на iPhone или Mac «Настройки» → «Приложения» → «Напоминания» → «Учетные записи» (или «Основные» → «Учетные записи»).
  2. Нажмите «Добавить учетную запись» → «Другое» → «Учетная запись CalDAV».
  3. Заполните поля:
    • Сервер: tasks.example.com
    • Пользователь: ваше имя учетной записи в Vikunja
    • Пароль: ваш пароль или сгенерированный токен приложения
    • Описание: Vikunja Tasks
  4. Включите переключатель «Напоминания» и нажмите «Сохранить».

Обратите внимание: протокол CalDAV в iOS работает по принципу периодического опроса (polling). Для ускорения синхронизации в разделе «Настройки» → «Учетные записи» → «Загрузка данных» установите интервал «Каждые 15 минут» или потяните список задач вниз для принудительного обновления.

Синхронизация на Android через клиент DAVx⁵

На платформе Android стандартный календарь не поддерживает задачи без слоя синхронизации. Лучшим решением является проверенный open-source агент DAVx⁵ (доступен бесплатно в каталоге F-Droid и в Google Play):

  1. Установите DAVx⁵ и откройте мастер добавления учетной записи.
  2. Выберите пункт «Вход с URL-адресом и именем пользователя».
  3. Укажите базовый URL: https://tasks.example.com/api/v1/dav/, логин и пароль.
  4. После обнаружения выберите нужные списки задач Vikunja. Для управления задачами на Android используйте популярные клиенты Tasks.org или OpenTasks, которые мгновенно подхватывают синхронизированные списки из DAVx⁵.

Интеграция с почтовым клиентом Mozilla Thunderbird

В десктопном клиенте Thunderbird перейдите на вкладку календаря: Новый календарь → В сети → CalDAV. Укажите адрес https://tasks.example.com/api/v1/dav/principals/username/ и данные входа. Задачи появятся в боковой панели планирования рабочего дня с возможностью быстрого перетаскивания писем в список дел.

6. Харденинг безопасности, защита сессий (CVE-2026-27575) и автоматические бэкапы

Когда сервис доступен в публичном интернете, необходимо защитить инфраструктуру от несанкционированного доступа и потери информации.

1. Принцип Secure-by-Default и управление учетными записями

В production-конфигурации мы намеренно зафиксировали VIKUNJA_SERVICE_ENABLEREGISTRATION=false. Это исключает ситуацию, когда посторонние сканеры сети находят открытую форму регистрации и создают несанкционированные аккаунты на вашем сервере.

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

bash
docker exec -it vikunja-app vikunja user create --email colleague@example.com --username colleague --password "StrongUserPassword123!"

Если вам удобнее разово зарегистрировать пользователя через браузер, переключите значение переменной на true в файле .env, примените изменения через docker compose up -d, проведите регистрацию и сразу верните значение false.

2. Защита активных сессий (CVE-2026-27575) и двухфакторная аутентификация

В версиях до 0.24.0 (а также в ветках до 2.3.0) существовала известная уязвимость, связанная с сохранением валидности сессий и JWT-токенов после смены пароля пользователем (CVE-2026-27575). Фиксированная нами версия 0.24.6 полностью устраняет эту проблему: при смене пароля все активные токены авторизации принудительно инвалидируются.

Обязательно включите двухфакторную аутентификацию в веб-интерфейсе: Settings → Security → Two Factor Authentication. Отсканируйте сгенерированный QR-код в TOTP-аутентификаторе (Aegis, 2FAS, Google Authenticator) и сохраните одноразовые резервные коды. Для генерации криптостойких паролей используйте утилиту Генератор надежных паролей SysKit.

3. Скрипт автоматического резервного копирования базы данных и вложений

Вся структура досок, задачи, метки и комментарии хранятся в PostgreSQL (контейнер vikunja-db), а загруженные вложения (файлы, аватары, скриншоты) — в локальном смонтированном каталоге /opt/vikunja/files на диске VDS.

Создайте автоматический скрипт резервного копирования с ротацией архивов:

bash (/opt/vikunja/backup.sh)
#!/usr/bin/env bash
set -euo pipefail

BACKUP_DIR="/opt/vikunja/backups"
DATA_DIR="/opt/vikunja/files"
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
KEEP_DAYS=14

mkdir -p "$BACKUP_DIR"

# 1. Дамп базы данных PostgreSQL через контейнер vikunja-db
docker exec -t vikunja-db pg_dump -U vikunja vikunja | gzip > "$BACKUP_DIR/vikunja_db_$TIMESTAMP.sql.gz"

# 2. Прямая архивация локального каталога файлов и вложений
tar -czf "$BACKUP_DIR/vikunja_files_$TIMESTAMP.tar.gz" -C "$DATA_DIR" .

# 3. Удаление резервных копий старше 14 дней
find "$BACKUP_DIR" -type f -name "vikunja_*" -mtime +$KEEP_DAYS -delete

echo "[$(date)] Резервная копия Vikunja успешно создана: $TIMESTAMP"

Сделайте скрипт исполняемым и добавьте его в системный планировщик cron:

bash
chmod +x /opt/vikunja/backup.sh

# Открытие планировщика задач cron
crontab -e

# Ежедневное создание бэкапа в 03:30 ночи
30 3 * * * /opt/vikunja/backup.sh >> /var/log/vikunja_backup.log 2>&1
💡 Нужна готовая конфигурация Nginx для продакшена?

Сгенерируйте оптимизированный конфиг обратного прокси с защитными заголовками HSTS, буферизацией и готовыми параметрами WebSocket в нашем интерактивном конфигураторе:

Сгенерировать Nginx Reverse Proxy

Рекомендуемые VDS-провайдеры

Отказоустойчивые сервера с быстрыми NVMe и каналом до 1 Гбит/с

Выбор редакции
⚡

Timeweb Cloud — Быстрые NVMe VDS

Идеально подходит для развертывания легковесных Go-сервисов и баз данных PostgreSQL с защитой от DDoS и мгновенной установкой Docker.

Конфигурация
1 vCPU 3.3 ГГц • 1 ГБ RAM • 15 ГБ NVMe • Трафик без лимита
Премиум Tier III
🔷

Selectel — Надежные облачные серверы

Отказоустойчивая инфраструктура корпоративного уровня в дата-центрах Москвы и Санкт-Петербурга с приватными сетями и снапшотами.

Конфигурация
1 vCPU • 2 ГБ RAM • 30 ГБ NVMe • Канал до 1 Гбит/с
Простота управления
🟠

Beget — Удобные серверы для проектов

Удобная панель управления сервером с быстрым развертыванием популярных стеков, почасовой тарификацией и отзывчивой поддержкой 24/7.

Конфигурация
1 vCPU • 1 ГБ RAM • 20 ГБ NVMe • 1 IP в комплекте

Инструменты SysKit по теме статьи

Бесплатные утилиты для проверки и диагностики вашего сервера

Вопросы и ответы (FAQ)

Популярные вопросы вебмастеров и сисадминов по данной теме

Можно ли использовать встроенную SQLite вместо PostgreSQL?
Да, Vikunja поддерживает SQLite, и для персонального использования одним человеком это вполне рабочий вариант. Однако для рабочих проектов, одновременной работы команды и CalDAV-синхронизации с постоянными фоновыми запросами рекомендуется использовать PostgreSQL: SQLite блокирует файл базы данных при записи (write-lock), что при активном обращении нескольких мобильных клиентов может вызывать микрозадержки и ошибки блокировки.
Как сбросить пароль администратора, если почтовый сервер SMTP не был настроен?
Сброс пароля выполняется одной командой внутри контейнера через встроенную консольную утилиту Vikunja. Выполните: <code>docker exec -it vikunja-app vikunja user reset-password &lt;username&gt;</code>. Утилита запросит или сгенерирует новый пароль прямо в терминале, после чего вы сможете авторизоваться в веб-интерфейсе.
Почему задачи в iOS Reminders или Thunderbird обновляются с задержкой?
Протокол CalDAV работает по принципу периодического опроса (polling), а не постоянного push-соединения. В настройках учетной записи на iPhone/iPad (раздел «Настройки» → «Учетные записи» → «Загрузка данных») выберите интервал проверки «Каждые 15 минут» или выполните свайп вниз в приложении «Напоминания» для принудительного обновления.
Поддерживается ли миграция существующих проектов из Trello, Todoist или Asana?
Да, в Vikunja встроен нативный мастер импорта. В веб-интерфейсе перейдите в «Settings» → «Migration». Поддерживается прямой импорт досок и задач из Trello (через экспорт JSON), Todoist (по API-токену), Microsoft To-Do и других трекеров с сохранением дедлайнов, меток, описаний и структуры колонок.

Читайте также в блоге SysKit

Смежные руководства и полезные технические статьи