bolt Valebyte VPS от $4/мес — NVMe, запуск за 60 секунд.

Получить VPS arrow_forward
eco Начальный Туториал

Развёртывание Plane на VPS: self-hosted управление проектами, SSL и резервные копии

calendar_month Oct 04, 2026 schedule 19 мин. чтения visibility 29 просмотров
Развёртывание Plane на VPS: self-hosted управление проектами, SSL и резервные копии
info

Нужен сервер для этого гайда? Мы предлагаем выделенные серверы и VPS в 50+ странах с мгновенной настройкой.

Нужен сервер для этого гайда?

Разверните VPS или выделенный сервер за минуты.

Развёртывание Plane на VPS: self-hosted управление проектами, SSL и резервные копии

TL;DR

Plane — self-hosted платформа для управления проектами, задачами, спринтами, заметками и командами. Ниже мы развернём Plane в Docker на Ubuntu 24.04 LTS, закроем его за Caddy с автоматическим SSL-сертификатом, настроим базовую защиту сервера и резервное копирование базы данных, конфигурации и пользовательских файлов.

  • Используем VPS с минимум 4 vCPU, 8 ГБ RAM и SSD от 80 ГБ.
  • Установим Docker Engine и Docker Compose Plugin из официального репозитория.
  • Развернём Plane через официальный self-hosted installer и зафиксируем версию релиза.
  • Откроем только SSH, HTTP и HTTPS, а административный доступ ограничим SSH-ключами.
  • Настроим Caddy для автоматического получения и продления TLS-сертификата.
  • Создадим ежедневный backup PostgreSQL, конфигурации и данных объектного хранилища.

1. TL;DR

В этом руководстве рассматривается полный цикл развёртывания Plane: от чистого VPS и базовой защиты Ubuntu до публикации приложения по HTTPS и восстановления из резервной копии. Команды рассчитаны на Ubuntu Server 24.04 LTS и Docker Engine 28.x или более новую стабильную версию, доступную в официальном репозитории Docker на момент установки.

  • Plane работает как набор контейнеров: web-интерфейс, API, фоновые задачи, PostgreSQL, Redis и хранилище файлов.
  • Доменное имя должно указывать на публичный IPv4-адрес сервера до запуска Caddy.
  • Секреты хранятся в файле .env с ограниченными правами доступа.
  • Один backup должен включать не только PostgreSQL, но и загруженные файлы, конфигурацию и ключи.

2. Содержание

Статья построена как практический сценарий для владельца нового VPS. Сначала определяются ресурсы и требования, затем выполняются подготовка сервера, установка Plane, публикация через HTTPS и настройка регулярных резервных копий.

  1. Подготовить DNS-запись для домена.
  2. Создать отдельного администратора и запретить вход по паролю.
  3. Установить Docker и системные утилиты.
  4. Развернуть Plane из официального источника.
  5. Настроить внешний reverse proxy и TLS.
  6. Проверить приложение и автоматизировать backup.

3. Что мы настраиваем и зачем

Схема: 3. Что мы настраиваем и зачем
Схема: 3. Что мы настраиваем и зачем

Что такое Plane

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

Self-hosted-вариант запускается в инфраструктуре владельца. Данные хранятся на его сервере, а доступ к приложению осуществляется через собственный домен. Это особенно удобно, когда необходимо контролировать расположение данных, сетевые правила, сроки хранения или интеграцию с внутренними сервисами.

Что будет работать после настройки

После выполнения инструкции пользователь сможет открыть, например, https://plane.example.com, создать рабочее пространство и пригласить участников команды. Plane будет работать в Docker-контейнерах, а Caddy примет внешний HTTPS-трафик и передаст его приложению по локальному интерфейсу.

На сервере также появятся:

  • PostgreSQL для постоянных данных приложения;
  • Redis для очередей и кэширования;
  • объектное хранилище для вложений и пользовательских файлов;
  • Docker volumes для данных, которые должны переживать пересоздание контейнеров;
  • журналы контейнеров и системные журналы для диагностики.

