Перейти к содержимому
Документация

Руководство: разверните первое приложение

В этом руководстве небольшой HTTP-сервис пройдёт путь от папки на вашем компьютере до адреса в продакшене со своим доменом и базой Postgres рядом. По пути вы увидите всё, что платформа приложений делает за вас: сборку, проверку работоспособности, предварительные версии релизов, перевод в продакшен, переменные, тома и откат. Kubernetes, аккаунт в реестре образов и YAML-файлы не понадобятся.

1. Пишем сервис#

Приложением может быть любая программа, которая слушает TCP-порт. Единственный контракт: прочитать порт из переменной окружения PORT и отвечать на нём по HTTP. Создайте папку, выполните npm init -y и сохраните это как server.js:

server.jsjs
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:

Dockerfilebash
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, запускает контейнер нового релиза и ждёт, пока он пройдёт проверку работоспособности.

terminalbash
# 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 (шаблон сразу запускает первый релиз) и подключите базу к сервису:

terminalbash
# 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 перечислены все флаги. А если части вашей системы лучше подходит код, который запускается по событиям и не требует своего сервера, следующее руководство создаёт и разворачивает функцию за тем же шлюзом.