В этом руководстве небольшой HTTP-сервис пройдёт путь от папки на вашем компьютере до адреса в продакшене со своим доменом и базой Postgres рядом. По пути вы увидите всё, что платформа приложений делает за вас: сборку, проверку работоспособности, предварительные версии релизов, перевод в продакшен, переменные, тома и откат. Kubernetes, аккаунт в реестре образов и 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 здесь не для красоты. После каждого развёртывания платформа выполняет проверку работоспособности и только потом переключает трафик на новый релиз. Отдельный эндпоинт, который отвечает быстро и не обращается к базе, делает развёртывания спокойными и предсказуемыми. Рядом с сервером положите 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 может быть сколь угодно сложным, в том числе многоэтапным.
2. Создаём приложение#
Приложение — это именованное место, куда попадают релизы. Оно создаётся один раз: с портом, который слушает программа, и путём проверки работоспособности. В CLI это одна строка, она показана на следующем шаге вместе с развёртыванием. Порты, проверку работоспособности и лимиты ресурсов можно изменить позже.
В консоли откройте Проекты, выберите проект или создайте его кнопкой Новый проект и нажмите Создать на холсте. Выберите Пустой сервис, если будете отправлять сборку со своего компьютера, или Образ Docker, чтобы запустить готовый образ; Репозиторий GitHub собирает сервис из репозитория и доступен в раннем доступе, по запросу. Укажите имя и порт — сервис появится на холсте, а справа откроется панель для всех следующих шагов.
3. Разворачиваем#
Выполните команды ниже в папке проекта. CLI упаковывает папку, отправляет её на сборочные серверы, собирает Dockerfile, запускает контейнер нового релиза и ждёт, пока он пройдёт проверку работоспособности.
# 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 и итог. Каждое развёртывание создаёт новый неизменяемый релиз, а предыдущие остаются на месте — поэтому потом откат происходит мгновенно.
В консоли то же самое находится под кнопкой Деплой в панели сервиса: Новый релиз принимает ссылку на образ, Собрать из исходников загружает папку, а Развернуть из GitHub собирает ветку там, где развёртывание из GitHub включено (ранний доступ, по запросу). Вкладка Деплои показывает каждый релиз с логом сборки.
4. Проверяем релиз#
Релиз работает рядом с продакшеном, но, как и любое новое приложение, он приватный: публичного адреса у него пока нет. Проверьте его из терминала: inquir apps logs web --tail 100 покажет вывод контейнера, а inquir apps status web — релизы, эндпоинты и имена хостов. То же самое есть на вкладке Деплои в панели сервиса, вместе с логами каждого релиза. Когда у приложения появится публичный адрес (шаг 5), новые релизы до перевода в продакшен будут доступны и по адресу предварительной версии: по нему можно проверить релиз, прогнать смоук-тесты или отправить ссылку коллеге.
5. Переводим в продакшен#
Релиз становится продакшеном, когда вы переводите его туда. Возьмите id релиза из вывода развёртывания или из inquir apps status web и выполните inquir apps promote <releaseId>. Трафик на адресе продакшена переключается на новый контейнер, а предыдущий релиз остаётся доступен для отката. Переводить релизы в продакшен намеренно могут только владельцы и администраторы рабочего пространства, чтобы предварительная версия не стала продакшеном случайно.
У каждого приложения есть приватный адрес внутри рабочего пространства, web.apps.internal, доступный только вашим приложениям и функциям. Публичный доступ включается явно: inquir apps update web --ingress public выдаёт публичное имя хоста с TLS. Внутренние API держите приватными и открывайте только то, что нужно пользователям.
В консоли: вкладка Деплои, выберите релиз и нажмите В продакшен. Публичный доступ — в разделе Настройки → Сеть, где кнопка Создать адрес сразу выдаёт публичное имя хоста. Если хотите, чтобы каждое успешное развёртывание сразу попадало в продакшен, запускайте его с флагом --promote.
6. Конфигурация и секреты#
Конфигурация хранится в переменных, а не в образе. Откройте вкладку Переменные сервиса, добавьте ключ, например LOG_LEVEL=debug, и нажмите Сохранить и развернуть заново: запустится новый релиз с новым окружением, пройдёт проверку работоспособности и примет трафик. Значения хранятся в зашифрованном виде и никогда не попадают в логи сборки.
В терминале передавайте --set KEY=VALUE при создании или обновлении приложения (inquir apps create, inquir apps update). Переменные, которые различаются в предварительной версии и в продакшене, тоже лучше держать вне образа: тогда один и тот же релиз везде работает одинаково — именно поэтому откат безопасен.
7. Добавляем базу данных#
Базы данных — тоже приложения: они создаются из шаблонов, в которых уже есть постоянный том и приватный TCP-эндпоинт. Создайте Postgres (шаблон сразу запускает первый релиз) и подключите базу к сервису:
# A Postgres from the template: a persistent volume and a private TCP endpoint. # The template starts its first release by itself; there is nothing to deploy. inquir apps create db --template postgres # 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 # backups and the plan's schedule, where available 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 в переменные сервиса; его подхватит следующий релиз. На холсте два сервиса теперь соединены линией, а панель базы показывает приватный адрес, учётные данные и вкладку Бэкапы. Платформа копирует том базы по расписанию — сейчас каждые 6 часов — целостным снимком с короткой заморозкой контейнера; inquir apps backups db показывает список снимков, а восстановление выполняется в один клик. Приложение, тома которого вместе занимают больше 2 ГБ, пока не копируется — храните собственную копию этих данных. Руководство по Node.js и Postgres в разделе о резервных копиях показывает, как безопасно проводить рискованные изменения схемы.
8. Свой домен#
Привяжите имя хоста командой inquir apps domain web shop.example.com. Команда напечатает DNS-записи, которые нужно создать у регистратора: CNAME для имени хоста и TXT-запись, подтверждающую владение. Когда записи сохранены у DNS-провайдера, выполните ту же команду с --verify. Проверка обращается напрямую к DNS-серверам вашего домена, поэтому ждать обновления публичных DNS-кэшей не нужно (некоторым провайдерам нужно несколько минут, чтобы опубликовать изменение); маршрутизация переключится, а сертификат выпустится автоматически. То же самое есть в разделе Настройки → Свои домены, где записи показаны рядом со статусом.
9. Если что-то пошло не так#
Неудачный релиз отменяется командой inquir apps rollback web или кнопкой Откатить на вкладке Деплои: за секунды продакшен снова указывает на предыдущий релиз, пересборка не нужна. Что проверить, если развёртывание не проходит:
- Проверка работоспособности не проходит. Контейнер запускается, но платформа не может достучаться до порта. Убедитесь, что программа слушает
0.0.0.0и порт изprocess.env.PORT, а не жёстко заданное значение, и что путь проверки отвечает до любой медленной инициализации. - Сборка падает. Лог сборки на вкладке Деплои содержит полный вывод Docker. Чаще всего в снимок не попали нужные файлы (проверьте
.dockerignore) или установка для продакшена пропустила dev-зависимость. - Адрес предварительной версии работает, а домен отвечает 404. Приложение всё ещё приватное. Откройте публичный доступ в разделе Настройки → Сеть или флагом
--ingress public, затем проверьте, что DNS-записи подтверждены. - Падает при запуске из-за отсутствующей переменной. Переменные, добавленные после развёртывания, попадают только в следующий релиз. Нажмите Сохранить и развернуть заново или выполните
inquir apps redeploy web.
Куда дальше#
Справочник по приложениям описывает TCP-эндпоинты, консоль, лимиты ресурсов и API за каждой командой. На странице CLI перечислены все флаги. А если части вашей системы лучше подходит код, который запускается по событиям и не требует своего сервера, следующее руководство создаёт и разворачивает функцию за тем же шлюзом.