Cloud-managed или self-hosted

Критерий Облачная версия Self-hosted на VPS
Установка Практически не требуется Нужно обслуживать сервер и контейнеры
Контроль данных Зависит от поставщика Данные находятся под контролем владельца
Стоимость Обычно зависит от числа пользователей Основной расход — сервер, диски и backup
Обновления Выполняются автоматически или поставщиком Нужно планировать самостоятельно
Интеграция Ограничена возможностями сервиса Можно настроить VPN, SSO, SMTP и внутренние webhook

Cloud-managed вариант рациональнее, если нет времени на эксплуатацию Linux-сервера. Self-hosted Plane на VPS выбирают, когда важны контроль, предсказуемая инфраструктура, независимость от лимитов SaaS или размещение рядом с другими внутренними сервисами.

Предварительные условия

Нужен домен или поддомен, например plane.example.com. Создайте DNS-запись типа A, указывающую на IPv4 сервера. Если используется IPv6, добавьте AAAA-запись только после проверки, что сервер и firewall корректно обслуживают IPv6.

# Проверяем, что DNS уже указывает на нужный адрес
dig +short plane.example.com A

До получения сертификата домен должен быть доступен из интернета по портам 80 и 443. Если перед сервером находится внешний firewall, его правила также должны разрешать эти порты.

4. Какой VPS-конфиг нужен под эту задачу

Схема: 4. Какой VPS-конфиг нужен под эту задачу
Схема: 4. Какой VPS-конфиг нужен под эту задачу

Plane — не статическая HTML-страница. Self-hosted установка запускает несколько контейнеров, базу данных, очередь задач и файловое хранилище. Поэтому ориентироваться только на размер веб-интерфейса неправильно: важны одновременно RAM, быстрый диск и запас CPU для фоновых операций.

Минимальные требования

Ресурс Минимум для тестовой команды Практичный старт для production
CPU 2 vCPU 4 vCPU
RAM 4 ГБ 8 ГБ
Диск 40 ГБ SSD 80–160 ГБ NVMe SSD
Сеть 100 Мбит/с 1 Гбит/с или выше
Адрес Публичный IPv4 Публичный IPv4 и при необходимости IPv6
ОС Ubuntu 24.04 LTS Ubuntu 24.04 LTS

Конфигурация с 4 vCPU и 8 ГБ RAM подходит для небольшой команды, нескольких проектов и умеренного числа вложений. Диск нужно выбирать с учётом роста файлов: база данных Plane обычно занимает меньше места, чем изображения, документы и другие вложения.

В качестве одного из вариантов можно взять VPS с 4 vCPU, 8 ГБ RAM, NVMe-диском от 80 ГБ и публичным IPv4. Аналогичные параметры можно получить у любого провайдера, если он предоставляет полный root-доступ, виртуализацию с гарантированными ресурсами и возможность делать внешние backup.

Когда нужен dedicated

Dedicated-сервер оправдан не самим фактом запуска Plane, а нагрузкой и требованиями к изоляции. Он нужен, если на одном сервере одновременно работают Plane, GitLab, CI runners, мониторинг, базы данных и другие ресурсоёмкие сервисы, либо если требуется гарантированная производительность без конкуренции за CPU и диск.

Для команды из нескольких десятков человек dedicated обычно не является обязательным. Сначала стоит измерить потребление CPU, RAM, I/O и размер данных. Переход на выделенный сервер имеет смысл после появления постоянной нагрузки, частого swap или необходимости размещать несколько production-систем.

Выбор локации

Локация влияет на задержку доступа, законодательные требования и стоимость передачи данных. Для команды, находящейся в одном регионе, выбирайте дата-центр с минимальным RTT до пользователей. Для международной команды важнее стабильный маршрут и наличие IPv4, чем разница в несколько миллисекунд.

