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

Отримати VPS arrow_forward
eco Початковий Туторіал

Встановлення Kestra на VPS: оркестрація завдань, Docker, PostgreSQL, SSL і розклади

calendar_month Oct 26, 2026 schedule 18 хв. читання visibility 28 переглядів
Установка Kestra на VPS: оркестрация задач, Docker, PostgreSQL, SSL и расписания
info

Потрібен сервер для цього гайду? Ми пропонуємо виділені сервери та VPS у 50+ країнах з миттєвим налаштуванням.

Потрібен сервер для цього гайду?

Розгорніть VPS або виділений сервер за хвилини.

Встановлення Kestra на VPS: оркестрація завдань, Docker, PostgreSQL, SSL і розклади

Коротко

Kestra — self-hosted платформа для оркестрації завдань, ETL-пайплайнів, API-автоматизації та розкладів. У цьому посібнику ви розгорнете Kestra на Ubuntu VPS через Docker Compose, підключите PostgreSQL, закриєте інтерфейс HTTPS-проксі Caddy, створите перший workflow із cron-розкладом і налаштуєте резервне копіювання.

  • Для невеликого production-інстансу достатньо VPS із 2 vCPU, 4 ГБ RAM і 40–60 ГБ NVMe.
  • Kestra та PostgreSQL працюватимуть в окремих Docker-контейнерах.
  • Caddy автоматично випустить і продовжить TLS-сертифікат Let’s Encrypt.
  • Усі паролі зберігатимуться у файлі .env, а не в Docker Compose або workflow.
  • Перший workflow запускатиметься вручну та за cron-розкладом.
  • Бекапи PostgreSQL і конфігурації запускатимуться через cron і надсилатимуться до зовнішнього сховища.

Що ми налаштовуємо і навіщо

Kestra — це платформа оркестрації, у якій завдання описуються декларативними YAML-файлами. Вона підходить для запуску ETL-процесів, обробки файлів, синхронізації SaaS-сервісів, викликів API, регулярних звітів, обслуговування інфраструктури, запуску Python-скриптів, SQL-запитів і контейнерних job.

На відміну від простого cron, Kestra зберігає історію запусків, параметри, логи, статуси завдань, помилки та повторні спроби. Веб-інтерфейс дає змогу вручну запускати workflow, передавати вхідні дані, переглядати виконання покроково та повторно запускати невдалі процеси.

Після виконання інструкції на сервері працюватимуть такі компоненти:

  • Kestra Server із веб-інтерфейсом та API;
  • PostgreSQL 16 як надійна база даних для workflow, черг, execution history і метаданих;
  • Docker Compose для керування сервісами;
  • Caddy як reverse proxy з автоматичним HTTPS;
  • Firewall UFW, SSH-ключі та Fail2ban для базового захисту VPS;
  • регулярний backup PostgreSQL, конфігурації та persistent-даних Kestra;
  • приклад workflow із ручним запуском і cron-розкладом.

Що можна автоматизувати через Kestra

Сценарій Приклад workflow Частота запуску
ETL та аналітика Забрати CSV із S3, очистити дані, завантажити в PostgreSQL Щогодини або щодня
DevOps-автоматизація Перевірити бекапи, зібрати метрики, надіслати сповіщення Кожні 15 хвилин
Інтеграції SaaS Отримати ліди з форми та створити запис у CRM За webhook або кожні 5 хвилин
Обробка файлів Конвертувати завантажені PDF, вилучити текст і зберегти результат За подією
Звіти Виконати SQL, зібрати звіт і надіслати його в Telegram або email У будні о 09:00

Cloud-managed або self-hosted Kestra

Managed-версія знімає з команди завдання з оновлення, зберігання даних і масштабування, але додає регулярну оплату та залежність від зовнішньої платформи. Self-hosted Kestra на VPS потребує початкового налаштування, зате дає змогу контролювати місце зберігання даних, ліміти, мережеві правила, плагіни, вихідні IP-адреси та витрати.

