DevOps и Docker 15 мин чтения 2026-10-25

Развертывание Plane на VDS в Docker Compose: автономный трекер задач, спринтов и роадмапов на замену Jira и Linear

Практическое руководство по развертыванию open-source трекера задач Plane v1.4.2 в Docker Compose на собственном VDS: микросервисная архитектура (Django, Celery, Next.js), RabbitMQ, PostgreSQL 15, объектное хранилище MinIO, Nginx с SSL и WebSocket, привязка портов к 127.0.0.1 и бэкап.

Инженерная редакция SysKit Проверено инженерами SysKit.ru

Уход зарубежных сервисов и блокировки корпоративных подписок поставили команды разработки перед жестким выбором: оставаться на облачной Jira или Linear с постоянным риском внезапной потери доступа либо откатываться к морально устаревшим трекерам вроде Redmine с архаичным интерфейсом из начала 2000-х. Plane — это один из самых быстрорастущих open-source проектов в сфере управления разработкой с более чем 61 000 звёзд на GitHub, распространяемый по лицензии AGPLv3. Платформа сочетает в себе скорость и эстетику Linear с мощью корпоративных рабочих процессов Jira: спринты (Cycles), модули (Modules), сквозные роадмапы, база знаний (Pages) и учет времени. При этом весь стек развертывается на вашем собственном VDS под полным контролем компании. В этом руководстве мы развернем стабильный релиз Plane v1.4.2 в Docker Compose, разберем микросервисную архитектуру с RabbitMQ и MinIO, настроим обратный прокси Nginx с SSL и организуем автоматический бэкап базы данных.

1. Почему команды уходят из Jira, Trello и Linear в Self-Hosted

Зависимость от проприетарных SaaS-трекеров несет для IT-бизнеса и продуктовых команд три фундаментальных риска:

  • Санкционная уязвимость и блокировки аккаунтов. Ограничения со стороны Atlassian (Jira, Trello, Confluence) наглядно показали, что доступ к годами накопленным бэклогам, технической документации и истории баг-репортов может быть заблокирован в одностороннем порядке за считанные часы.
  • Экономика масштабирования. В облачных решениях стоимость подписки начисляется за каждого разработчика, тестировщика и менеджера ($8–$15 за пользователя в месяц). Для команды из 20–30 специалистов это выливается в регулярные расходы от 200 000 рублей в год без учета сложностей с зарубежной оплатой.
  • Конфиденциальность кодовой базы и 152-ФЗ. Задачи в трекере содержат архитектурные схемы, обсуждения уязвимостей, ссылки на закрытые репозитории и клиентские данные. Размещение этой информации на собственном сервере гарантирует соблюдение требований законодательства РФ и корпоративных регламентов информационной безопасности.
Критерий Jira Cloud Linear Redmine Plane v1.4.2 (Self-Hosted)
Размещение данных Зарубежные облака Зарубежные облака Свой сервер Свой VDS в РФ
Оплата за пользователей Подушная ($8–15/юзер) Подушная ($8–12/юзер) Бесплатно 0 ₽ (без лимитов)
Интерфейс и скорость Тяжелый / перегруженный Молниеносный Устаревший (Ruby/HTML) Современный (Next.js / React)
Спринты и документация Да (нужен Confluence) Базовые циклы Только через плагины Cycles + Pages из коробки
Лицензия Проприетарная Проприетарная GPL v2 AGPLv3 (Открытый исходный код)

2. Архитектура Plane v1.4.2: Frontend, API (Django), Worker, RabbitMQ и MinIO