Резервные копии желательно хранить в другой географической зоне или хотя бы на другом физическом сервере. Backup на том же VPS не защищает от удаления диска, блокировки аккаунта, аппаратной аварии или ошибки администратора.

5. Подготовка сервера

Подключение и создание администратора

Предполагается, что провайдер выдал чистый сервер Ubuntu 24.04 LTS и первоначальный доступ по SSH. Подставьте IP-адрес и имя пользователя, созданного при установке.

# Подключаемся к серверу по SSH
ssh root@SERVER_IP

Создадим пользователя deploy, добавим его в группу sudo и установим публичный ключ. Выполняйте блок от root.

# Создаём отдельного администратора
adduser deploy

# Разрешаем пользователю выполнять административные команды
usermod -aG sudo deploy

# Создаём каталог для SSH-ключей
install -d -m 700 -o deploy -g deploy /home/deploy/.ssh

# Открываем редактор для добавления публичного ключа
nano /home/deploy/.ssh/authorized_keys

# Исправляем владельца и права файла ключей
chown deploy:deploy /home/deploy/.ssh/authorized_keys
chmod 600 /home/deploy/.ssh/authorized_keys

Вставьте в authorized_keys содержимое файла id_ed25519.pub со своего компьютера. После этого проверьте новый вход в отдельном терминале, не закрывая текущую root-сессию.

# Проверяем вход новым пользователем
ssh deploy@SERVER_IP

# Проверяем права sudo
sudo -v

Обновление системы и базовые утилиты

# Обновляем индексы пакетов и устанавливаем исправления
sudo apt update && sudo apt full-upgrade -y

# Устанавливаем инструменты администрирования и диагностики
sudo apt install -y ca-certificates curl gnupg lsb-release \
  unzip jq git vim nano htop tree dnsutils \
  ufw fail2ban unattended-upgrades

Перезагрузите сервер, если обновлялось ядро или системные библиотеки.

# Проверяем необходимость перезагрузки
if [ -f /var/run/reboot-required ]; then sudo reboot; fi

SSH-ключи и отключение паролей

После проверки входа по ключу запретим парольную аутентификацию. Перед изменением конфигурации сохраните копию файла и проверьте синтаксис SSH.

# Сохраняем резервную копию конфигурации SSH
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak

# Открываем конфигурацию SSH
sudo nano /etc/ssh/sshd_config

Убедитесь, что присутствуют следующие параметры:

PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
# Проверяем конфигурацию перед перезапуском
sudo sshd -t

# Применяем настройки SSH
sudo systemctl restart ssh

Firewall

Откроем SSH, HTTP и HTTPS. Если SSH работает на нестандартном порту, замените 22/tcp соответствующим значением. Сначала разрешите SSH и только потом включайте UFW.

# Разрешаем административный доступ и веб-трафик
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

# Включаем firewall с политикой запрета входящих соединений
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw --force enable

# Проверяем активные правила
sudo ufw status verbose

Fail2ban

Fail2ban временно блокирует адреса, с которых выполняются повторные неудачные попытки входа в SSH. Это не заменяет ключи и firewall, но уменьшает шум от автоматических сканеров.

# Создаём локальную конфигурацию jail для SSH
sudo tee /etc/fail2ban/jail.d/sshd.local > /dev/null <<'EOF'
[sshd]
enabled = true
backend = systemd
port = 22
maxretry = 5
findtime = 10m
bantime = 1h
EOF

# Перезапускаем fail2ban и включаем автозапуск
sudo systemctl enable --now fail2ban

# Проверяем состояние SSH-защиты
sudo fail2ban-client status sshd

6. Установка ПО — пошагово

Схема: 6. Установка ПО — пошагово
Схема: 6. Установка ПО — пошагово

Установка Docker Engine

На Ubuntu лучше использовать официальный apt-репозиторий Docker, а не старые пакеты из стандартного репозитория. В 2026 году ориентируйтесь на актуальную стабильную ветку Docker Engine 28.x или более новую, если она уже опубликована для Ubuntu 24.04.