Self-hosted варіант особливо зручний, якщо workflow працюють із внутрішніми базами, приватними API, закритими Git-репозиторіями або чутливими документами. Сервер можна розмістити в потрібній юрисдикції, підключити до VPN-мережі та обмежити доступ до панелі за IP або додатковою HTTP-аутентифікацією.

Не використовуйте вбудовану H2-базу Kestra для production-розгортання. Вона допустима для локальної розробки й тестів, але для VPS із реальними розкладами, журналами та кількома workflow використовуйте PostgreSQL.

Яка конфігурація VPS потрібна для цього завдання

Навантаження Kestra залежить не стільки від кількості YAML-файлів, скільки від характеру завдань, що виконуються. Якщо workflows лише викликають API та виконують SQL-запити, вимоги помірні. Якщо вони запускають Python-обробку файлів, Docker-контейнери, браузерну автоматизацію або трансформації великих таблиць, потрібні додаткові CPU, RAM і швидкий диск.

Профіль CPU RAM Диск Підходить для
Тестовий 1 vCPU 2 ГБ 25 ГБ NVMe Вивчення інтерфейсу, 1–3 легких workflow
Мінімальний production 2 vCPU 4 ГБ 40–60 ГБ NVMe До десятків API, SQL і cron-завдань на день
Робочий 4 vCPU 8 ГБ 100 ГБ NVMe Команда, паралельні workflow, великі логи
Важкі обчислення 8 vCPU+ 16–32 ГБ+ 200 ГБ NVMe+ Python, Docker jobs, великі файли, ML та ETL

Практичний стартовий варіант — 2 vCPU, 4 ГБ RAM, 60 ГБ NVMe і канал від 100 Мбіт/с. Такий сервер зазвичай витримує сам Kestra, PostgreSQL, Caddy, базові системні служби та помірну кількість одночасно запущених завдань. Якщо ви збираєтеся запускати workflow із Docker-контейнерами, починайте з 4 vCPU і 8 ГБ RAM.

Для такого сценарію можна взяти VPS із зазначеними характеристиками, встановити Ubuntu Server 24.04 LTS і одразу налаштувати DNS-запис для майбутнього домену Kestra.

Коли потрібен dedicated-сервер

Виділений сервер потрібен не для самого інтерфейсу Kestra, а для важких workload. Переходьте на dedicated, якщо регулярно обробляєте десятки гігабайтів файлів, паралельно запускаєте багато контейнерів, потребуєте гарантованих CPU-ресурсів, високого IOPS або зберігаєте великий обсяг execution-логів локально.

Також dedicated має сенс, якщо Kestra запускає внутрішні CI-процеси, браузери Playwright, конвертацію відео, моделі машинного навчання або масштабні Spark-завдання. Для звичайної автоматизації API, SQL і бекапів VPS простіше, дешевше та легше масштабувати вертикально.

Як вибрати локацію

Локація впливає на затримку до бази даних, зовнішніх API та користувачів веб-інтерфейсу. Якщо Kestra підключається до бази в європейському дата-центрі, обирайте VPS поруч із нею. Якщо завдання працюють із локальними API або корпоративною мережею, важливішими є близькість до VPN-шлюзу та стабільна маршрутизація.

Для TLS-сертифіката та публічних webhook важливе інше: доменне ім’я має вказувати на публічний IP сервера, а порти 80 і 443 мають бути доступними з інтернету. До встановлення Caddy створіть A-запис, наприклад kestra.example.com, спрямований на IP VPS.

Підготовка сервера

Нижче передбачається чистий сервер з Ubuntu Server 24.04 LTS і доступом через SSH під користувачем root. Виконуйте початкові дії з локального термінала. Замініть SERVER_IP на зовнішню адресу свого VPS.

Створення адміністратора та налаштування SSH-ключа

Спочатку створіть окремого користувача. Не запускайте Docker Compose і не працюйте з Kestra під root без потреби. Ім’я користувача у прикладі — ops.

ssh root@SERVER_IP
adduser ops
usermod -aG sudo ops

Додайте публічний SSH-ключ для нового користувача. Команду нижче запускають на локальному комп’ютері, де вже є ключ ~/.ssh/id_ed25519.pub.

ssh-copy-id ops@SERVER_IP
ssh ops@SERVER_IP

Переконайтеся, що вхід новим користувачем працює, і лише після цього вимикайте вхід root та автентифікацію за паролем. Відкрийте другий SSH-сеанс, щоб не втратити доступ у разі помилки конфігурації.

sudo nano /etc/ssh/sshd_config.d/99-hardening.conf
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
KbdInteractiveAuthentication no
X11Forwarding no
AllowUsers ops

Перевірте синтаксис конфігурації та перезапустіть SSH-службу.

sudo sshd -t && sudo systemctl restart ssh

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

Оновіть пакети до актуального стану. Для production-сервера корисно ввімкнути автоматичні security-оновлення, але оновлення Docker і Kestra краще виконувати окремо у контрольоване вікно.

sudo apt update && sudo apt full-upgrade -y
sudo apt install -y ca-certificates curl gnupg lsb-release \
  ufw fail2ban unattended-upgrades jq htop vim cron

Перевірте версію ядра та потребу в перезавантаженні. Якщо файл /var/run/reboot-required існує, перезапустіть VPS у відповідне вікно.

test -f /var/run/reboot-required && cat /var/run/reboot-required
sudo reboot

Firewall UFW і Fail2ban

На сервері мають бути відкриті лише SSH, HTTP і HTTPS. PostgreSQL не публікується назовні на порт 5432: Kestra звертається до нього через внутрішню Docker-мережу.

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status verbose

Fail2ban блокуватиме IP-адреси після повторних невдалих спроб входу через SSH. Створіть мінімальне локальне налаштування jail.

sudo tee /etc/fail2ban/jail.d/sshd.local > /dev/null <<'EOF'
[sshd]
enabled = true
maxretry = 5
findtime = 10m
bantime = 1h
EOF
sudo systemctl enable --now fail2ban
sudo fail2ban-client status sshd

Якщо ви використовуєте нестандартний SSH-порт, спочатку дозвольте його в UFW і перевірте новий вхід, а вже потім закривайте старий порт. Не змінюйте SSH-порт як єдиний захід безпеки: ключі, вимкнення root-login і Fail2ban важливіші.

اِ

Встановлення ПЗ — покроково

Для розгортання використовуємо Docker Engine 27+ і Docker Compose Plugin v2. Kestra буде закріплена за конкретним тегом образу, а не за latest. Це захищає від випадкового оновлення під час перезапуску контейнерів.

Встановлення Docker Engine і Docker Compose

Додайте офіційний ключ і репозиторій Docker для Ubuntu. Команди виконуються від імені користувача ops через sudo.

sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
  sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

Додайте репозиторій, оновіть індекс пакетів і встановіть Docker Engine, CLI та Compose Plugin.

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

sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io \
  docker-buildx-plugin docker-compose-plugin

Додайте користувача до групи Docker. Після виконання команди вийдіть із SSH-сеансу та підключіться знову: членство в групі застосовується лише для нового сеансу.

sudo usermod -aG docker ops
exit

Після повторного входу перевірте Docker. Контейнер hello-world має завершитися без помилок.

docker --version
docker compose version
docker run --rm hello-world

Група docker фактично надає користувачу права, порівнянні з правами root. Додавайте до неї лише довірених адміністраторів. Для невеликої інсталяції це зручніше, ніж виконувати кожну команду через sudo.

Встановлення Caddy

Caddy прийматиме трафік на портах 80 і 443, автоматично отримуватиме сертифікат Let’s Encrypt і пересилатиме запити до Kestra на localhost. Встановлюйте 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
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | \
  sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update && sudo apt install -y caddy

Перевірте, що Caddy запущено. Поки конфігурацію не змінено, він не проксуватиме Kestra.

sudo systemctl enable --now caddy
sudo systemctl status caddy --no-pager

Створення структури каталогів

