Документация

Как это работает. От репозитория до стабильного прода.

Как подготовить проект, задеплоить его, подключить базу, откатить неудачный релиз и понять, почему что-то упало.

01 / раздел

Быстрый старт

От репозитория до работающего сервиса по HTTPS — четыре шага.

  1. 01

    Зарегистрируйтесь

    Через VK ID, Яндекс ID или по почте. Оплата — в рублях российской картой.

  2. 02

    Создайте проект и выберите репозиторий

    Подключите GitHub и укажите ветку. Тип приложения и стек определим по коду.

  3. 03

    Проверьте настройки

    Покажем, что нашли: порт, команду запуска, нужную базу. Переменные окружения можно загрузить из .env.

  4. 04

    Нажмите «Задеплоить»

    Соберём, развернём и дождёмся, пока приложение ответит. Дальше — обновление на каждый git push.

Задеплоить проект

02 / раздел

Подготовка проекта

Нужен репозиторий на GitHub. Dockerfile не обязателен: популярные стеки собираем сами.

СтекКак соберём
PythonFastAPI, Django, Flask и другие — по requirements.txt или pyproject.toml.
Node.jsNext.js, Nuxt, Express, NestJS и другие — по package.json, командами build и start.
GoGin, Echo, Fiber — по go.mod.
PHP, Java, Ruby, Rust и другиеLaravel, Spring, Rails и другие — тоже автоматически. Не собралось — добавьте Dockerfile или напишите нам.
Любой стек со своим DockerfileСобираем строго по нему — полный контроль над сборкой.
Готовый Docker-образМожно развернуть без сборки: укажите образ при добавлении сервиса.

Порт и адрес

Приложение должно слушать 0.0.0.0 и порт, указанный в настройках сервиса (его покажем на шаге проверки). Если слушать 127.0.0.1, снаружи приложение будет недоступно, и статус «работает» не поставится.

FastAPI — команда запуска
uvicorn main:app --host 0.0.0.0 --port 8000
package.json — Next.js
{
  "name": "shop-web",
  "scripts": {
    "build": "next build",
    "start": "next start -H 0.0.0.0 -p 3000"
  }
}

Проверка здоровья

Сделайте маршрут, который отвечает 200, например /health, и укажите его в настройках сервиса. Релиз считается работающим, только когда этот маршрут ответил. Без него проверяем, что открыт порт.

main.py
# main.py
from fastapi import FastAPI

app = FastAPI()

@app.get("/health")
def health():
    return {"ok": True}

Свой Dockerfile

Положите Dockerfile в корень сервиса — сборка пойдёт по нему, а не автоматически.

Dockerfile — Java
FROM eclipse-temurin:21-jre
WORKDIR /app
COPY target/app.jar app.jar
EXPOSE 8080
CMD ["java", "-jar", "app.jar"]

03 / раздел

Проекты и сервисы

Проект — изолированное окружение: своя закрытая сеть, свои базы, свои сервисы. Другие проекты не видят ни его сервисы, ни базу.

Сервис — одно приложение внутри проекта: сайт, API или фоновый воркер. Сервисы одного проекта могут жить в одном репозитории (разные папки) или в разных.

Публичные и приватные сервисы

Публичный сервис получает адрес в интернете с HTTPS. Приватный — только внутреннее имя вида worker:8000: к нему могут обращаться другие сервисы проекта, но не интернет. Переключается в меню «⋯» сервиса.

Адреса соседей

Каждый сервис получает адреса остальных сервисов проекта в переменных вида ИМЯ_URL: у сервиса shop-api это SHOP_API_URL. Свою переменную с тем же именем платформа не перезапишет.

Доступ для сотрудников

В «Настройках» проекта, раздел «Доступ», создайте ссылку-приглашение и отправьте её сотруднику или клиенту. Ссылка одноразовая и действует 7 дней. Платит за проект только владелец.

