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

Готовые рецепты: скопировать, развернуть, открыть

Готовые к копированию рецепты для самых частых проектов. Каждый — это Dockerfile, inquir.yaml и пара команд: положите файлы в папку проекта, разверните, откройте адрес. Сборка идёт на Inquir, Docker на компьютере не нужен. Каждый рецепт на этой странице развёрнут на Inquir Compute ровно в таком виде.

Что написано в inquir.yaml: на каком порту слушает приложение, какой адрес отвечает, когда оно работает (проверка работоспособности), и сколько ему CPU и памяти. Сервис всегда называется web. Порт в inquir.yaml должен совпадать с портом, который слушает ваш сервер или nginx: если меняете одно, поменяйте и другое.

Выберите рецепт:

Сайт на React (Vite)#

Приложение на React, собранное Vite и отдаваемое nginx. Результат: сайт по адресу https://my-site-xxxxxx.apps.inquir.org с HTTPS; ссылки вида /about открываются напрямую, файлы сжимаются и кешируются браузером. Нужно: Node.js 20.19+ на компьютере — только чтобы создать проект; сам сайт собирается на Inquir.

Полный пример: inquir-examples/static-react-vite на GitHub.

1. Создайте проект

terminalbash
# Skip this if you already have a React project
npm create vite@9.2.1 my-site -- --template react
cd my-site
npm install

2. Добавьте три файла рядом с package.json

Копируйте как есть. Менять может понадобиться только порт (8080 во всех трёх файлах) и папку сборки, если проект собирается не в dist/.

filesbash
my-site/
├── Dockerfile       ← new
├── nginx.conf       ← new
├── inquir.yaml      ← new
├── package.json
├── package-lock.json
├── index.html
└── src/
Dockerfilebash
# Step 1: build the site with Node.js
FROM node:22.23.4-alpine@sha256:fe4f6d74e20370acb04ad889077d14d0f64a9c8ea6a42bc60cddf1e844699914 AS build
WORKDIR /app
COPY package*.json ./
RUN if [ -f package-lock.json ]; then npm ci; else npm install; fi
COPY . .
# Vite writes the finished site to dist/
RUN npm run build

# Step 2: serve the finished files with nginx (runs as a regular user, port 8080)
FROM nginxinc/nginx-unprivileged:1.30.6-alpine@sha256:f5116ed4606f3eb015dd4a8e28cb9b351476dc0ad4bc6e9f93b19cec130cdf03
COPY nginx.conf /etc/nginx/conf.d/default.conf
COPY --from=build /app/dist/ /usr/share/nginx/html/
EXPOSE 8080
nginx.confbash
server {
    listen 8080;                 # the same port as runtime.port in inquir.yaml
    server_name _;
    root /usr/share/nginx/html;
    index index.html;
    absolute_redirect off;

    # Compress text files. gzip_proxied is needed: requests reach nginx through a proxy.
    gzip on;
    gzip_proxied any;
    gzip_vary on;
    gzip_types text/css application/javascript text/javascript application/json image/svg+xml text/plain;

    # Health check: the platform calls it before sending visitors to a new version.
    location = /healthz {
        access_log off;
        default_type text/plain;
        return 200 "ok\n";
    }

    # Files in /assets/ have a hash in their names: browsers may keep them for a year.
    location /assets/ {
        add_header Cache-Control "public, max-age=31536000, immutable";
        try_files $uri =404;
    }

    # Any other path: the file if it exists, otherwise index.html (React Router links work).
    location / {
        add_header Cache-Control "no-cache";
        try_files $uri $uri/ /index.html;
    }
}
inquir.yamlbash
version: 1
services:
  web:                      # always "web"
    runtime:
      port: 8080            # the port nginx listens on (nginx.conf)
      healthcheck:
        type: http
        path: /healthz
      resources:            # plenty for a static site
        cpuVCpus: 0.25
        memoryMb: 128

3. Разверните

Из терминала. Вместо my-site можно взять любое имя — оно войдёт в адрес.

terminalbash
# In the my-site folder
inquir apps create my-site --ingress public   # once: a new app with a public address
inquir apps deploy my-site --promote          # build, start, then send visitors to it