Зберігайте конфігурацію проєкту в одному каталозі. У прикладі використовується /opt/kestra. Persistent-дані зберігатимуться в Docker named volumes, а файли конфігурації, експорт workflow і резервні копії — на хості.

sudo mkdir -p /opt/kestra/{config,backups,flows}
sudo chown -R ops:ops /opt/kestra
cd /opt/kestra
pwd

Станом на 2026 рік перед production-встановленням обов’язково звіряйте актуальний стабільний тег у реєстрі образів Kestra та changelog проєкту. У прикладі використовується закріплений тег v0.24.0 як шаблон. Не замінюйте тег на latest; натомість оновлюйте його свідомо після створення резервної копії та перевірки release notes.

Конфігурація Kestra, PostgreSQL і SSL

Підготовка секретів

Згенеруйте окремі довгі паролі для PostgreSQL і базової HTTP-автентифікації Caddy. Файл .env не додавайте до Git і не надсилайте в месенджери. Права 600 забороняють читання файлу іншими користувачами сервера.

cd /opt/kestra
POSTGRES_PASSWORD=$(openssl rand -base64 32 | tr -d '\n')
CADDY_PASSWORD=$(openssl rand -base64 24 | tr -d '\n')

cat > .env <<EOF
POSTGRES_DB=kestra
POSTGRES_USER=kestra
POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
KESTRA_DOMAIN=kestra.example.com
CADDY_USER=admin
CADDY_PASSWORD=${CADDY_PASSWORD}
EOF

chmod 600 .env

Замініть kestra.example.com на власний домен. До запуску Caddy перевірте DNS: команда має повернути публічний IP вашого VPS.

source /opt/kestra/.env
getent ahostsv4 "$KESTRA_DOMAIN"
curl -4 ifconfig.me ; echo

Конфігурація Kestra

Створіть файл config/application.yml. У ньому Kestra використовує PostgreSQL як repository і queue backend. Локальне storage підходить для одного вузла Kestra. У разі переходу до кількох серверів storage потрібно перенести в S3-сумісне об’єктне сховище.

cat > /opt/kestra/config/application.yml <<'EOF'
datasources:
  postgres:
    url: jdbc:postgresql://postgres:5432/${POSTGRES_DB}
    driverClassName: org.postgresql.Driver
    username: ${POSTGRES_USER}
    password: ${POSTGRES_PASSWORD}

kestra:
  repository:
    type: postgres
  queue:
    type: postgres
  storage:
    type: local
    local:
      base-path: /app/storage
  tasks:
    tmp-dir:
      path: /tmp/kestra-wd/tmp
  url: https://${KESTRA_DOMAIN}/
  server:
    basic-auth:
      enabled: false

logger:
  levels:
    io.kestra: INFO
EOF

Basic authentication Kestra вимкнена, оскільки зовнішній доступ захищатиме Caddy. Це спрощує роботу з браузером і API, але означає, що Caddy має залишатися єдиною точкою входу. Порт Kestra не публікується назовні.

Docker Compose для Kestra і PostgreSQL

Створіть compose.yml. PostgreSQL не має секції ports, отже, доступний лише контейнерам у внутрішній Docker-мережі. Kestra публікується на 127.0.0.1:8080, тому Caddy на тому самому сервері може до неї звертатися, а інтернет — ні.

cat > /opt/kestra/compose.yml <<'EOF'
services:
  postgres:
    image: postgres:16.6-alpine
    container_name: kestra-postgres
    restart: unless-stopped
    environment:
      POSTGRES_DB: ${POSTGRES_DB}
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
      interval: 10s
      timeout: 5s
      retries: 10
    networks:
      - kestra_internal

  kestra:
    image: kestra/kestra:v0.24.0
    container_name: kestra
    restart: unless-stopped
    depends_on:
      postgres:
        condition: service_healthy
    environment:
      POSTGRES_DB: ${POSTGRES_DB}
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      KESTRA_DOMAIN: ${KESTRA_DOMAIN}
      JAVA_OPTS: "-Xms512m -Xmx1536m"
    command: server standalone --config /etc/kestra/application.yml
    ports:
      - "127.0.0.1:8080:8080"
    volumes:
      - ./config/application.yml:/etc/kestra/application.yml:ro
      - kestra_storage:/app/storage
      - kestra_workdir:/tmp/kestra-wd
    healthcheck:
      test: ["CMD-SHELL", "wget -qO- http://localhost:8080/health | grep -q UP"]
      interval: 30s
      timeout: 10s
      retries: 10
      start_period: 60s
    networks:
      - kestra_internal