# Удаляем конфликтующие неофициальные пакеты
sudo apt remove -y docker.io docker-doc docker-compose podman-docker containerd runc || true

# Создаём каталог для ключей apt
sudo install -m 0755 -d /etc/apt/keyrings

# Загружаем официальный ключ Docker
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
  sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

# Делаем ключ доступным для apt
sudo chmod a+r /etc/apt/keyrings/docker.gpg

# Добавляем репозиторий Docker для текущего релиза Ubuntu
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# Обновляем список пакетов и устанавливаем Docker Compose Plugin
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io \
  docker-buildx-plugin docker-compose-plugin

# Разрешаем запуск Docker без sudo для пользователя deploy
sudo usermod -aG docker "$USER"

# Проверяем версии
docker --version
docker compose version

После добавления пользователя в группу Docker нужно открыть новую SSH-сессию. Группа docker фактически предоставляет root-права, поэтому добавляйте в неё только доверенных администраторов.

# Проверяем работу Docker после нового входа
docker run --rm hello-world

Загрузка официального установщика Plane

Self-hosted-дистрибутив Plane публикуется проектом Plane в GitHub. Установщик создаёт каталог развёртывания, Docker Compose-файлы и шаблон переменных окружения. Перед применением в production проверьте release notes и совместимость выбранной версии.

# Переходим в домашний каталог администратора
cd ~

# Создаём отдельный каталог для Plane
mkdir -p ~/plane
cd ~/plane

# Загружаем официальный установщик из репозитория Plane
curl -fsSL -o setup.sh \
  https://raw.githubusercontent.com/makeplane/plane/master/deploy/selfhost/install.sh

# Делаем установщик исполняемым
chmod 700 setup.sh

# Просматриваем установщик перед запуском
less setup.sh

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

# Запускаем интерактивную установку Plane
./setup.sh install

В зависимости от версии установщика команда может называться ./setup.sh install, ./setup.sh start или иметь меню действий. Используйте название, которое показывает сам скрипт при запуске с параметром помощи.

# Показываем доступные действия конкретной версии установщика
./setup.sh --help

Получение исходной конфигурации

Обычно в каталоге Plane появляются файл .env и один или несколько Compose-файлов. Если installer создал только шаблон, скопируйте его в рабочий файл и заполните значения.

# Показываем содержимое каталога развёртывания
find ~/plane -maxdepth 2 -type f -printf '%p\n' | sort

# Если присутствует шаблон, создаём рабочий файл окружения
[ -f ~/plane/.env.example ] && cp ~/plane/.env.example ~/plane/.env

# Ограничиваем доступ к секретам
chmod 600 ~/plane/.env

Запуск контейнеров

Перед первым запуском изучите итоговую конфигурацию. Это позволяет увидеть имена сервисов, проброшенные порты и volume, который нужно включить в резервное копирование.

# Переходим в каталог Plane
cd ~/plane

# Проверяем и разворачиваем итоговую Compose-конфигурацию
docker compose config > /tmp/plane-compose-resolved.yml

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

Первый запуск может занять несколько минут: Docker скачивает образы, создаёт сеть и volumes, а приложение выполняет миграции базы данных.

# Проверяем список контейнеров и их состояние
docker compose ps

# Смотрим последние 200 строк общего журнала
docker compose logs --tail=200

# Следим за журналом конкретного сервиса при необходимости
docker compose logs -f --tail=100 web

Имя сервиса web зависит от версии Compose-файла. Если такого сервиса нет, сначала выполните docker compose config --services и выберите фактическое имя frontend или proxy-сервиса.

7. Конфигурация

Схема: 7. Конфигурация
Схема: 7. Конфигурация

Переменные окружения

Все секреты Plane должны находиться в .env или в защищённом менеджере секретов. Не вставляйте пароли PostgreSQL, ключи JWT и SMTP-пароли непосредственно в Compose-файл, Git-репозиторий или shell-скрипт, доступный всем пользователям.