В отличие от монолитных систем, платформа makeplane/plane спроектирована как распределенный микросервисный комплекс. Официальная редакция Community Edition включает в себя несколько специализированных контейнеров:

  • plane-frontend (web): пользовательский интерфейс на Next.js, отвечающий за быстрый клиентский рендеринг канбан-досок, списков задач и страниц документации.
  • plane-backend (api): ядро бизнес-логики на Python (Django REST Framework), управляющее правами доступа, схемой данных, аутентификацией и REST API.
  • Асинхронные воркеры (worker и beat-worker): фоновые обработчики Celery. Воркер берет на себя тяжелые задачи (отправка почтовых уведомлений, генерация превью, вебхуки), а beat-воркер запускает периодические фоновые процедуры по расписанию.
  • plane-live (live): легковесный сервис WebSocket на Node.js, транслирующий перемещение карточек и изменения статусов между экранами коллег в реальном времени.
  • Брокер сообщений RabbitMQ (plane-mq): надежная шина передачи сообщений между веб-сервером и очередями воркеров Celery с поддержкой подтверждения доставки (ACK).
  • Кэш Valkey / Redis (plane-redis): высокоскоростное in-memory хранилище для оперативного кэширования сессий пользователей и временных ключей.
  • Объектное хранилище MinIO (plane-minio): S3-совместимое локальное хранилище для аватаров, вложений к задачам, файлов документов и логов.
  • Внутренний шлюз (proxy): обратный прокси на базе Envoy/Nginx, который маршрутизирует запросы браузера к фронтенду, API или вебсокетам через единую точку входа.

💡 Совет инженера: почему Plane использует RabbitMQ вместе с Redis

Многие простые сервисы используют Redis и для кэша, и для очередей задач. Plane разделяет эти уровни: быстрый кэш сессий хранится в Redis, а критически важные очереди задач Celery обрабатываются брокером RabbitMQ. Это исключает потерю фоновых задач при перезапуске кэша или пиковых нагрузках на память.

3. Системные требования к серверу: почему Plane требует от 4 до 8 ГБ RAM

Поскольку Plane объединяет в одном комплексе фронтенд Next.js, бэкенд на Django, два процесса Celery, брокер RabbitMQ, базу данных PostgreSQL и объектное хранилище MinIO, суммарное потребление ресурсов заметно выше, чем у легковесных утилит. Для надежной работы необходимо выделить достаточный запас оперативной памяти:

Параметр Минимальный тариф (до 5 инженеров) Рекомендуемый тариф (команда 10–30 человек)
Процессор (vCPU) 2 vCPU (от 2.8 ГГц) 4 vCPU (от 3.3 ГГц)
Оперативная память (RAM) 4 ГБ (+ 2 ГБ swap) 8 ГБ RAM
Дисковое пространство 40 ГБ NVMe 80–120 ГБ NVMe (с запасом под вложения MinIO)
Операционная система Ubuntu 24.04 LTS / Debian 12 Ubuntu 24.04 LTS x86_64

В базовом состоянии все контейнеры стека потребляют около 2.8–3.2 ГБ оперативной памяти. Если вы запускаете Plane на сервере с 4 ГБ RAM, обязательно настройте файл подкачки (swap) размером не менее 2 ГБ, чтобы избежать аварийного завершения воркеров Celery при компиляции отчетов или миграциях базы данных.

4. Развертывание в Docker Compose с защитой портов и секретами

При развертывании корпоративного трекера задач важно соблюдать три принципа сетевой безопасности:

  1. Привязка порта только к локальной петле (127.0.0.1:8090:80). Внутренний прокси Plane публикуется на локальном порту 8090, а доступ из внешнего мира организуется через внешний реверс-прокси Nginx с SSL. Это исключает обход UFW (подробности в статье Docker обходит UFW на Linux).
  2. Раздельные криптографические секреты. Пароли к базе данных, брокеру RabbitMQ и ключ подписи сессий Django SECRET_KEY генерируются через криптостойкий генератор.
  3. Изоляция прав и аппаратные лимиты памяти. Предотвращают отказ всей операционной системы хоста при пиковых нагрузках на сборку веб-страниц.

Генерация секретов и подготовка каталога проекта

# Создаём рабочий каталог для трекера
mkdir -p /opt/plane && cd /opt/plane

# Генерируем уникальные криптографические ключи
PLANE_SECRET=$(openssl rand -hex 32)
DB_PASS=$(openssl rand -hex 24)
MQ_PASS=$(openssl rand -hex 24)
MINIO_KEY=$(openssl rand -hex 16)
MINIO_SECRET=$(openssl rand -hex 32)

# Создаём защищенный файл переменных окружения .env
cat <<EOF > .env
APP_DOMAIN=plane.example.ru
APP_RELEASE=v1.4.2

WEB_URL=https://plane.example.ru
CORS_ALLOWED_ORIGINS=https://plane.example.ru
API_BASE_URL=http://api:8000
DEBUG=0

# База данных PostgreSQL 15
PGHOST=plane-db
PGDATABASE=plane
POSTGRES_USER=plane
POSTGRES_PASSWORD=${DB_PASS}
POSTGRES_DB=plane
POSTGRES_PORT=5432
PGDATA=/var/lib/postgresql/data

# Кэш Redis / Valkey
REDIS_HOST=plane-redis
REDIS_PORT=6379

# Брокер сообщений RabbitMQ
RABBITMQ_HOST=plane-mq
RABBITMQ_PORT=5672
RABBITMQ_USER=plane
RABBITMQ_PASSWORD=${MQ_PASS}
RABBITMQ_VHOST=plane

# Секрет Django для подписи токенов
SECRET_KEY=${PLANE_SECRET}

# Объектное хранилище MinIO
USE_MINIO=1
AWS_ACCESS_KEY_ID=${MINIO_KEY}
AWS_SECRET_ACCESS_KEY=${MINIO_SECRET}
AWS_S3_ENDPOINT_URL=http://plane-minio:9000
AWS_S3_BUCKET_NAME=uploads
FILE_SIZE_LIMIT=52428800
EOF

chmod 600 .env

💡 Совет инженера: пароли для баз данных

Для генерации надежных паролей баз данных и служебных токенов удобно использовать встроенный генератор надёжных паролей SysKit. Выбирайте длину от 32 символов без знаков кавычек и спецсимволов, чувствительных к экранированию в файлах .env.

Манифест docker-compose.yml для Plane

