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

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

Установка Kestra на VPS: оркестрация задач, Docker, PostgreSQL, SSL и расписания

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

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

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

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

Установка Kestra на VPS: оркестрация задач, Docker, PostgreSQL, SSL и расписания

TL;DR

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-конфиг нужен под эту задачу

Схема: Какой VPS-конфиг нужен под эту задачу
Схема: Какой 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 будет закреплена на конкретном тегe образа, а не на 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, расписание и миграции базы. Не удаляйте старый образ немедленно: он может пригодиться для отката, если новая версия несовместима с используемым плагином. Перед обновлением PostgreSQL major-версии делайте отдельный проверенный 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 вручную. Это важнее автоматического обновления образов и позволяет быстро откатиться при несовместимости плагинов или изменений в конфигурации.

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

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

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

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

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.