xboctploy
Легковесная CLI-утилита на Rust для централизованного деплоя хобби-проектов (Node.js, Rust) с локального ПК на слабую VPS по SSH.
- сборка, тесты и линтеры выполняются локально — CPU VPS не тратится
- артефакты передаются по SFTP (без rsync, работает на Windows/Linux/macOS)
- сервисные команды (
pm2 restart,systemctl restart) запускаются по SSH - fail-fast: упавший шаг немедленно останавливает деплой (ADR-005)
Установка
cargo install --path .
Требуется Rust 1.88+. Кроссплатформенно: Windows (MSVC), Linux, macOS.
Быстрый старт
xboctploy --list # показать проекты из конфига
xboctploy --dry-run demo # напечатать план деплоя без выполнения
xboctploy demo # задеплоить проект demo
Вывод:
deploying 'demo'
[Local] running: npm run build... Success! (1.2s)
[SFTP] transferring dist to /var/www/pages... Done! (14 file(s), 231.5 KiB) (829ms)
[Remote] running: pm2 restart pages... Success! (102ms)
Deploy successful! (total 2.3s)
Конфигурация
Файл ищется по цепочке:
--config PATH, если указан явно;./deploy.tomlв текущей папке — удобно держать рядом с проектом и в тестах;- глобальный
~/.config/xboctploy/deploy.toml— запуск «из любой папки».
Схема:
[servers.my-vps] # профиль сервера: описывается один раз
host = "195.0.2.10" # алиас из ~/.ssh/config или IP
port = 2222
user = "deploy"
key_path = "~/.ssh/id_ed25519"
[projects.my-node-app]
server = "my-vps" # ссылка на профиль
workdir = "~/code/my-node-app" # где выполнять локальные команды (~ разворачивается)
[projects.my-node-app.env] # переменные для локальных команд сборки
PUBLIC_BASE_PATH = "/my-node-app"
[projects.my-node-app.local] # шаги сборки на вашей машине
commands = ["npm ci", "npm run build"]
[[projects.my-node-app.sync]] # что заливать на сервер
source = "dist" # файл или папка (относительно workdir)
target = "/var/www/pages"
[projects.my-node-app.remote] # команды управления на сервере
commands = ["pm2 restart pages"]
Проект может задать параметры подключения и напрямую (host, user, port,
key_path вместо server) — тогда они имеют приоритет над профилем.
Приоритет параметров SSH: проект → [servers.<name>] → ~/.ssh/config → дефолт.
Windows-нюанс TOML
В basic-строках "..." бэкслеши — escape-символы, путь C:\Users сломает парсинг.
Для путей Windows используйте литеральные строки '...':
workdir = 'C:\code\my-node-app'
или прямые слэши C:/code/my-node-app.
Аутентификация
Цепочка (первый успешный способ используется):
- ssh-agent: OpenSSH-агент (named pipe на Windows /
SSH_AUTH_SOCKна Unix), затем Pageant; перебираются все ключи агента; - файловый ключ
key_path→identity_file→~/.ssh/id_rsa(ключи с passphrase пока не поддерживаются); - иначе — понятная ошибка.
Проверка host key — TOFU поверх вашего ~/.ssh/known_hosts: неизвестный хост
доверяется и запоминается, смена ключа сервера — громкая ошибка (MITM-защита).
Переменные окружения (.env)
Если рядом с workdir проекта есть .env, его переменные (KEY=VALUE, #
комментарии, кавычки, префикс export) доступны всем локальным командам.
.env не копируется на сервер, если не указан явно в sync.
Приоритет источников: [env] из deploy.toml → .env → окружение ОС.
# .env
NODE_ENV=production
API_TOKEN="secret"
export DB_URL=postgres://localhost/app
Разработка
just test # fmt + clippy -D warnings + cargo test
just run # деплой из test/deploy.toml (в git не входит)