# Build succeeded in 34692ms
# Release ef51e99f is serving
# Production now serves ef51e99f
#   https://my-site-2mk7b4.apps.inquir.org      <- your site

# After every change: the same command
inquir apps deploy my-site --promote

Из консоли, через GitHub.

  1. Отправьте проект вместе с новыми файлами в репозиторий GitHub.
  2. В консоли откройте Приложения, откройте проект (или создайте его кнопкой Новый проект) и выберите Создать → Репозиторий GitHub. В первый раз нажмите Подключить GitHub и разрешите доступ к репозиторию.
  3. Выберите репозиторий и укажите Внутренний HTTP-порт 8080. Ветку, корневую директорию и путь к Dockerfile оставьте как есть, если файлы лежат в корне репозитория.
  4. Нажмите Развернуть приложение. Inquir соберёт проект и запустит его; каждый push в эту ветку разворачивается снова.
  5. Дайте публичный адрес: в приложении откройте Настройки → Сеть → Публичный доступ и нажмите Создать адрес.

Откройте сайт. Адрес печатается в конце развёртывания и виден в разделе Настройки → Сеть. Должна открыться стартовая страница Vite + React; /healthz отвечает ok.

Свой домен. Привяжите его из терминала (ниже) или в разделе Настройки → Сеть, добавьте две показанные DNS-записи там, где купили домен, и подтвердите — HTTPS выпустится автоматически. Подробно: Собственные домены.

terminalbash
# Prints two DNS records to add where you bought the domain
inquir apps domain my-site www.example.com
# Once the records are live: the site answers on your domain, with HTTPS
inquir apps domain my-site www.example.com --verify

Если что-то не работает

  • Сборка падает на npm ci. package-lock.json не совпадает с package.json: выполните npm install у себя и разверните снова. Если сборка упала, команда подскажет, как открыть её журнал.
  • Развёртывание ждёт, а потом не проходит проверку работоспособности. Порт должен совпадать везде: listen в nginx.conf, port в inquir.yaml и, для GitHub, Внутренний HTTP-порт.
  • Страница открывается из меню, но после обновления — 404. В nginx.conf нет последнего блока (try_files … /index.html) или он изменён.
  • Адрес не открывается. Приложение приватно, пока у него нет публичного адреса: inquir apps update <app> --ingress public или Создать адрес в разделе «Настройки → Сеть».
Подробнее

Кеширование. Vite складывает JS и CSS в /assets/ с хешем в имени каждого файла, поэтому браузеры могут хранить их год. index.html отдаётся с no-cache, и посетители видят новую версию сразу после развёртывания.

Сжатие. Оставьте gzip_proxied any: запросы приходят к nginx через прокси платформы, и без этой строки nginx отдаёт файлы несжатыми.

Create React App. Те же файлы; в Dockerfile замените /app/dist/ на /app/build/, а в nginx.conf — /assets/ на /static/.

Next.js как статический сайт. Добавьте output: 'export' в next.config, в Dockerfile замените /app/dist/ на /app/out/, а в nginx.conf — /assets/ на /_next/static/ и последний try_files на $uri $uri.html $uri/ /index.html. Приложение Next.js с серверным рендерингом или API-маршрутами — не статический сайт: оно работает как Node.js-сервер, как в рецепте API на Node.js.

Настройки, которые вшиваются при сборке (VITE_*). Vite записывает значения VITE_* в файлы во время сборки, поэтому переменные запущенного приложения до них не доходят. Укажите их в build.args в inquir.yaml и передайте через Dockerfile:

inquir.yaml + Dockerfilebash
# inquir.yaml: values baked into the site at build time
version: 1
services:
  web:
    build:
      args:
        VITE_API_URL: https://api.example.com
    runtime:
      port: 8080
      healthcheck: { type: http, path: /healthz }

# Dockerfile, in step 1 before "RUN npm run build":
ARG VITE_API_URL
ENV VITE_API_URL=$VITE_API_URL

Статический HTML-сайт#