networks:
  kestra_internal:
    name: kestra_internal

volumes:
  postgres_data:
  kestra_storage:
  kestra_workdir:
EOF

Параметр JAVA_OPTS обмежує heap Java до 1,5 ГБ. На VPS із 4 ГБ RAM це розумна відправна точка: решта пам’яті залишається PostgreSQL, ОС і файловому кешу. На сервері з 8 ГБ RAM можна збільшити -Xmx до 3–4 ГБ після спостереження за реальним споживанням пам’яті.

Запустіть сервіси у фоновому режимі та перевірте їхній статус. Перший запуск може тривати кілька хвилин: Kestra створює таблиці та застосовує міграції в PostgreSQL.

cd /opt/kestra
docker compose pull
docker compose up -d
docker compose ps
docker compose logs --tail=100 kestra

Перевірте локальний endpoint до налаштування проксі. Відповіддю може бути JSON або HTTP-перенаправлення залежно від версії Kestra, але кодом не має бути 502 або Connection refused.

curl -I http://127.0.0.1:8080/
docker inspect --format='{{.State.Health.Status}}' kestra
docker inspect --format='{{.State.Health.Status}}' kestra-postgres

Налаштування Caddy і HTTPS

Спочатку створіть bcrypt-хеш пароля для Caddy. Команда запросить пароль, який ви зберегли в .env. Не вставляйте пароль у командний рядок: він залишиться в shell history.

source /opt/kestra/.env
read -rsp "Password for Caddy user ${CADDY_USER}: " INPUT_PASSWORD; echo
CADDY_HASH=$(printf '%s' "$INPUT_PASSWORD" | caddy hash-password --stdin)
unset INPUT_PASSWORD
printf '%s\n' "$CADDY_HASH"

Створіть Caddyfile. Замість змінної в конфігурації вкажіть виведений хеш вручну на місці PASTE_BCRYPT_HASH_HERE. Це безпечніше, ніж залишати пароль у відкритому вигляді.

sudo tee /etc/caddy/Caddyfile > /dev/null <<'EOF'
kestra.example.com {
    encode zstd gzip

    basic_auth {
        admin PASTE_BCRYPT_HASH_HERE
    }

    reverse_proxy 127.0.0.1:8080 {
        header_up Host {host}
        header_up X-Real-IP {remote_host}
        header_up X-Forwarded-For {remote_host}
        header_up X-Forwarded-Proto {scheme}
    }

    log {
        output file /var/log/caddy/kestra-access.log
        format json
    }
}
EOF

Замініть домен і хеш у файлі, створіть каталог журналів, потім перевірте синтаксис. Caddy отримує сертифікат автоматично після успішного завантаження конфігурації, якщо DNS уже вказує на сервер і порт 80 доступний ззовні.

sudo mkdir -p /var/log/caddy
sudo chown caddy:caddy /var/log/caddy
sudo caddy validate --config /etc/caddy/Caddyfile
sudo systemctl reload caddy
sudo systemctl status caddy --no-pager

Відкрийте https://kestra.example.com у браузері. Браузер попросить логін і пароль Caddy, після чого відкриється інтерфейс Kestra. Також перевірте TLS із консолі.

curl -I https://kestra.example.com
sudo journalctl -u caddy -n 100 --no-pager

Перший workflow і cron-розклад

Відкрийте Kestra у браузері, створіть namespace, наприклад company.ops, потім перейдіть до розділу Flows і створіть flow. Для першої перевірки вставте наведений нижче YAML. Він записує повідомлення в логи та спрацьовує кожні 15 хвилин.

id: health_report
namespace: company.ops
description: Проверочный workflow с cron-расписанием

triggers:
  - id: every_15_minutes
    type: io.kestra.plugin.core.trigger.Schedule
    cron: "/15    "
    timezone: "Europe/Moscow"

tasks:
  - id: write_log
    type: io.kestra.plugin.core.log.Log
    message: "Kestra работает. Время запуска: {{ execution.startDate }}"

  - id: shell_check
    type: io.kestra.plugin.scripts.shell.Commands
    commands:
      - "date -u"
      - "echo Workflow finished successfully"

Збережіть workflow, натисніть Execute і відкрийте вкладку Executions. Має з’явитися статус SUCCESS. Потім дочекайтеся часу, кратного 15 хвилинам, або тимчасово замініть cron на для тесту щохвилини. Після перевірки поверніть звичайний розклад.

Не зберігайте токени API, ключі S3, паролі баз даних і webhook secrets безпосередньо в YAML. Використовуйте секрети Kestra, змінні середовища або зовнішній secret manager. Для початку можна створювати secrets через інтерфейс у namespace, а згодом підключити Vault, SOPS або хмарний secrets manager.

Резервні копії та обслуговування

Для відновлення Kestra потрібні не лише дані PostgreSQL. Необхідно зберегти конфігураційні файли, файл Compose, Caddyfile, файл секретів .env і persistent storage. PostgreSQL містить метадані, execution history, налаштування та дані черг; storage містить файли, створені завданнями й плагінами.

Що резервувати Чому Як часто
PostgreSQL dump Workflow metadata, executions, queues, налаштування Щодня, перед оновленням
Docker volume Kestra storage Файли завдань, вкладення та локальні артефакти Щодня
/opt/kestra Compose, YAML-конфігурації, секрети, скрипти Після кожної зміни та щодня
/etc/caddy/Caddyfile HTTPS-проксі та доступ до панелі Після зміни

Локальний backup-скрипт

Наступний скрипт створює стиснений дамп PostgreSQL і архівує каталог конфігурації. Він зберігає останні 14 днів локально. Локальний backup не захищає від видалення VPS, тому потім його потрібно надсилати до S3-сумісного сховища або на окремий сервер.

cat > /opt/kestra/backup-kestra.sh <<'EOF'
#!/usr/bin/env bash
set -euo pipefail

BASE="/opt/kestra"
DATE=$(date +%F_%H-%M-%S)
DEST="${BASE}/backups/${DATE}"

mkdir -p "${DEST}"

cd "${BASE}"
docker compose exec -T postgres pg_dump \
  -U "${POSTGRES_USER}" \
  -d "${POSTGRES_DB}" \
  --format=custom \
  --file="/tmp/kestra_${DATE}.dump"

docker cp kestra-postgres:"/tmp/kestra_${DATE}.dump" \
  "${DEST}/postgres.dump"

docker compose exec -T postgres rm -f "/tmp/kestra_${DATE}.dump"

tar --exclude='backups' \
  --exclude='.git' \
  -czf "${DEST}/kestra-config.tar.gz" \
  -C /opt kestra

docker run --rm \
  -v kestra_kestra_storage:/source:ro \
  -v "${DEST}":/backup \
  alpine:3.20 \
  tar -czf /backup/kestra-storage.tar.gz -C /source .

find "${BASE}/backups" -mindepth 1 -maxdepth 1 -type d -mtime +14 -exec rm -rf {} \;
EOF

chmod 700 /opt/kestra/backup-kestra.sh
cd /opt/kestra && ./backup-kestra.sh
ls -lah /opt/kestra/backups

Ім’я Docker volume зазвичай формується з імені каталогу та імені volume. У цьому випадку проєкт запускається з /opt/kestra, тому volume називається kestra_kestra_storage. Якщо команда повернула помилку про неіснуючий volume, подивіться точну назву через docker volume ls і виправте скрипт.

Надсилання backup до зовнішнього сховища

Для реального захисту зберігайте копії за межами основного VPS. Практичні варіанти: S3-сумісне об’єктне сховище, окремий backup VPS через SSH, Borg repository або Restic repository. Нижче наведено приклад із Restic і S3-сумісним backend. Змінні доступу помістіть в окремий файл із правами 600.

sudo apt install -y restic
sudo tee /etc/kestra-restic.env > /dev/null <<'EOF'
export RESTIC_REPOSITORY="s3:s3.example.net/kestra-backups"
export RESTIC_PASSWORD="CHANGE_TO_A_LONG_UNIQUE_RESTIC_PASSWORD"
export AWS_ACCESS_KEY_ID="CHANGE_ME"
export AWS_SECRET_ACCESS_KEY="CHANGE_ME"
EOF
sudo chmod 600 /etc/kestra-restic.env

Ініціалізуйте репозиторій один раз, потім додайте завантаження даних у кінець backup-скрипта. Перед використанням перевірте параметри endpoint і bucket у вибраного S3-провайдера.

source /etc/kestra-restic.env
restic init
restic backup /opt/kestra/backups
restic snapshots

Додайте щоденний запуск. Cron запускається від користувача ops, тому йому мають бути доступні Docker і файли проєкту.

crontab -e
15 2    /opt/kestra/backup-kestra.sh >> /opt/kestra/backups/backup.log 2>&1
30 2    . /etc/kestra-restic.env && restic backup /opt/kestra/backups && restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune >> /opt/kestra/backups/restic.log 2>&1

Оновлення Kestra без втрати даних

Для одного VPS оновлення — це коротке maintenance window, а не справжнє rolling deployment. Спочатку створіть backup, прочитайте release notes вибраної версії, оновіть тег образу в compose.yml, завантажте образ і перезапустіть лише контейнер Kestra.

cd /opt/kestra
./backup-kestra.sh
docker compose pull kestra
docker compose up -d --no-deps kestra
docker compose logs -f --tail=100 kestra

Після оновлення перевірте інтерфейс, виконання тестового workflow, розклад і міграції бази. Не видаляйте старий образ негайно: він може знадобитися для відкату, якщо нова версія несумісна з використовуваним плагіном. Перед оновленням major-версії PostgreSQL створіть окремий перевірений backup і дотримуйтеся процедури upgrade PostgreSQL, а не просто змінюйте тег контейнера.

Troubleshooting + FAQ

Чому Caddy не отримує TLS-сертифікат і в логах є помилка ACME?

Спочатку перевірте A-запис домену командою getent ahostsv4 kestra.example.com: вона має повертати IP VPS. Потім переконайтеся, що UFW дозволяє TCP-порти 80 і 443, а у провайдера немає додаткового cloud firewall. Перевірте, що інший вебсервер не зайняв порт 80: sudo ss -ltnp | grep ':80\|:443'. Після виправлення DNS і портів виконайте sudo systemctl reload caddy та перегляньте journalctl -u caddy.

Чому в браузері відображається 502 Bad Gateway?

Код 502 означає, що Caddy доступний, але не може підключитися до Kestra. Виконайте docker compose ps у каталозі /opt/kestra: контейнер Kestra має бути у стані running або healthy. Потім перевірте локально curl -I http://127.0.0.1:8080/. Якщо відповіді немає, перегляньте docker compose logs kestra і docker compose logs postgres. Частою причиною є те, що PostgreSQL ще не пройшов healthcheck або вказано неправильні змінні бази.

Kestra постійно перезапускається. Що перевірити?

Почніть із docker compose logs --tail=200 kestra. Помилки підключення до PostgreSQL зазвичай вказують на неправильний пароль, ім’я бази або пошкоджену конфігурацію JDBC. Помилки OutOfMemoryError означають, що VPS не вистачає RAM або параметр -Xmx має надто велике значення. Перевірте пам’ять через free -h і docker stats. На VPS із 2 ГБ RAM краще не запускати PostgreSQL і Kestra з важкими workflows одночасно.

