MAATRIX / Блог / Windmill на Ubuntu 24.04: пошаговая установка

Windmill на Ubuntu 24.04: пошаговая установка

MAATRIX

У любой команды рано или поздно скапливается десяток разрозненных скриптов: один чистит базу по расписанию, другой дёргает внешний API, третий формирует отчёт, который приходится запускать руками и присылать в чат. Превращать каждый такой скрипт в отдельный сервис с формой ввода и логами — дорого по времени. Windmill решает именно эту задачу: берёт готовый код на Python, TypeScript, Go, Bash, SQL или PowerShell и за пару минут превращает его в веб-форму, кнопку в интерфейсе или шаг в workflow с расписанием. Ниже — пошаговая установка Windmill на Ubuntu 24.04 через Docker Compose: от чистой системы до рабочего инстанса с HTTPS и бэкапом.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →

Что такое Windmill и зачем ставить его на свой сервер

Windmill — open-source платформа для внутренних инструментов, workflow-оркестрации и фоновых задач. Ядро написано на Rust, а сами скрипты пишутся на привычных языках: Python, TypeScript/Deno, Go, Bash, SQL, PowerShell. По сути это гибрид того, что раньше приходилось собирать из трёх разных продуктов — конструктора внутренних панелей вроде Retool, оркестратора workflow вроде n8n и планировщика задач вроде cron с человеческим интерфейсом. Скрипт, workflow из нескольких шагов или простое веб-приложение с формами — всё это описывается в UI Windmill и хранится в его собственной базе вместе с версиями, логами запусков и правами доступа.

Держать такую платформу у себя, а не в чужом облаке, есть смысл по трём причинам. Через Windmill проходят учётные данные к вашим базам, API-ключи внешних сервисов, токены доступа — и приватнее держать их на сервере, который контролируете вы, а не в SaaS с непрозрачной политикой хранения секретов. Дальше — отсутствие лимитов: облачные тарифы workflow-платформ обычно считают запуски и активные сценарии, а на своём сервере ограничение только в ресурсах железа. И наконец контроль над обновлениями: вы сами решаете, когда переходить на новую версию, не полагаясь на чужой график релизов.

По ресурсам Windmill не самый лёгкий инструмент — кроме основного сервера ему нужна PostgreSQL и минимум один воркер, поэтому для комфортного старта стоит закладывать 2 ядра и 4 ГБ памяти, а не довольствоваться минимальным тарифом. Конкретная цифра — не измеренный бенчмарк, а ориентир: реальное потребление зависит от числа воркеров и того, насколько тяжёлые задачи вы на них вешаете. У MAATRIX подходящий VPS на Ubuntu 24.04 арендуется с оплатой из России картой, по СБП, криптой или токеном MAAT, а локацию можно взять под задачу — US ближе к зарубежным API, RU меньше пинг до российских сервисов.

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

Начните с обновления системы и базового фаервола — Windmill будет открыт наружу через HTTPS, и порт 22 должен остаться доступен только для SSH:

apt update && apt upgrade -y
apt install -y git curl
ufw allow 22/tcp && ufw allow 80,443/tcp && ufw enable

Если вы ещё не переходили на вход по ключу вместо пароля, сделайте это до открытия сервиса наружу — подробный разбор есть в статье про настройку фаервола ufw. Заведите домен (или поддомен вроде windmill.example.com) и направьте его A-запись на IP сервера — он понадобится и для HTTPS, и для корректных ссылок, которые Windmill генерирует в уведомлениях и веб-хуках.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Шаг 2. Установка Docker и получение конфигурации Windmill

Поставьте Docker и плагин Compose официальным скриптом:

curl -fsSL https://get.docker.com | sh
docker compose version

Дальше нужен сам конфиг стека. Проще всего склонировать официальный репозиторий — в нём уже лежит рабочий docker-compose.yml с нужным набором сервисов:

git clone https://github.com/windmill-labs/windmill.git
cd windmill
cp .env.example .env

В комплекте идут несколько сервисов, и понимать их роль важно до первого запуска:

  • db — контейнер PostgreSQL, единственное хранилище Windmill: скрипты, флоу, логи запусков, секреты, права доступа — всё лежит здесь;
  • windmill_server — веб-интерфейс, API и планировщик;
  • windmill_worker (обычно несколько реплик) — забирают задачи из очереди в Postgres и исполняют скрипты;
  • windmill_worker_native — облегчённый воркер для встроенных типов задач вроде HTTP-запросов, без запуска отдельного интерпретатора на каждый вызов;
  • lsp — сервер автодополнения кода в редакторе скриптов;
  • caddy — реверс-прокси, который может сам выпустить HTTPS-сертификат для указанного домена.

Состав сервисов и их имена периодически меняются от релиза к релизу, поэтому перед запуском стоит свериться с актуальным docker-compose.yml в репозитории — сам принцип (сервер + воркеры + Postgres) остаётся неизменным. Общие практики работы с production-конфигурацией Docker Compose разобраны в статье про подготовку compose-файла для продакшена.

Шаг 3. Переменные окружения

Откройте .env и приведите в порядок ключевые переменные. Первым делом — пароль базы данных, он используется и контейнером db, и строкой подключения DATABASE_URL:

# .env
POSTGRES_PASSWORD=замените-на-свой-длинный-пароль
DATABASE_URL=postgres://postgres:замените-на-свой-длинный-пароль@db/windmill?sslmode=disable
BASE_URL=https://windmill.example.com

BASE_URL — не косметика: по нему Caddy выпускает сертификат, а Windmill формирует ссылки в письмах, ответах API и адресах веб-хуков. Если оставить значение по умолчанию (localhost или пример из шаблона), внешние сервисы не смогут корректно достучаться до ваших флоу через веб-хук. Пароль базы данных, заданный «из коробки» в .env.example, обязательно замените — это первое, что проверяют при попытке достучаться до открытого API Postgres.

Шаг 4. Запуск и первый вход

Когда .env настроен и DNS-запись домена уже распространилась, поднимайте стек:

docker compose up -d
docker compose logs -f windmill_server

В логах должно появиться сообщение о старте сервера и подключении к базе. Дайте Postgres и миграциям схемы отработать — при первом запуске это может занять чуть больше времени, чем при обычном рестарте. Откройте домен в браузере: Windmill предложит создать первого пользователя, который автоматически становится суперадмином инстанса. Задайте надёжный пароль — через этот аккаунт открывается управление всеми workspace, секретами и правами остальных пользователей.

После входа создайте свой первый workspace (логическое пространство для скриптов и флоу — по аналогии с проектом или командой) и попробуйте импортировать простой Python-скрипт или написать его прямо в редакторе. Запустите тестовый job и проверьте, что он появляется в истории запусков с логом — это подтверждает, что сервер, база и хотя бы один воркер работают согласованно.

Шаг 5. HTTPS и реверс-прокси

Если вы используете включённый в comprose-файл Caddy и указали реальный домен в BASE_URL, сертификат Let's Encrypt выпустится автоматически при первом обращении по HTTPS — никаких дополнительных действий не требуется, порты 80 и 443 просто должны быть открыты и указывать на сервер. Это самый простой путь для одиночного инстанса Windmill на отдельном сервере.

Если на сервере уже крутится свой Nginx, Traefik или Caddy для других сервисов, отключите встроенный caddy-контейнер и проксируйте на windmill_server, оставив его порт доступным только на 127.0.0.1. Логика та же, что для любого self-hosted сервиса за прокси — подробная схема с автоматическим сертификатом разобрана в статье про Caddy с авто-HTTPS. Держать порт базы данных и сам windmill_server закрытыми от прямого доступа из интернета — обязательное условие: наружу должен смотреть только прокси на 443.