Самый короткий способ выложить HTML, CSS и JavaScript: nginx отдаёт вашу папку public/. Нужны только файлы.

Полный пример: inquir-examples/static-html на GitHub.

1. Положите сайт в public/ и добавьте два файла

Ничего менять не нужно, если только вы не переименуете папку public/ (тогда поменяйте её и в Dockerfile).

filesbash
my-page/
├── Dockerfile
├── inquir.yaml
└── public/          ← your site: index.html, CSS, images, JS
    ├── index.html
    └── style.css
Dockerfilebash
# nginx that runs as a regular user and listens on port 8080
FROM nginxinc/nginx-unprivileged:1.30.6-alpine@sha256:f5116ed4606f3eb015dd4a8e28cb9b351476dc0ad4bc6e9f93b19cec130cdf03
# Your site: everything in the public/ folder
COPY public/ /usr/share/nginx/html/
EXPOSE 8080
inquir.yamlbash
version: 1
services:
  web:                      # always "web"
    runtime:
      port: 8080            # nginx listens here
      healthcheck:
        type: http
        path: /             # the home page must answer
      resources:
        cpuVCpus: 0.25
        memoryMb: 128
public/index.htmlbash
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>My site</title>
    <link rel="stylesheet" href="/style.css" />
  </head>
  <body>
    <h1>Hello from Inquir Compute</h1>
    <p>Edit public/index.html and deploy again.</p>
  </body>
</html>

2. Разверните

Из терминала. Вместо my-site можно взять любое имя — оно войдёт в адрес.

terminalbash
# In the my-page folder
inquir apps create my-page --ingress public
inquir apps deploy my-page --promote
#   https://my-page-6w79j4.apps.inquir.org      <- your site

Из консоли, без GitHub.

  1. В консоли откройте Приложения и нажмите Создать в браузере. Введите Название приложения и нажмите Создать приложение — откроется редактор в браузере.
  2. Создайте в редакторе файлы из этого рецепта и вставьте их содержимое.
  3. Нажмите Развернуть на нижней панели. Inquir соберёт файлы и запустит сайт.
  4. Дайте публичный адрес: в приложении откройте Настройки → Сеть → Публичный доступ и нажмите Создать адрес.

Откройте сайт по напечатанному адресу. Чтобы изменить его, поправьте файлы и разверните снова.

Свой домен. Привяжите его из терминала (ниже) или в разделе Настройки → Сеть, добавьте две показанные DNS-записи там, где купили домен, и подтвердите — HTTPS выпустится автоматически. Подробно: Собственные домены.

Если что-то не работает

  • Развёртывание не проходит проверку работоспособности. Проверка открывает главную страницу, поэтому public/index.html должен существовать.
  • Одна страница отдаёт 404. На сервере имена файлов различают регистр: About.html и about.html — разные файлы.
  • Адрес не открывается. Приложение приватно, пока у него нет публичного адреса: inquir apps update <app> --ingress public или Создать адрес в разделе «Настройки → Сеть».
Подробнее

Нужны сжатие, долгое кеширование или одностраничное приложение со своими маршрутами? Возьмите nginx.conf из рецепта для React, добавьте в Dockerfile COPY nginx.conf /etc/nginx/conf.d/default.conf и укажите путь проверки /healthz.

API на Node.js (Express)#

API на Express, который слушает порт из переменной PORT — её задаёт Inquir. Результат: https://my-api-xxxxxx.apps.inquir.org/api/hello. Fastify или Hono — так же: Dockerfile тот же, меняется CMD.

Полный пример: inquir-examples/node-api на GitHub.

1. Проект: четыре файла

Выполните npm install один раз, чтобы появился package-lock.json и каждая сборка ставила те же версии. Порт задаётся в inquir.yaml — Inquir передаёт его приложению в PORT; 3000 в server.js — только значение по умолчанию для запуска на своём компьютере.

package.jsonjson
{
  "name": "my-api",
  "private": true,
  "type": "module",
  "scripts": {
    "start": "node server.js"
  },
  "dependencies": {
    "express": "^5.2.1"
  }
}
server.jsjs
import express from 'express';

const app = express();
app.use(express.json());

// Health check: the platform calls it before sending traffic to a new version.
app.get('/healthz', (req, res) => res.send('ok'));

app.get('/api/hello', (req, res) => {
  res.json({ message: 'Hello from Inquir Compute', time: new Date().toISOString() });
});

// The platform sets PORT to runtime.port from inquir.yaml.
const port = Number(process.env.PORT) || 3000;
const server = app.listen(port, () => console.log(`listening on ${port}`));

// Finish open requests before a new version replaces this one.
process.on('SIGTERM', () => server.close(() => process.exit(0)));
Dockerfilebash
FROM node:22.23.4-alpine@sha256:fe4f6d74e20370acb04ad889077d14d0f64a9c8ea6a42bc60cddf1e844699914
WORKDIR /app
ENV NODE_ENV=production
COPY package*.json ./
RUN if [ -f package-lock.json ]; then npm ci --omit=dev; else npm install --omit=dev; fi
COPY . .
# Run as the regular "node" user that the image ships with
USER node
EXPOSE 3000
CMD ["node", "server.js"]
inquir.yamlbash
version: 1
services:
  web:                      # always "web"
    runtime:
      port: 3000            # the port server.js listens on
      healthcheck:
        type: http
        path: /healthz
      resources:
        cpuVCpus: 0.25
        memoryMb: 256

2. Разверните и вызовите

terminalbash
# In the my-api folder (npm install once, so package-lock.json exists)
inquir apps create my-api --ingress public
inquir apps deploy my-api --promote

curl https://my-api-88n5um.apps.inquir.org/api/hello
# {"message":"Hello from Inquir Compute","time":"2026-10-22T18:16:37.443Z"}

Из консоли: те же шаги, что для сайта на React, — GitHub с Внутренним HTTP-портом 3000 или Создать в браузере с этими файлами.

Если что-то не работает

  • Развёртывание не проходит проверку работоспособности. Сервер должен слушать PORT на всех адресах: app.listen(port), а не app.listen(port, 'localhost').
  • Приложение запускается и останавливается. Посмотрите, что оно напечатало: inquir apps logs <app> --tail 100. Если не найден пакет — его нет в файле зависимостей.
  • Адрес не открывается. Приложение приватно, пока у него нет публичного адреса: inquir apps update <app> --ingress public или Создать адрес в разделе «Настройки → Сеть».

API на Python (FastAPI)#

Приложение на FastAPI под uvicorn. Результат: https://my-api-xxxxxx.apps.inquir.org/api/hello и интерактивная документация API на /docs.

Полный пример: inquir-examples/python-fastapi на GitHub.

1. Проект: четыре файла

Новые пакеты добавляйте в requirements.txt с точной версией. Порт задаётся в inquir.yaml; Dockerfile читает его из PORT.

requirements.txtbash
fastapi==0.141.1
uvicorn[standard]==0.54.0
main.pypython
from datetime import datetime, timezone

from fastapi import FastAPI

app = FastAPI()


# Health check: the platform calls it before sending traffic to a new version.
@app.get("/healthz")
def healthz():
    return {"ok": True}


@app.get("/api/hello")
def hello():
    return {"message": "Hello from Inquir Compute", "time": datetime.now(timezone.utc).isoformat()}
Dockerfilebash
FROM python:3.12.15-slim@sha256:cb33f7f771ecec2ef1225cf39b159591a040391bd73e4c01f00fdfc4c47611d2
ENV PYTHONUNBUFFERED=1 PIP_NO_CACHE_DIR=1 PIP_DISABLE_PIP_VERSION_CHECK=1
WORKDIR /app
COPY requirements.txt ./
RUN pip install -r requirements.txt
COPY . .
# Run as a regular user, not root
RUN useradd --create-home --uid 10001 app
USER app
EXPOSE 8000
# The platform sets PORT to runtime.port from inquir.yaml
CMD ["sh", "-c", "exec uvicorn main:app --host 0.0.0.0 --port ${PORT:-8000} --proxy-headers --forwarded-allow-ips='*'"]
inquir.yamlbash
version: 1
services:
  web:                      # always "web"
    runtime:
      port: 8000            # the port uvicorn listens on
      healthcheck:
        type: http
        path: /healthz
      resources:
        cpuVCpus: 0.25
        memoryMb: 256