Названия переменных зависят от конкретного релиза Plane. Не удаляйте обязательные значения из файла, который создал installer. Заполните домен и сгенерируйте случайные секреты там, где это предусмотрено шаблоном.

# Генерируем криптографически случайные значения для собственных секретов
openssl rand -hex 32
openssl rand -base64 48

# Открываем файл переменных окружения
nano ~/plane/.env

# Проверяем права на файл секретов
stat -c '%A %U:%G %n' ~/plane/.env

В конфигурации должны быть корректно заданы публичный URL приложения, домен, параметры PostgreSQL, Redis, SMTP и объектного хранилища. Публичный URL должен использовать окончательный HTTPS-адрес, например:

WEB_URL=https://plane.example.com
CORS_ALLOWED_ORIGINS=https://plane.example.com

Точные имена переменных нужно сверять с документацией и шаблоном выбранного релиза. Не следует механически добавлять несуществующие переменные: приложение может проигнорировать их и продолжить работу с небезопасными значениями по умолчанию.

Публикация через Caddy

Caddy автоматически получает сертификат Let’s Encrypt и продлевает его. Сначала Plane можно запустить на локальном порту, недоступном из интернета, а наружу выставить только Caddy.

Проверьте, какой сервис Plane публикует HTTP-порт:

# Показываем сервисы и опубликованные порты
cd ~/plane
docker compose config --services
docker compose ps

Если Compose-файл публикует контейнерный порт 80 на хостовый порт 80, измените привязку на локальный адрес и свободный порт, например 127.0.0.1:8080:80. Делайте это в поддерживаемом override-файле или способом, предусмотренным installer. Пример override ниже применим только если сервис действительно называется proxy и внутри слушает порт 80.

services:
  proxy:
    ports:
      - "127.0.0.1:8080:80"

Если внутренний сервис имеет другое имя, замените proxy. Не публикуйте напрямую наружу PostgreSQL, Redis, MinIO или административные порты.

# Применяем изменение и пересоздаём контейнеры
cd ~/plane
docker compose up -d

# Проверяем локальный HTTP-ответ
curl -I http://127.0.0.1:8080

Установим Caddy из официального репозитория.

# Добавляем официальный ключ репозитория Caddy
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | \
  sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg

# Добавляем репозиторий Caddy
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | \
  sudo tee /etc/apt/sources.list.d/caddy-stable.list

# Устанавливаем Caddy 2.x
sudo apt update
sudo apt install -y caddy

Создайте конфигурацию /etc/caddy/Caddyfile. Замените домен на свой.

plane.example.com {
    reverse_proxy 127.0.0.1:8080

    encode zstd gzip

    header {
        X-Content-Type-Options nosniff
        X-Frame-Options SAMEORIGIN
        Referrer-Policy strict-origin-when-cross-origin
    }

    log {
        output file /var/log/caddy/plane-access.log
        format json
    }
}
# Проверяем синтаксис Caddyfile
sudo caddy validate --config /etc/caddy/Caddyfile

# Включаем запуск Caddy вместе с системой
sudo systemctl enable --now caddy

# Перезапускаем после изменения конфигурации
sudo systemctl reload caddy

# Проверяем состояние reverse proxy
sudo systemctl status caddy --no-pager

Если DNS уже настроен, Caddy отправит запрос на получение сертификата автоматически. Проверка должна выполняться с внешнего компьютера или через публичный домен:

# Проверяем HTTPS и заголовки ответа
curl -I https://plane.example.com

# Проверяем TLS-сертификат
curl -vI https://plane.example.com 2>&1 | grep -E 'SSL connection|subject:|issuer:'

Проверка состояния Plane

Откройте домен в браузере, создайте первоначальную учётную запись и проверьте создание проекта, задачи и вложения. Затем посмотрите контейнеры и последние ошибки.

# Проверяем, что контейнеры не находятся в состоянии restarting
cd ~/plane
docker compose ps

# Ищем ошибки в журналах за последний запуск
docker compose logs --since=10m 2>&1 | grep -iE 'error|fatal|panic' || true

# Проверяем место на диске
df -h
docker system df

Команда ping проверяет только ICMP-связность и не подтверждает работу HTTPS. Для приложения полезнее использовать curl, проверку статуса контейнеров и просмотр журналов.

8. Бэкапы и обслуживание

Что необходимо сохранять

Минимальный backup Plane состоит из четырёх частей: дампа PostgreSQL, пользовательских файлов, файла .env и Compose-конфигурации. Если используется MinIO или другое S3-совместимое хранилище, его bucket с вложениями нельзя заменять одним только дампом базы данных.

  • PostgreSQL: рабочие пространства, проекты, задачи, пользователи и настройки.
  • Object storage: изображения, документы, аватары и вложения.
  • Конфигурация: .env, Compose-файлы и Caddyfile.
  • Ключи: только если они нужны для расшифровки или доступа к backup.

Не полагайтесь на snapshot VPS как на единственный backup. Snapshot удобен для быстрого отката, но при проблеме с самим аккаунтом или хранилищем он может стать недоступен вместе с сервером.

Установка restic

Restic шифрует backup до отправки во внешнее хранилище. В примере используется S3-совместимый bucket. Создайте bucket заранее, отдельного пользователя с минимальными правами и сохраните пароль репозитория вне сервера либо в защищённом secret-хранилище.

# Устанавливаем restic из репозитория Ubuntu
sudo apt update
sudo apt install -y restic

# Создаём каталоги для временных дампов и скриптов
sudo install -d -m 700 /var/backups/plane
sudo install -d -m 700 /usr/local/sbin

Скрипт резервного копирования

Имена сервисов базы данных и объектного хранилища нужно определить по выводу docker compose config --services. В примере база называется plane-db. Если в вашей версии имя другое, измените переменную DB_SERVICE.

sudo nano /usr/local/sbin/plane-backup.sh
#!/usr/bin/env bash
set -Eeuo pipefail

PLANE_DIR="/home/deploy/plane"
BACKUP_DIR="/var/backups/plane"
STAMP="$(date -u +%Y-%m-%dT%H-%M-%SZ)"
DB_SERVICE="plane-db"

# Эти переменные лучше загрузить из отдельного root-only файла
source /root/.config/plane-backup/restic.env

mkdir -p "$BACKUP_DIR/$STAMP"

# Создаём логический дамп PostgreSQL внутри контейнера
cd "$PLANE_DIR"
docker compose exec -T "$DB_SERVICE" \
  pg_dumpall -U postgres | gzip -9 > "$BACKUP_DIR/$STAMP/postgres.sql.gz"

# Сохраняем конфигурацию и Compose-файлы
tar --exclude='.log' -czf "$BACKUP_DIR/$STAMP/config.tar.gz" \
  -C "$PLANE_DIR" .env docker-compose.yml docker-compose.yaml 2>/dev/null || true

# Сохраняем Caddyfile
tar -czf "$BACKUP_DIR/$STAMP/caddy.tar.gz" \
  -C /etc caddy/Caddyfile

# Отправляем зашифрованные данные во внешнее S3-хранилище
restic backup "$BACKUP_DIR/$STAMP" \
  --tag plane \
  --host "$(hostname -f)"

# Удаляем локальные временные файлы старше двух дней
find "$BACKUP_DIR" -mindepth 1 -maxdepth 1 -type d -mtime +2 -exec rm -rf {} +

# Удаляем старые удалённые backup по политике хранения
restic forget --tag plane --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune

Создайте файл с параметрами restic. Доступ к нему должен иметь только root.

# Создаём каталог для параметров резервного копирования
sudo install -d -m 700 /root/.config/plane-backup

# Создаём файл с URL S3 и паролем restic
sudo nano /root/.config/plane-backup/restic.env