РольЧто может
НаблюдательСмотрит статус, релизы и логи. Секретов не видит, ничего не меняет.
РазработчикДеплоит, откатывает, перезапускает, правит переменные и настройки, подключает домены. Новый репозиторий подключает только владелец.
АдминистраторВсё, что разработчик, плюс удаление сервисов и баз, восстановление базы и приглашение разработчиков и наблюдателей.
ВладелецВсё, включая оплату, назначение администраторов и удаление проекта.

Управление

ДействиеЧто происходит
ЗадеплоитьСобирает свежий коммит ветки и разворачивает его новой версией.
ПерезапуститьПересоздаёт под с текущим образом и актуальными переменными, без пересборки.
ПриостановитьОстанавливает сервис. Плата за него не списывается; релизы, переменные и диск сохраняются.
ПереименоватьМеняет имя в панели. Адрес и внутреннее имя не меняются.
УдалитьУдаляет сервис, его адрес и историю релизов. Проект и базы остаются.

04 / раздел

Переменные окружения

Переменные хранятся зашифрованными и передаются только вашему приложению. В панели значения скрыты, пока вы не нажмёте «показать»; из логов секреты вырезаются перед показом.

Изменения применяются при следующем развёртывании или перезапуске — панель покажет, какие сервисы нужно перезапустить.

Что подставляет платформа

ПеременнаяКогда
DATABASE_URLК проекту подключён PostgreSQL.
REDIS_URLПодключён Redis.
AMQP_URLПодключён RabbitMQ.
MONGODB_URLПодключена MongoDB.
ИМЯ_URLАдреса других сервисов проекта.
PYTHONUNBUFFERED=1Python-сервисы: чтобы логи появлялись сразу.

05 / раздел

Базы данных и бэкапы

К проекту можно подключить PostgreSQL, Redis, RabbitMQ, Kafka и MongoDB. База доступна только сервисам этого проекта — адреса в интернете у неё нет. Размер базы и диска меняется на её странице.

Подключение из Python
import os
import psycopg

# DATABASE_URL подставляет платформа, когда к проекту подключён PostgreSQL.
conn = psycopg.connect(os.environ["DATABASE_URL"])

Бэкапы

Дампы PostgreSQL снимаются каждый час и хранятся у другого провайдера — не там же, где база. Почасовые копии живут двое суток, по одной копии в день — 30 дней. Каждый день платформа поднимает свежую копию во временной базе и проверяет, что она восстанавливается. Журнал проверок — когда, за сколько секунд, сколько таблиц и строк вернулось — виден на странице базы.

Бэкап, который никто не восстанавливал, — надежда, а не бэкап. Поэтому зелёная отметка ставится только после проверки восстановлением.

06 / раздел

Релизы и откат

Каждое развёртывание — версия: v1, v2, … Все они видны на ленте версий над вкладками сервиса. Текущая версия в проде подсвечена зелёным.

Откат

Кнопка «Откатить» возвращает прошлую версию целиком — код, переменные и размер — без пересборки, обычно быстрее 30 секунд. Откат не стирает историю: он создаёт новую версию, а на ленте видно, к какой вернулись.

Автооткат

Включается в настройках сервиса. Если новый релиз не стал здоровым за указанное время (по умолчанию 5 минут), платформа сама вернёт предыдущий здоровый. Причина пишется в журнал.

07 / раздел

Миграции базы

Укажите команду миграций в настройках сервиса, например alembic upgrade head. Она выполняется отдельным шагом до развёртывания, из нового образа. Перед ней снимается снапшот базы.

По умолчанию миграции ждут вашего подтверждения — сборка готова, но прод не трогается, пока вы не нажмёте «Применить».

Если между версиями менялась схема, на ленте версий перед релизом стоит жёлтая засечка. Откат через неё предупредит заранее и предложит восстановить снапшот базы. Совет: сначала совместимое расширение схемы, удаление колонок — отдельным релизом позже.

08 / раздел

Задачи по расписанию