Чому workflow за cron не запускається?

Перевірте, що flow збережено, увімкнено і він не містить помилок у YAML. У cron із п’яти полів вираз /15 * означає кожні 15 хвилин. Переконайтеся, що timezone вказано явно: без нього час може інтерпретуватися в UTC. Відкрийте розділ Executions і знайдіть помилки trigger. Також перегляньте логи: docker compose logs kestra | grep -i schedule. Для тестування тимчасово встановіть розклад щохвилини.

Яка конфігурація VPS підійде мінімально?

Для знайомства з Kestra можна використовувати 1 vCPU, 2 ГБ RAM і 25 ГБ NVMe, але це некомфортний production-варіант. Практичний мінімум для Kestra, PostgreSQL, Caddy і кількох невеликих workflow — 2 vCPU, 4 ГБ RAM і 40–60 ГБ NVMe. Якщо workflow запускають Python, Chromium, Docker-контейнери або обробляють файли, обирайте щонайменше 4 vCPU і 8 ГБ RAM.

Що обрати — VPS чи dedicated для цього завдання?

VPS достатньо для API-автоматизації, SQL-завдань, регулярних звітів, webhook і більшості невеликих ETL-процесів. Dedicated потрібен за постійного значного CPU-навантаження, десятків паралельних container jobs, великих обсягів локальних даних або суворої вимоги до виділених ресурсів. Зазвичай розумніше почати з VPS і стежити за docker stats, навантаженням CPU, IOPS і часом виконання workflow.

Чи можна відкрити PostgreSQL назовні для підключення з DBeaver?

Технічно можна, але для Kestra це зазвичай не потрібно й небезпечно. PostgreSQL має залишатися всередині Docker-мережі. Для адміністративного доступу використовуйте SSH-тунель: ssh -L 5432:127.0.0.1:5432 ops@SERVER_IP, але для цього тимчасово потрібно буде пробросити PostgreSQL лише на localhost. Безпечніший варіант — виконувати SQL-команди через docker compose exec postgres psql безпосередньо на сервері.

Чому backup не бачить Docker volume Kestra?

Спочатку виконайте docker volume ls і знайдіть volume, пов’язаний зі storage. Docker Compose формує ім’я з project name та імені volume, тому воно може відрізнятися від прикладу, якщо проєкт було запущено з іншого каталогу або з параметром -p. Виправте ім’я volume у backup-скрипті. Також перевірте права на каталог /opt/kestra/backups і переконайтеся, що cron запускається від користувача, який входить до групи docker.

Висновки та наступні кроки

Тепер на VPS працює Kestra з PostgreSQL, Docker Compose, HTTPS через Caddy, базовим захистом сервера, cron-розкладами та резервним копіюванням. Інстанс готовий до запуску production-workflow, якщо ви регулярно перевіряєте логи, вільне місце на диску та успішність backup.

  1. Створіть окремі namespace для розробки та production, а секрети перенесіть у Kestra Secrets або зовнішній secret manager.
  2. Налаштуйте сповіщення в Telegram, Slack або email для execution зі статусом FAILED.
  3. За зростання навантаження винесіть storage у S3-сумісне сховище, PostgreSQL — на окремий сервер або managed-базу, а навантаження worker ізолюйте в окремих контейнерах.

Перед будь-яким оновленням Kestra створюйте перевірений backup і тестуйте критичні workflows вручну. Це важливіше за автоматичне оновлення образів і дає змогу швидко виконати відкат у разі несумісності плагінів або змін у конфігурації.

Чи був цей гайд корисним?

Ваш відгук допомагає нам покращувати гайди.

Share this post:

Надішліть гайд тому, кому він може стати в пригоді.

Telegram VKVK WhatsApp Facebook LinkedIn XX

встановлення Kestra на VPS: оркестрація завдань, Docker, PostgreSQL, SSL і розклади
support_agent
Valebyte Support
Usually replies within minutes
Hi there!
Send us a message and we'll reply as soon as possible.