# Пример содержимого; замените значения на свои
RESTIC_REPOSITORY="s3:https://s3.example.net/plane-backups"
RESTIC_PASSWORD="GENERATE_AND_STORE_A_LONG_RANDOM_PASSWORD"
AWS_ACCESS_KEY_ID="BACKUP_ACCESS_KEY"
AWS_SECRET_ACCESS_KEY="BACKUP_SECRET_KEY"

# Ограничиваем права
sudo chmod 600 /root/.config/plane-backup/restic.env

# Делаем скрипт исполняемым
sudo chmod 700 /usr/local/sbin/plane-backup.sh

# Инициализируем репозиторий один раз
sudo bash -c 'source /root/.config/plane-backup/restic.env && restic init'

Проверьте backup вручную до добавления cron.

# Запускаем полный backup и проверяем код возврата
sudo /usr/local/sbin/plane-backup.sh

# Показываем список снимков restic
sudo bash -c 'source /root/.config/plane-backup/restic.env && restic snapshots --tag plane'

Планировщик cron

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

# Открываем root crontab
sudo crontab -e
# Ежедневно в 02:30 по времени сервера
30 2    /usr/local/sbin/plane-backup.sh >> /var/log/plane-backup.log 2>&1

Проверка восстановления

Не тестируйте восстановление поверх единственной production-базы. Создайте временный сервер или отдельный Compose-проект, восстановите последний snapshot, импортируйте PostgreSQL и проверьте вход, проекты и вложения.

# Проверяем целостность данных restic
sudo bash -c 'source /root/.config/plane-backup/restic.env && restic check'

# Показываем содержимое последнего снимка
sudo bash -c 'source /root/.config/plane-backup/restic.env && restic ls latest --tag plane'

Обновления Plane

Перед обновлением прочитайте release notes конкретной версии и сделайте backup. Для небольшой команды безопаснее maintenance window: остановить запись, обновить образы, дождаться миграций и проверить основные сценарии.

# Создаём backup перед обновлением
sudo /usr/local/sbin/plane-backup.sh

# Загружаем новые образы и пересоздаём контейнеры
cd /home/deploy/plane
docker compose pull
docker compose up -d

# Проверяем миграции и состояние сервисов
docker compose ps
docker compose logs --tail=200

Не используйте бездумно docker system prune -a: команда может удалить образы, необходимые для быстрого отката. Не удаляйте volumes, пока не подтверждено наличие внешнего backup и понятен процесс восстановления.

9. Troubleshooting и FAQ

Почему домен открывается с ошибкой 502 Bad Gateway?

Сначала проверьте, что Caddy работает: systemctl status caddy. Затем убедитесь, что Plane действительно слушает локальный порт командой curl -I http://127.0.0.1:8080. Если ответа нет, выполните docker compose ps и docker compose logs --tail=200 в каталоге Plane. Частая причина — неверное имя сервиса в override-файле, остановившийся контейнер или указание Caddy на порт, который не опубликован на хосте.

Сертификат Caddy не выпускается. Что проверить?

Проверьте A-запись командой dig +short plane.example.com и сравните адрес с публичным IP сервера. Порты 80 и 443 должны быть разрешены в UFW, внешнем firewall и security group провайдера. Если включён прокси CDN, убедитесь, что он не блокирует HTTP-проверку или временно используйте DNS-настройку без проксирования. Подробная причина находится в journalctl -u caddy -e.

Контейнеры Plane постоянно перезапускаются. Что делать?

Посмотрите статус и код завершения: docker compose ps, затем журналы конкретного контейнера: docker compose logs --tail=300 SERVICE. Проверьте свободную RAM и диск через free -h и df -h. Типичные причины — недостаток памяти, неправильные секреты, недоступная база, незаполненные обязательные переменные или повреждённый volume. Не удаляйте volumes до анализа логов и проверки backup.

Какой VPS-конфиг минимально подойдёт?