services:
  plane-db:
    image: postgres:15.7-alpine
    container_name: plane-db
    restart: unless-stopped
    env_file:
      - .env
    environment:
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_DB: ${POSTGRES_DB}
    volumes:
      - pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
      interval: 10s
      timeout: 5s
      retries: 5
    mem_limit: 1.5g
    cpus: 1.5

  plane-redis:
    image: valkey/valkey:7.2.11-alpine
    container_name: plane-redis
    restart: unless-stopped
    command: ["valkey-server", "--maxmemory-policy", "noeviction"]
    volumes:
      - redisdata:/data
    healthcheck:
      test: ["CMD", "valkey-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5
    mem_limit: 512m
    cpus: 1.0

  plane-mq:
    image: rabbitmq:3.13.6-management-alpine
    container_name: plane-mq
    restart: unless-stopped
    env_file:
      - .env
    environment:
      RABBITMQ_DEFAULT_USER: ${RABBITMQ_USER}
      RABBITMQ_DEFAULT_PASS: ${RABBITMQ_PASSWORD}
      RABBITMQ_DEFAULT_VHOST: ${RABBITMQ_VHOST}
    volumes:
      - rabbitmq_data:/var/lib/rabbitmq
    healthcheck:
      test: ["CMD", "rabbitmq-diagnostics", "check_running"]
      interval: 15s
      timeout: 10s
      retries: 5
    mem_limit: 512m
    cpus: 1.0

  plane-minio:
    image: minio/minio:RELEASE.2024-08-17T01-24-54Z
    container_name: plane-minio
    restart: unless-stopped
    env_file:
      - .env
    environment:
      MINIO_ROOT_USER: ${AWS_ACCESS_KEY_ID}
      MINIO_ROOT_PASSWORD: ${AWS_SECRET_ACCESS_KEY}
    command: ["server", "/export", "--console-address", ":9001"]
    volumes:
      - uploads:/export
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
      interval: 15s
      timeout: 5s
      retries: 5
    mem_limit: 768m
    cpus: 1.0

  web:
    image: makeplane/plane-frontend:v1.4.2
    container_name: plane-web
    restart: unless-stopped
    env_file:
      - .env
    depends_on:
      - api
    mem_limit: 1g
    cpus: 1.0

  space:
    image: makeplane/plane-space:v1.4.2
    container_name: plane-space
    restart: unless-stopped
    env_file:
      - .env
    depends_on:
      - api
    mem_limit: 512m
    cpus: 0.5

  admin:
    image: makeplane/plane-admin:v1.4.2
    container_name: plane-admin
    restart: unless-stopped
    env_file:
      - .env
    depends_on:
      - api
    mem_limit: 512m
    cpus: 0.5

  live:
    image: makeplane/plane-live:v1.4.2
    container_name: plane-live
    restart: unless-stopped
    env_file:
      - .env
    depends_on:
      - api
      - plane-redis
    mem_limit: 512m
    cpus: 0.5

  api:
    image: makeplane/plane-backend:v1.4.2
    container_name: plane-api
    restart: unless-stopped
    env_file:
      - .env
    command: ["./bin/docker-entrypoint-api.sh"]
    depends_on:
      plane-db:
        condition: service_healthy
      plane-redis:
        condition: service_healthy
      plane-mq:
        condition: service_healthy
    mem_limit: 1.5g
    cpus: 1.5

  worker:
    image: makeplane/plane-backend:v1.4.2
    container_name: plane-worker
    restart: unless-stopped
    env_file:
      - .env
    command: ["./bin/docker-entrypoint-worker.sh"]
    depends_on:
      api:
        condition: service_started
    mem_limit: 1g
    cpus: 1.0

  beat-worker:
    image: makeplane/plane-backend:v1.4.2
    container_name: plane-beat-worker
    restart: unless-stopped
    env_file:
      - .env
    command: ["./bin/docker-entrypoint-beat.sh"]
    depends_on:
      api:
        condition: service_started
    mem_limit: 512m
    cpus: 0.5

  migrator:
    image: makeplane/plane-backend:v1.4.2
    container_name: plane-migrator
    restart: "no"
    env_file:
      - .env
    command: ["./bin/docker-entrypoint-migrator.sh"]
    depends_on:
      plane-db:
        condition: service_healthy

  proxy:
    image: makeplane/plane-proxy:v1.4.2
    container_name: plane-proxy
    restart: unless-stopped
    env_file:
      - .env
    ports:
      # Защита: слушаем локальную петлю на порту 8090
      - "127.0.0.1:8090:80"
    depends_on:
      - web
      - api
      - space
      - admin
      - live
    mem_limit: 512m
    cpus: 0.5

volumes:
  pgdata:
  redisdata:
  rabbitmq_data:
  uploads:

Запуск и инициализация базы данных

# Скачиваем образы всех микросервисов
docker compose pull

# Запускаем контейнеры в фоновом режиме
docker compose up -d

# Проверяем успешность выполнения миграций схемы данных
docker compose logs -f migrator

# Проверяем состояние всех запущенных сервисов
docker compose ps

Контейнер migrator при первом старте создаст все необходимые таблицы в PostgreSQL 15 и затем завершит свою работу со статусом Exited (0) — это штатное поведение. Остальные сервисы перейдут в статус Up.

5. Настройка Nginx с SSL Let's Encrypt и поддержкой WebSocket

Поскольку прокси-шлюз Plane привязан к локальному порту 127.0.0.1:8090, для публичного защищенного доступа настраивается внешний Nginx. Платформа активно использует микросервис plane-live для трансляции изменений на канбан-досках и синхронного редактирования документов Pages, поэтому поддержка постоянных WebSocket-соединений критически важна.

Конфигурация виртуального хоста Nginx

Создайте файл конфигурации для домена (например, /etc/nginx/sites-available/plane.example.ru.conf):

# Разрешаем загрузку тяжелых вложений, логов и скриншотов
client_max_body_size 50M;

server {
    listen 80;
    server_name plane.example.ru;

    # Автоматический редирект HTTP на защищенный HTTPS
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name plane.example.ru;

    # Сертификаты Let's Encrypt
    ssl_certificate /etc/letsencrypt/live/plane.example.ru/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/plane.example.ru/privkey.pem;

    # Рекомендуемые параметры безопасности SSL/TLS
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 1d;

    # Заголовки безопасности
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;

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

        # Критично для Plane: поддержка WebSocket для сервиса live
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

        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;

        # Увеличенные таймауты для живых сессий и загрузки файлов
        proxy_read_timeout 86400s;
        proxy_send_timeout 86400s;
        proxy_buffering off;
    }
}