На вкладке «Расписание» сервиса задаются команды, которые платформа запускает сама: очистка, выгрузки, рассылки. Расписание — в формате cron (0 3 * * * — каждый день в 3:00) по московскому времени.

Задача выполняется в контейнере сервиса через sh -c — тем же образом и с теми же переменными, что и текущий релиз. Откатили сервис — задачи тоже идут из отката. Диск сервиса задаче не подключается.

Один запуск длится не дольше 30 минут, а медленная задача не наслаивается сама на себя: следующий запуск ждёт, пока закончится предыдущий. Последний запуск и его вывод видны там же, запустить задачу можно вручную.

09 / раздел

Наблюдение и уведомления

Статус «работает» означает, что приложение отвечает на проверку здоровья, а не что контейнер запущен. После деплоя платформа продолжает следить за каждым сервисом раз в минуту.

Что случилосьЧто делает платформа
Приложение упалоПерезапускает его автоматически.
Приложение зависло: работает, но не отвечаетЕсли молчит дольше трёх минут и это не медленный старт — пересоздаёт под. Не чаще раза в час.
Не отвечает дольше полутора минутПрисылает уведомление в панель и в Telegram — один раз на падение.
Снова отвечаетПрисылает «снова отвечает».
Сертификат не продлилсяПредупреждает за 14, 7, 3 и 1 день до истечения.

Уведомления в Telegram

  1. 01

    Откройте «Настройки → Профиль»

    В панели Prichal.

  2. 02

    Нажмите «Привязать Telegram»

    Откроется наш бот уведомлений.

  3. 03

    Отправьте боту /start

    Аккаунт привяжется автоматически; в панели появится отметка.

10 / раздел

Сеть и HTTPS

Публичный сервис получает адрес на домене платформы. HTTPS-сертификат выдаётся при развёртывании и продлевается сам; его состояние видно во вкладке «Сеть» сервиса.

Собственный домен

Во вкладке «Сеть» сервиса нажмите «Подключить домен» и добавьте у регистратора одну из записей, которые покажет панель:

ДоменЗапись
Поддомен (www.shop.ru, app.shop.ru)CNAME на уникальное имя вида d1a2b3….prichal.tech — своё для каждого домена.
Корень домена (shop.ru)A на IP платформы и TXT _prichal.shop.ru с кодом подтверждения.

DNS проверяется раз в минуту; как только записи появятся, домен подтвердится сам и получит HTTPS-сертификат. До 5 доменов на сервис и до 20 на аккаунт. Домен, не подтверждённый за 7 дней, освобождается.

Одной A-записи для подтверждения мало: домен, который уже смотрит на наш адрес, иначе мог бы «занять» любой клиент платформы. TXT-код или уникальный CNAME доказывают, что DNS правите именно вы.

Исходящие соединения и почта

Из приложения открыты соединения в интернет на порты 80, 443 и SMTP 465/587. Письма отправляйте через внешний SMTP-провайдер (Яндекс, Mail.ru, Unisender, SendPulse) на порт 465 или 587. Порт 25 закрыт: прямая отправка на почтовые серверы получателей недоступна.

11 / раздел

Частые ошибки

Причину падения платформа показывает человеческим языком вместе с последними строками лога. Самые частые:

Что видноПричинаЧто делать
Не отвечает на портПриложение слушает 127.0.0.1 или другой порт.Слушайте 0.0.0.0 и порт из настроек сервиса.
Не хватило памяти (OOMKilled)Приложению тесно в текущем размере.Увеличьте размер в один клик в меню «⋯».
ModuleNotFoundErrorЗависимость не указана в requirements.txt / package.json.Добавьте её и сделайте push.
Падает при стартеНет нужной переменной окружения или неверная команда запуска.Проверьте переменные и команду во вкладке «Настройки».
Сборка не прошлаСтек не распознан или ошибка в сборке.Откройте лог сборки; при необходимости добавьте Dockerfile.

Не получилось разобраться — напишите нам, поможем.