Для ознакомительной установки можно начать с 2 vCPU, 4 ГБ RAM и 40 ГБ SSD, но это оставляет небольшой запас для Docker, базы и обновлений. Практичный минимальный production-вариант — 4 vCPU, 8 ГБ RAM и SSD от 80 ГБ. Если планируются большие вложения, размер диска выбирайте по прогнозу роста данных и отдельно храните backup. Для стабильной работы важнее быстрый SSD и гарантированные ресурсы, чем большое число виртуальных ядер.

Что выбрать — VPS или dedicated для этой задачи?

Для одного Plane и небольшой команды обычно достаточно VPS. Dedicated нужен, когда сервер одновременно обслуживает тяжёлые CI-задачи, GitLab, базы данных, мониторинг и другие приложения, либо требуется полная изоляция ресурсов. Решение лучше принимать по измерениям: если RAM постоянно заканчивается, появляется swap, а диск испытывает высокую I/O-нагрузку, сначала можно увеличить VPS, а затем рассмотреть dedicated.

Можно ли не использовать Caddy и оставить встроенный reverse proxy?

Можно, если официальный deployment Plane уже предоставляет поддерживаемый proxy-контейнер и корректную конфигурацию TLS. Внешний Caddy удобен тем, что отделяет управление сертификатом от приложения и позволяет не публиковать внутренние сервисы. Нельзя одновременно занимать порт 80 несколькими proxy: выберите один внешний входной слой. В любом варианте должны быть открыты только 80 и 443, а базы и очереди должны оставаться во внутренней Docker-сети.

Где посмотреть причину ошибки входа или неработающей задачи?

Проверьте журналы frontend, API и фоновых workers, а не только Caddy. Список точных имён сервисов выводится командой docker compose config --services. Затем используйте docker compose logs --since=15m SERVICE. Если ошибка связана с письмами, проверьте SMTP-переменные и доступность сервера отправки. Если не загружаются вложения, проверьте настройки объектного хранилища и наличие свободного места.

Что делать, если закончился диск?

Сначала определите источник: df -h, du -xhd1 /var/lib/docker и docker system df. Проверьте размер uploads, PostgreSQL и журналов. Старые локальные backup можно удалить только после подтверждения, что внешняя копия доступна. Логи Docker следует ограничить через поддерживаемые параметры Compose или daemon configuration. Не выполняйте удаление volumes и не используйте aggressive prune без понимания, какие данные хранятся в каждом томе.

Как безопасно обновлять Plane без простоя?

Полностью бесперебойное обновление зависит от конкретной версии Plane и схемы базы, поэтому для одной VPS лучше использовать короткое окно обслуживания. Сделайте внешний backup, проверьте release notes, скачайте новые образы, примените docker compose up -d и проверьте миграции. Для минимизации простоя можно заранее скачать образы командой docker compose pull. Перед обновлением сохраните текущий tag образов и Compose-файлы для отката.

10. Выводы и следующие шаги

Схема: 10. Выводы и следующие шаги
Схема: 10. Выводы и следующие шаги

В результате Plane работает на собственном VPS в Docker, доступен по HTTPS через Caddy, а сервер защищён SSH-ключами, UFW и fail2ban. Конфигурация, PostgreSQL и пользовательские файлы включены в зашифрованный внешний backup с регулярной проверкой восстановления.

Дальше полезно включить мониторинг CPU, RAM, диска и срока действия backup, затем вынести объектное хранилище на отдельный S3-совместимый сервис при росте вложений. При увеличении команды можно добавить SMTP, SSO, отдельный сервер базы данных или масштабировать VPS после анализа реального потребления ресурсов.

Был ли этот гайд полезен?

Ваш отзыв помогает нам улучшать гайды.

Поделиться записью:

Отправьте гайд тому, кому он может пригодиться.

Telegram VKVK WhatsApp Facebook LinkedIn XX

развёртывание plane на vps: self-hosted управление проектами, ssl и резервные копии
support_agent
Valebyte Support
Usually replies within minutes
Hi there!
Send us a message and we'll reply as soon as possible.