Выпуск SSL-сертификата Let's Encrypt

# Активируем виртуальный хост
ln -s /etc/nginx/sites-available/plane.example.ru.conf /etc/nginx/sites-enabled/

# Проверяем конфигурацию Nginx
nginx -t

# Выпускаем бесплатный сертификат с автоматическим редиректом
certbot --nginx -d plane.example.ru --non-interactive --agree-tos --redirect -m admin@example.ru

# Применяем новую конфигурацию Nginx
systemctl reload nginx

После установки сертификата проверьте корректность цепочки и отсутствие ошибок TLS с помощью сервиса проверки SSL-сертификатов, а также проанализируйте заголовки ответа через сканер HTTP-заголовков безопасности.

Первоначальный вход в панель управления и создание воркспейса

Откройте браузер по адресу https://plane.example.ru:

  1. При первом входе система предложит зарегистрировать учетную запись главного администратора (Owner). Укажите рабочую почту и задайте надежный мастер-пароль.
  2. Создайте рабочее пространство (Workspace): задайте имя компании или команды и уникальный URL-идентификатор (slug).
  3. В настройках проекта выберите часовой пояс и формат отображения дат.
  4. Перейдите в раздел Members и отправьте инвайты разработчикам, тестировщикам и продакт-менеджерам.

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

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

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

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

Высокочастотные процессоры 3.3 ГГц и скоростные NVMe-накопители для мгновенной реакции очередей Celery и базы PostgreSQL в Plane.

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

Selectel — Инфраструктура Tier III

Отказоустойчивые серверы в сертифицированных дата-центрах РФ уровня Tier III, приватные изолированные сети и полное соблюдение 152-ФЗ.

Конфигурация
2 vCPU • 4 ГБ RAM • 60 ГБ NVMe • Приватная сеть
Быстрый старт
🟠

Beget — Простой старт для домена

Готовое Docker-окружение на Ubuntu 24.04 LTS, автоматический выпуск SSL и оперативная русскоязычная техническая поддержка 24/7.

Конфигурация
2 vCPU • 4 ГБ RAM • 50 ГБ NVMe • Быстрый запуск

6. Организация процессов: спринты (Cycles), модули (Modules) и база знаний (Pages)

В отличие от простых канбан-досок, Plane v1.4.2 изначально спроектирован под полноценные методологии разработки (Scrum и Kanban) и объединяет четыре ключевые подсистемы:

1. Спринты и итерации (Cycles)

Циклы в Plane представляют собой аналог спринтов в Jira:

  • Вы задаете дату старта и окончания итерации (например, 2 недели).
  • Задачи переносятся из общего бэклога в спринт с оценкой сложности (Story Points или часы).
  • Встроенный график сгорания задач (Burndown Chart) наглядно показывает текущий темп команды и прогнозирует дату завершения итерации.
  • При закрытии спринта все незавершенные карточки можно в один клик перенести в следующий цикл или вернуть в бэклог.

2. Функциональные модули (Modules)

Модули заменяют собой громоздкие эпики (Epics). Это логические блоки функциональности (например, «Редизайн чекаута» или «Интеграция с СБП»), объединяющие задачи из разных проектов и спринтов. Модуль позволяет отслеживать совокупный прогресс готовности фичи, назначать лида направления и фиксировать дедлайны релиза.

3. База знаний и документация (Pages)

