Приложения
Приложение принадлежит окружению проекта и работает контейнером на одной из нод команды. Каждый деплой
создаёт релиз; пять последних сборок хранятся для откатов. См. также сервис apps.
Виды
| Вид |
Для чего |
Получает |
web |
HTTP-сервисы |
адрес, порт, необязательный путь проверки здоровья |
worker |
очереди, боты с long polling, всё без HTTP |
ничего публичного |
bot |
Telegram-боты с вебхуками |
https://bots.xvii.network/<app>, вебхук настраивается сам |
cron |
задачи по расписанию |
разовые запуски по расписанию, вывод хранится 30 дней |
| база данных |
PostgreSQL, MariaDB, Valkey, Redis, MongoDB |
см. Базы данных |
xvii apps create api --project shop --port 3000 --health /healthz
xvii apps create worker --project shop --kind worker
xvii apps create cleanup --project shop --kind cron --schedule "0 3 * * *"
Деплой
xvii apps deploy api --project shop --dir .
xvii apps deploy api --dir . --dockerfile docker/api.Dockerfile
Папка (файлы, которые git не игнорирует, до 512 МБ) собирается на той ноде, где работает приложение, —
по Dockerfile или через Railpack. Реестра между ними нет; на одной ноде идёт одна сборка за раз.
xvii apps deploy api --image ghcr.io/acme/api:1.3
Для приватных образов нужен вход в реестр, см. ниже.
xvii apps import --compose docker-compose.yml --project legacy --deploy
Сервисы становятся приложениями, сервисы баз данных — управляемыми базами с сохранением паролей,
именованные тома остаются томами.
Деплой запускает новый контейнер рядом с живым и переключает трафик, когда тот здоров. На запуск у релиза
пять минут (пятнадцать для самого первого); если не вышло, приложение остаётся на последнем живом релизе.
Ставьте production-зависимости в финальный образ: успешная сборка не значит, что в рантайме есть всё нужное.
xvii apps rollback api # предыдущий релиз
xvii apps rollback api 12 # снова релиз №12
xvii apps stop worker
xvii apps start worker
Проверки здоровья
Для веб-приложений агент ноды запрашивает путь проверки через сеть команды с заголовком Host приложения.
Делайте его дешёвым, независимым от входа и медленных зависимостей: проверка, падающая во время миграции
базы, откатит деплой.
Переменные и файлы
Приложение получает переменные набора своего окружения в env, разрешённые на момент деплоя,
плюс собственные:
- обычные переменные и запечатанные секреты на самом приложении (в панели видны только имена);
- файлы из env, смонтированные только для чтения в
/run/xvii/files;
PORT для веб-приложений, если env его не задаёт.
Изменения переменных применяются при следующем деплое.
Адреса
Приложения в production отвечают на https://<app>.apps.xvii.network, другие окружения — на
https://<app>-<env>.apps.xvii.network (если имя занято, добавляется slug проекта). Свои имена подключаются
в domains.
Логи и метрики
xvii apps logs api -n 50
xvii apps logs api -f --since 10m
Панель показывает CPU, память и перезапуски поминутно за 30 дней. Если живой контейнер перезапускается,
в notify уходит app.crashed.
Превью
xvii apps deploy web --dir . --preview mr-12 --ttl 7d
xvii apps previews web
xvii apps previews web --rm mr-12
Превью — копия приложения со своим адресом, https://<app>-<name>.apps.xvii.network, в окружении preview
проекта. Оно исчезает, если его не деплоили в течение TTL (по умолчанию 7 дней, максимум 30). У ботов
превью нет: они делили бы один токен.
Боты
Приложение вида bot получает обновления Telegram на https://bots.xvii.network/<app id>. Когда релиз
становится живым, apps вызывает setWebhook с BOT_TOKEN из env и собственным секретом, проверяет секрет
в каждом обновлении и передаёт его на порт бота. Бот получает PORT, WEBHOOK_SECRET и WEBHOOK_URL.
Cron
Cron-приложение запускает образ своего релиза разовым контейнером по расписанию (пять полей в UTC или
@hourly, @daily). Один запуск за раз, по умолчанию таймаут час; вывод, код выхода и ошибки хранятся 30
дней; неудачный запуск шлёт cron.failed. Кнопка Запустить сейчас — в панели.
Тома
У приложения могут быть именованные тома. Том привязывает приложение к его ноде, а деплои сначала
останавливают старый контейнер и только потом запускают новый (два контейнера не могут безопасно делить том).
Приватные реестры
echo "$GHCR_TOKEN" | xvii apps registries --team acme --add ghcr.io --user acme-bot
xvii apps registries --team acme
xvii apps registries --team acme --rm ghcr.io
Хватит токена только на чтение (GitHub read:packages, GitLab read_registry). Пароли запечатываются и
никогда не возвращаются из API; ноды используют временный конфиг Docker на каждую загрузку образа.
Шаблоны
xvii apps templates
xvii apps install umami --project site --name stats
Около пятидесяти пяти шаблонов (n8n, Gitea, Forgejo, WordPress, Nextcloud, Directus, NocoDB, Baserow,
Grafana, Mattermost, Open WebUI, Keycloak, Paperless-ngx, Jellyfin…), каждый закреплён на настоящем теге
образа. Установка создаёт его базы данных и приложения; первые данные для входа, если они есть, показываются
один раз.
Переезд на другую ноду
xvii apps move fra1 --project shop --env production
Образы копируются, пока окружение работает; затем оно останавливается, копируются его тома, оно запускается
на новой ноде и проверяется. Если что-то пошло не так, оно снова запускается на старом месте; исходные
данные не трогаются. Ожидайте минуту-две простоя. Нужен администратор команды, а новая нода должна
вписываться в квоту команды.
Лимиты и события
Лимиты apps.apps, apps.memory, apps.cpu, apps.nodes. События app.deployed, app.deploy_failed,
app.crashed, cron.failed, bot.webhook_failed, node.offline и другие (События).