Шаг 6. Воркеры и масштабирование под нагрузку

Отдельный воркер, а не общий процесс — осознанное решение: если тяжёлый скрипт зависнет или упадёт с ошибкой памяти, это не положит интерфейс и не остановит остальные задачи в очереди. Воркеры забирают job'ы из очереди в Postgres по тегам — тег соответствует языку (python3, bash, go, powershell) или произвольной группе, которую вы задаёте сами для маршрутизации нагрузки на конкретные машины.

Масштабирование горизонтальное — увеличиваете число реплик сервиса windmill_worker:

docker compose up -d --scale windmill_worker=3

Для небольшой команды с редкими задачами хватает одного-двух воркеров и windmill_worker_native для лёгких встроенных операций вроде HTTP-запросов и трансформаций данных — они выполняются в самом процессе воркера без запуска отдельного интерпретатора под каждый вызов, поэтому быстрее и экономнее по ресурсам. Если у вас появляются CPU-тяжёлые Python-скрипты (обработка изображений, парсинг больших файлов), логично вынести их на отдельный воркер с собственным тегом и не смешивать с быстрыми служебными задачами — тогда долгий job не будет держать очередь для всех остальных.

Шаг 7. Автозапуск, обновление и бэкап

Политика restart: unless-stopped, уже прописанная в официальном compose-файле, поднимает стек после перезагрузки сервера сама — проверьте это, перезапустив сервер и убедившись, что все контейнеры вернулись в строй. Обновление сводится к скачиванию свежих образов и пересозданию контейнеров:

docker compose pull
docker compose up -d

Перед обновлением на новую мажорную версию загляните в changelog проекта — релизы иногда приносят миграции схемы базы, которые применяются автоматически при старте, но лучше знать об этом заранее. Единственное, что действительно нельзя терять — данные в томе Postgres: там лежат все скрипты, флоу, история запусков и секреты. Регулярный pg_dump тома базы и хранение копии за пределами сервера превращают любое неудачное обновление в проблему на пять минут, а не в потерю месяцев работы. Общий подход к резервному копированию Docker-томов и типичные ошибки разобраны в статье про бэкап Docker volume.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Чем Windmill отличается от n8n?

n8n делает упор на визуальную сборку сценариев из готовых узлов-интеграций с внешними сервисами. Windmill ближе к платформе для разработчиков: вы пишете код на Python, TypeScript, Go, Bash или SQL, а Windmill сам превращает его в UI, API-эндпоинт или шаг флоу с расписанием. Если у вас уже есть скрипты и хочется их упаковать в инструмент — обычно проще именно с Windmill; сравнение похожих задач для n8n есть в статье про установку n8n на Ubuntu 24.04.

Обязательна ли именно PostgreSQL из comprose-файла?

Да, Windmill жёстко завязан на Postgres как единственное хранилище состояния — своей встроенной базы нет. Можно указать в DATABASE_URL внешний управляемый Postgres вместо контейнера db, тогда сам сервис db из compose можно отключить.

Windmill бесплатен?

Ядро распространяется под открытой лицензией и самостоятельный хостинг бесплатен без ограничения числа запусков или воркеров. Часть функций (расширенный SSO, некоторые enterprise-возможности) доступна только в платной редакции — для установки, описанной здесь, они не нужны.

Можно ли обойтись без HTTPS для внутреннего использования?

Технически да, если сервис доступен только внутри приватной сети или через VPN. Но через Windmill проходят пароли и API-ключи к другим системам, поэтому даже для внутреннего инстанса разумнее закрыть его либо HTTPS, либо доступом только по VPN, а не голым HTTP наружу.

Как перенести Windmill на другой сервер?

Достаточно перенести том с данными Postgres (или сделать pg_dump/pg_restore) и файл .env с настройками — сам стек воссоздаётся из того же docker-compose.yml командой docker compose up -d.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →