В этом туториале мы проведём небольшой HTTP-сервис от папки на ноутбуке до production-адреса с собственным доменом и Postgres рядом. По пути вы увидите всё, что делает за вас плоскость Applications: сборку, health-check, превью-релизы, промоут, переменные, тома и откат. Ни Kubernetes, ни аккаунта в registry, ни YAML-файлов не понадобится.
1. Пишем сервис#
Приложением может быть любая программа, которая слушает TCP-порт. Единственный контракт: прочитать порт из переменной окружения PORT и отвечать на нём по HTTP. Создайте папку, выполните npm init -y и сохраните это как server.js:
const http = require('node:http'); // The platform tells the container which port to listen on. const port = Number(process.env.PORT || 3000); http.createServer((req, res) => { if (req.url === '/healthz') { // The health check: anything below 500 means "serving". res.writeHead(200, { 'content-type': 'text/plain' }); res.end('ok'); return; } res.writeHead(200, { 'content-type': 'application/json' }); res.end(JSON.stringify({ hello: 'world', at: new Date().toISOString() })); }).listen(port, () => console.log(`listening on ${port}`));
Маршрут /healthz тут не для красоты. После каждого деплоя платформа опрашивает health-check и только потом переключает трафик на новый релиз. Отдельный эндпоинт, который отвечает быстро и не трогает базу, делает деплой скучным в лучшем смысле слова. Рядом с сервером положите Dockerfile:
FROM node:22-alpine WORKDIR /app COPY package*.json ./ RUN npm ci --omit=dev COPY . . ENV NODE_ENV=production EXPOSE 3000 CMD ["node", "server.js"]
Это весь проект: два файла плюс package.json. Если у вас уже есть сервис со своим Dockerfile, берите его как есть. Сборка идёт на платформе, поэтому Dockerfile может быть сколь угодно сложным, включая multi-stage.
2. Создаём приложение#
Приложение — это именованный слот, в который приземляются релизы. Создаётся один раз: с портом, который слушает программа, и путём health-check. В CLI это одна строка, она показана на следующем шаге вместе с деплоем. Порты, health-check и лимиты ресурсов можно менять потом.
В дашборде откройте Applications, выберите или создайте проект и нажмите + Create на канвасе. Empty service — если будете пушить сборку со своей машины, GitHub repository — чтобы собирать из репозитория, Docker image — чтобы запустить готовый образ. Укажите имя и порт, и сервис появится на канвасе, а справа откроется панель, где живёт всё дальнейшее.
3. Деплоим#
Выполните команды ниже внутри папки проекта. Деплой упаковывает папку, отправляет её на билдеры, собирает Dockerfile, поднимает контейнер нового релиза, ждёт health-check и печатает превью-URL.
# 1. The application: an HTTP service on port 3000, health-checked at /healthz inquir apps create web --port 3000 --health-path /healthz # 2. Build the Dockerfile in this directory on the platform's builders and # release the image. The command waits for the health check to pass and # prints the preview URL of the new release. inquir apps deploy web # 3. Look around inquir apps status web # releases, endpoints, hostnames inquir apps logs web --tail 100 # container logs # 4. Take production (owner or admin), then give it a public domain inquir apps promote <releaseId> inquir apps update web --ingress public
Следите за логом: snapshot ваших файлов, build с выводом Docker, start, health и, наконец, адрес превью. Каждый деплой создаёт новый неизменяемый релиз, а предыдущие остаются на месте — именно поэтому откат потом мгновенный.
В дашборде то же самое живёт под кнопкой Deploy в панели сервиса: New release принимает ссылку на образ, Build from source загружает папку, Deploy from GitHub собирает ветку. Вкладка Deployments показывает каждый релиз с его логом сборки.
4. Проверяем превью#
Откройте превью-URL из вывода. Он обслуживает только новый релиз, так что можно покликать, прогнать смоук-тесты или отправить ссылку коллеге до того, как её увидит кто-то ещё. Если что-то не так, inquir apps logs web --tail 100 покажет вывод контейнера, а inquir apps status web — релизы, эндпоинты и хосты. В панели сервиса то же самое лежит во вкладках Logs и Deployments.
5. Промоутим в production#
Релиз становится production, когда вы его промоутите. Возьмите id релиза из вывода деплоя или из inquir apps status web и выполните inquir apps promote <releaseId>. Трафик на production-адресе переключается на новый контейнер; предыдущий релиз остаётся доступен для отката. Промоут намеренно разрешён только владельцам и админам воркспейса, чтобы превью не превратилось в production случайно.
У каждого приложения есть приватный адрес внутри воркспейса, web.apps.internal, до которого дотягиваются только ваши приложения и функции. Публичный доступ включается явно: inquir apps update web --ingress public выдаёт публичный хост с TLS. Внутренние API держите приватными и открывайте только то, что нужно пользователям.
В дашборде: вкладка Deployments, выбираете релиз, Promote. Публичный доступ — в Settings → Networking, где Generate Domain тут же выдаёт публичный хост. Если хотите, чтобы каждый успешный деплой сразу шёл в production, деплойте с --promote.
6. Конфигурация и секреты#
Конфигурация живёт в переменных, а не в образе. Откройте вкладку Variables сервиса, добавьте ключ вроде LOG_LEVEL=debug и нажмите Save & redeploy: стартует новый релиз с новым окружением, проходит health-check и забирает трафик. Значения хранятся зашифрованными и никогда не попадают в логи сборки.
Из терминала передавайте --set KEY=VALUE при создании или обновлении приложения. Переменные, которые отличаются между превью и production, тоже лучше держать вне образа: тогда один и тот же релиз везде работает одинаково — именно поэтому откат безопасен.
7. Добавляем базу данных#
Базы данных — тоже приложения, создаваемые из шаблонов, у которых уже есть постоянный том и приватный TCP-эндпоинт. Создайте Postgres, задеплойте и подключите к сервису:
# A Postgres from the template: a persistent volume and a private TCP endpoint inquir apps create db --template postgres inquir apps deploy db # Wire it into the service: DATABASE_URL lands in web's variables inquir apps connect db web inquir apps deploy web # the next release picks the variable up # Later on inquir apps backups db # snapshots: automatic every 6 h, newest 7 kept inquir apps domain web shop.example.com # bind your hostname, prints the DNS records inquir apps domain web shop.example.com --verify # once the records are live: routed, TLS issued inquir apps rollback web # back to the previous production release
Команда connect кладёт готовый DATABASE_URL в переменные сервиса; следующий релиз его подхватывает. На канвасе два сервиса теперь соединены ребром, а панель базы показывает приватный адрес, учётные данные и вкладку Backups. Снимки делаются каждые шесть часов, хранятся семь последних; восстановление — один клик или inquir apps backups db в терминале.
8. Собственный домен#
Привяжите хост командой inquir apps domain web shop.example.com. Команда напечатает DNS-записи, которые нужно создать у регистратора: CNAME для хоста и TXT-запись, подтверждающая владение. Когда они разрезолвятся, выполните ту же команду с --verify: маршрутизация переключится, сертификат выпустится автоматически. То же самое есть в Settings → Networking → Custom domains, записи показаны рядом со статусом.
9. Если что-то пошло не так#
Плохой релиз отменяется командой inquir apps rollback web или кнопкой Roll back во вкладке Deployments: production за секунды снова указывает на предыдущий релиз, пересборка не нужна. Что проверить, если деплой не проходит:
- Health-check не зеленеет. Контейнер стартует, но платформа не достучалась до порта. Убедитесь, что программа слушает
0.0.0.0иprocess.env.PORT, а не захардкоженное значение, и что health-путь отвечает до любой медленной инициализации. - Сборка падает. Лог сборки во вкладке Deployments содержит полный вывод Docker. Чаще всего в снимок не попали файлы (проверьте
.dockerignore) или production-установка пропустила dev-зависимость. - На превью работает, на домене 404. Приложение всё ещё приватное. Откройте ingress в Settings → Networking или через
--ingress public, затем проверьте, что DNS-записи верифицированы. - Падает на старте из-за отсутствующей переменной. Переменные, добавленные после деплоя, попадают только в следующий релиз. Нажмите Save & redeploy или выполните
inquir apps redeploy web.
Куда дальше#
Справочник по приложениям описывает TCP-эндпоинты, консоль, лимиты ресурсов и API за каждой командой. Страница CLI перечисляет все флаги. А если части вашей системы лучше быть событийным кодом без сервера, следующий туториал пишет и деплоит функцию и ставит её за тот же шлюз.