2. Разверните и вызовите

terminalbash
# In the my-api folder
inquir apps create my-api --ingress public
inquir apps deploy my-api --promote

curl https://my-api-uqprbk.apps.inquir.org/api/hello
# {"message":"Hello from Inquir Compute","time":"2026-10-22T18:16:43.033814+00:00"}

Из консоли: те же шаги, что для сайта на React, — GitHub с Внутренним HTTP-портом 8000 или Создать в браузере с этими файлами.

Если что-то не работает

  • Развёртывание не проходит проверку работоспособности. uvicorn должен слушать --host 0.0.0.0, как в Dockerfile; адрес по умолчанию 127.0.0.1 недоступен снаружи контейнера.
  • Приложение запускается и останавливается. Посмотрите, что оно напечатало: inquir apps logs <app> --tail 100. Если не найден пакет — его нет в файле зависимостей.
  • Адрес не открывается. Приложение приватно, пока у него нет публичного адреса: inquir apps update <app> --ingress public или Создать адрес в разделе «Настройки → Сеть».
Подробнее

Flask или Django. Dockerfile тот же, последняя строка — gunicorn: CMD ["sh", "-c", "exec gunicorn app:app --bind 0.0.0.0:${PORT:-8000}"] (для Django — myproject.wsgi вместо app:app), и gunicorn в requirements.txt.

Подключить базу Postgres#

Любой из рецептов API получает базу Postgres за несколько шагов. База приватная: к ней подключаются только ваши приложения, а пароль не появляется в терминале. В пробный период помещается одна база.

1. Используйте DATABASE_URL в коде

Добавьте драйвер и обработчик, который берёт адрес из переменной DATABASE_URL:

server.jsjs
// npm install pg
import pg from 'pg';

const db = new pg.Pool({ connectionString: process.env.DATABASE_URL, max: 5 });

app.get('/api/db', async (req, res) => {
  const { rows } = await db.query('select now() as now, version() as version');
  res.json(rows[0]);
});
main.pypython
# requirements.txt: psycopg[binary]==3.3.6
import os

import psycopg


@app.get("/api/db")
def db_time():
    with psycopg.connect(os.environ["DATABASE_URL"]) as conn:
        now, version = conn.execute("select now(), version()").fetchone()
    return {"now": now.isoformat(), "version": version}

2. Создайте базу и подключите её к приложению

terminalbash
# A Postgres 16 database with its own disk, in the same project as my-api
# (inquir apps create my-api printed the project's name)
inquir apps create my-db --template postgres --project <project>

# Hand my-api the address: DATABASE_URL appears in its variables.
# "no verified private address yet"? Wait a minute and run it again.
inquir apps connect my-db my-api

3. Разверните новый код

terminalbash
# In the my-api folder: the new code picks DATABASE_URL up
inquir apps deploy my-api --promote

curl https://my-api-88n5um.apps.inquir.org/api/db
# {"now":"2026-10-22T18:21:23.413Z","version":"PostgreSQL 16.15 on x86_64-pc-linux-musl, ..."}

# Later, after changing only a variable (not the code): inquir apps redeploy my-api

В консоли: на холсте проекта выберите Создать → База данных, тип postgres, и нажмите Создать базу данных. Когда она запустится, откройте её вкладку База данных, нажмите Подключиться и скопируйте строку Приватный (Внутри сети Inquir). Затем откройте свой API, на вкладке Переменные добавьте DATABASE_URL с этим значением, сохраните и разверните новый код (push в GitHub или Развернуть заново, если код уже там).

Если что-то не работает

  • connect отвечает «no verified private address yet». База ещё запускается: подождите минуту и повторите команду.

Дальше: пошаговое руководство объясняет предварительные версии, перевод в продакшен и откат; Контейнерные приложения — всё, что умеют inquir.yaml и консоль.