Огромная ценность Plane — встроенная альтернатива Confluence и Notion. В разделе Pages инженеры и архитекторы могут вести техническую документацию, архитектурные RFC и регламенты релизов прямо рядом с кодом и задачами:

  • Поддерживается богатый Markdown-редактор, блоки кода с подсветкой синтаксиса и таблицы.
  • Любой абзац или пункт чек-листа в документе можно мгновенно конвертировать в отдельную задачу в трекере.
  • Благодаря микросервису plane-live несколько участников могут одновременно редактировать документ без конфликтов версий.

4. Сортировка входящих обращений (Triage)

Механизм Triage позволяет изолировать основной бэклог от хаотичного потока входящих багов от службы поддержки или пользователей. Входящая карточка попадает в «буферную зону», где тимлид или продукт-овнер может принять задачу (Accept), отклонить ее (Decline) или запросить уточнение деталей, не засоряя активные доски разработчиков.

7. Автоматизация и интеграции: вебхуки, REST API и связка с GitLab

Все операции в Plane доступны через REST API. Платформа также поддерживает вебхуки для мгновенного информирования команд в корпоративных чатах.

Пример автоматического создания задачи через Python и REST API

С помощью API можно легко настроить захват ошибок из системы мониторинга (например, Sentry или Grafana Alertmanager):

import requests

BASE_URL = "https://plane.example.ru/api/v1"
WORKSPACE_SLUG = "my-company"
PROJECT_ID = "ваш_uuid_проекта"
# Токен генерируется в профиле: Settings -> API Tokens
API_TOKEN = "plane_pat_xxxxxxxxxxxxxxxxxxxx"

headers = {
    "x-api-key": API_TOKEN,
    "Content-Type": "application/json"
}

issue_data = {
    "name": "Аварийное падение воркера при обработке выгрузки",
    "description_html": "<p>Мониторинг зафиксировал OOM на сервере выгрузок. Требуется провести профилирование памяти.</p>",
    "priority": "urgent",  # urgent, high, medium, low, none
    "state": "b6a8e52a-xxxx-xxxx-xxxx-xxxxxxxxxxxx"  # UUID статуса 'To Do'
}

url = f"{BASE_URL}/workspaces/{WORKSPACE_SLUG}/projects/{PROJECT_ID}/issues/"
response = requests.post(url, json=issue_data, headers=headers, timeout=10)
response.raise_for_status()

created_issue = response.json()
print(f"Задача успешно создана! Идентификатор: {created_issue.get('sequence_id')}")

Интеграция с локальным GitLab: закрытие задач через коммиты

В разделе Project Settings → Integrations → Webhooks добавьте вебхук на пуш-события из вашего GitLab-сервера. При оформлении коммитов по шаблону Fixes PROJ-104: оптимизирован SQL-запрос Plane автоматически свяжет коммит с карточкой задачи и переведет ее в статус «Готово к тестированию».

8. Резервное копирование базы PostgreSQL, вложений MinIO и обновление

В Plane данные разделены на два независимых контура:

  1. Реляционные данные (PostgreSQL 15): проекты, спринты, описания задач, комментарии, пользователи и права хранятся в томе pgdata.
  2. Бинарные вложения (MinIO): прикрепленные скриншоты, логи, PDF-спецификации и аватары хранятся в томе uploads.

Скрипт создания комплексного резервного архива

Создайте скрипт /usr/local/bin/backup-plane.sh для создания целостного дампа:

#!/usr/bin/env bash
set -euo pipefail

BACKUP_DIR="/var/backups/plane"
TIMESTAMP="$(date +%Y%m%d-%H%M%S)"
TARGET_DIR="${BACKUP_DIR}/${TIMESTAMP}"

mkdir -p "${TARGET_DIR}"

# 1. Дамп базы данных PostgreSQL 15
echo "Создание дампа базы PostgreSQL..."
docker exec plane-db pg_dump -U plane plane | gzip -9 > "${TARGET_DIR}/plane-db.sql.gz"

# 2. Архивация вложений и файлов MinIO
echo "Архивация вложений задач..."
tar -czf "${TARGET_DIR}/plane-uploads.tar.gz" -C /var/lib/docker/volumes/plane_uploads/_data .

# 3. Резервная копия файла конфигурации с секретами
cp /opt/plane/.env "${TARGET_DIR}/plane.env"

echo "Бэкап успешно создан в ${TARGET_DIR} ($(du -sh "${TARGET_DIR}" | cut -f1))"

# Ротация: удаляем локальные архивы старше 14 дней
find "${BACKUP_DIR}" -mindepth 1 -maxdepth 1 -type d -mtime +14 -exec rm -rf {} +
# Делаем скрипт исполняемым
chmod +x /usr/local/bin/backup-plane.sh

# Добавляем в cron для ночного запуска в 03:30
echo "30 3 * * * /usr/local/bin/backup-plane.sh >> /var/log/plane-backup.log 2>&1" | crontab -

Для максимальной надежности настройте автоматическую отправку архивов в независимое облачное хранилище по нашей инструкции по автоматическим шифрованным бэкапам VDS в S3.

Процедура обновления Plane до новых версий

cd /opt/plane

# 1. Создаем свежий бэкап перед обновлением
/usr/local/bin/backup-plane.sh

# 2. Скачиваем обновленные образы
docker compose pull

# 3. Перезапускаем сервисы (мигратор автоматически применит новую схему БД)
docker compose up -d

# 4. Проверяем лог мигратора и состояние контейнеров
docker compose logs migrator
docker compose ps

9. Чек-лист готовности Plane v1.4.2 к коммерческой эксплуатации

Параметр Рекомендуемое значение Назначение
Сетевой порт прокси 127.0.0.1:8090:80 Защита от сканирования из интернета и обхода правил UFW
Секреты .env Раздельные ключи для DB, MQ, MinIO и Django Изоляция контуров и защита от компрометации токенов
Лимиты ресурсов Директивы mem_limit и cpus Защита операционной системы от зависания по OOM
WebSocket в Nginx Заголовки Upgrade и отключение буферизации Мгновенная синхронизация канбан-досок и страниц Pages
Файл подкачки (swap) Не менее 2 ГБ swap на NVMe Стабильность фоновых воркеров Celery при миграциях
Резервные копии Ежедневный дамп PostgreSQL + архивация MinIO Гарантия сохранности задач и прикрепленных документов

Развертывание Plane на собственном VDS дает команде полную независимость от зарубежных облачных платформ, сохраняет привычную скорость работы современного интерфейса Linear и защищает корпоративные данные в соответствии с законодательством РФ.

🎯 Подберите производительный VDS для трекера задач Plane

Поскольку микросервисный стек Plane включает в себя несколько контейнеров, базу данных и воркеры Celery, для плавной работы интерфейса критически важны скоростные ядра процессора и быстрые диски NVMe. Выбирайте надежных российских хостинг-провайдеров с проверенными дата-центрами уровня Tier III.

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

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

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

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

Сколько оперативной памяти требуется стеку Plane в Docker?
Минимальный объем оперативной памяти для комфортного запуска стека (Next.js фронтенд, Django API, воркеры Celery, PostgreSQL 15, RabbitMQ, Valkey и MinIO) составляет 4 ГБ RAM с обязательным подключением swap-файла размером от 2 ГБ. Для стабильной работы команды из 10–30 инженеров без риска падения процессов рекомендуется выбирать тариф VDS с 8 ГБ RAM и современными процессорами от 3.3 ГГц.
Зачем Plane нужны и RabbitMQ, и Redis одновременно?
Платформа разделяет кэш и асинхронные очереди: высокоскоростной in-memory кэш Redis (Valkey) используется для оперативного кэширования веб-сессий и прав доступа, тогда как брокер RabbitMQ отвечает за надежную маршрутизацию очередей задач Celery с поддержкой подтверждения доставки сообщений. Такое разделение предотвращает потерю фоновых задач при переполнении кэша.
Как перенести задачи и проекты из облачной Jira в Plane?
В панели администрирования Plane доступен штатный модуль импорта данных (Settings → Import/Export). Вы можете выгрузить проект из Jira в стандартный JSON/CSV формат или подключить прямую синхронизацию через токен Jira API: система автоматически сопоставит статусы, типы задач, пользователей и перенесет структуру бэклога.

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

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