Разделы документации
Настройки сборки и свой Dockerfile
Команды сборки и запуска, корневая папка монорепозитория, версия рантайма, переменные сборки и свой Dockerfile, если автоопределения мало.
Платформа сама выбирает, как собрать приложение из исходников, а семь полей приложения позволяют этот выбор поменять: сборщик, корневая директория, команды сборки и запуска, версии рантайма и два набора переменных сборки. Если в корне сборки лежит Dockerfile, платформа собирает образ по нему, и писать для этого ничего не нужно.
Настройки сборки есть у приложений из репозитория и из архива. У приложения из готового образа сборки нет, и любое из этих полей отвечает ошибкой 422. Меняются настройки через API: на странице приложения в панели их нет.
Что настраивается
| Поле | Что делает | По умолчанию |
|---|---|---|
builder |
выбирает способ сборки: auto, railpack или dockerfile |
auto |
root_directory |
каталог внутри репозитория или архива, из которого идёт сборка | корень |
build_command |
команда сборки вместо той, что выбрала платформа | выбирает платформа |
start_command |
команда запуска вместо той, что выбрала платформа | выбирает платформа |
runtime_versions |
версии языков и инструментов, которые нужны сборке | выбирает платформа |
build_env |
переменные, видные только сборке | пусто |
build_secrets |
секреты, видные только сборке | пусто |
Автоопределение языка, зависимостей и команды запуска разбирает страница Сборка без Dockerfile. Здесь только то, чем его можно переопределить.
Как изменить настройки
Поля задаются при создании приложения в теле запроса POST /api/v1/applications и меняются запросом PATCH /api/v1/applications/{id}. Правится ровно то, что прислано, остальное остаётся как было. Все запросы и права токена описаны в разделе API nodbox.
Пример для приложения из монорепозитория:
{
"root_directory": "apps/web",
"build_command": "pnpm --filter web build",
"start_command": "node dist/server.js",
"runtime_versions": { "node": "22" },
"build_env": { "NODE_ENV": "production" },
"build_secrets": { "NPM_TOKEN": "значение секрета" }
}
Текущие значения лежат в блоке build ответа GET /api/v1/applications/{id}. Ключи в нём те же, что в запросе.
Настройки действуют со следующей версии
Правка настроек ничего не деплоит. Она ложится на приложение, а каждая новая версия снимает настройки в момент заказа и собирается по этому снимку. Работающая версия остаётся такой, какой была.
Из этого следует два правила:
- Новые настройки заработают, когда закажешь версию или запушишь в ветку с включённым автодеплоем.
- Версия, которая уже собирается, не заметит правку, сделанную после её заказа.
Откат возвращает версию с уже собранным образом, поэтому сборка при откате не повторяется. Подробнее - в разделе Версии и откат.
Чем собирать: поле builder
Поле builder решает, чем собирать образ.
| Значение | Что происходит |
|---|---|
auto |
есть Dockerfile в корне сборки - образ собирается по нему, нет - платформа определяет язык сама |
railpack |
образ собирает платформа, даже если Dockerfile лежит рядом: он может быть нужен только для локальной разработки |
dockerfile |
образ всегда собирается по Dockerfile; если файла нет, версия падает с причиной dockerfile_missing |
Явный dockerfile не уходит в автоопределение молча: выбранный способ платформа не подменяет другим. Что именно выбрано, видно в начале лога сборки. Например, при auto там будет строка «В корне сборки найден Dockerfile - образ собирается по нему.»
Команды сборки и запуска и версии рантайма действуют только в сборке, которую ведёт платформа. Если образ собирается по Dockerfile, всё это записано в самом файле. Поэтому при builder: dockerfile поля build_command, start_command и runtime_versions запрещены: запрос с ними отвечает 422. Платформа судит тот сборщик, который будет у приложения после запроса. Запрос {"builder": "railpack", "build_command": "make"} для приложения с Dockerfile проходит, а {"builder": "dockerfile", "build_command": "make"} нет.
Переход на dockerfile ранее заданные команды и версии не стирает: они вернутся в дело вместе с автосборкой. Стереть их можно явно: null для команд и {} для версий. Если при auto команды заданы, а Dockerfile найден, в логе сборки появится строка о том, что они не применяются.
Монорепозиторий: корневая директория
Поле root_directory задаёт каталог, из которого идёт сборка. Для приложения из монорепозитория это apps/web или другой путь до его папки с package.json или Dockerfile. Всё, что лежит выше этого каталога, сборке не видно: он становится её контекстом.
Правила записи пути:
- путь считается от корня репозитория или архива, без ведущего слэша
.и..в пути запрещены- завершающий слэш отбрасывается:
apps/web/иapps/web- один и тот же каталог - пустое значение или
nullвозвращают сборку из корня
Каталога может не оказаться в исходниках версии, или путь может вести через символическую ссылку за их пределы. В обоих случаях версия падает с причиной root_directory_missing, а лог сборки просит проверить путь в настройках. Если указан root_directory, то и Dockerfile ищется в нём, а не в корне репозитория.
Для автодеплоя монорепозитория есть отдельный фильтр путей: Автодеплой по push. Корневая директория выбирает, что собирать, а фильтр - при каких изменениях запускать сборку.
Команды и версии рантайма
build_command и start_command переопределяют выбор платформы. Это одна строка для оболочки, до 512 символов и без управляющих символов вроде перевода строки. Пустая строка и null значат «пусть решает платформа».
{
"build_command": "npm run build:prod",
"start_command": "node dist/server.js"
}
runtime_versions - объект вида «имя инструмента: версия». Платформа не знает язык приложения до сборки, поэтому версия указывается вместе с именем инструмента:
{
"runtime_versions": { "node": "22", "python": "3.12" }
}
Инструментов не больше десяти. Имя пишется строчными латинскими буквами, цифрами и дефисом, начинается с буквы. Версия - это строка вроде 22, 3.12 или 1.22.5, без пробелов и знака @. Набор заменяется целиком: присланный объект и есть новый набор, {} возвращает выбор платформе.
Переменные сборки и переменные приложения
У приложения четыре набора переменных, и они не пересекаются. Переменная сборки не попадает в работающее приложение, а переменная приложения не видна сборке.
| Набор | Кто видит значение | Что отдаёт API |
|---|---|---|
env |
работающее приложение | значения |
secrets |
работающее приложение | только имена |
build_env |
сборка | значения |
build_secrets |
сборка | только имена |
Пара env и secrets описана на странице Переменные и секреты. Одно и то же имя, например NODE_ENV, можно задать и в env, и в build_env с разными значениями: это две настройки двух разных этапов.
Правила у build_env и build_secrets такие же, как у рантаймовых наборов:
- имя состоит из латинских букв, цифр и подчёркивания и не начинается с цифры
- имя не длиннее 128 символов, значение не длиннее 4 096 символов
- переменных и секретов сборки вместе не больше 100
- одно имя не может быть одновременно в
build_envи вbuild_secrets: запрос отвечает422с названием имени - несколько системных имён, например
PATHиHOME, заняты платформой, и ответ422называет такое имя
Правятся наборы по-разному:
build_envзаменяется целиком. Присланный объект и есть новый набор,{}убирает все переменные, а если поле не прислать, набор не тронут.build_secretsнакладывается поверх прежнего набора. Присланное имя получает новое значение,nullпод именем стирает секрет, неназванные остаются. Пустая строка - это значение, а не удаление.
Значения секретов сборки наружу не возвращаются никогда: по API в блоке build лежит список имён. Поэтому прислать набор целиком было бы нечем. Чтобы превратить переменную сборки в секрет, одним запросом пришли build_env без неё и build_secrets с ней.
В автосборке значения обоих наборов доступны командам сборки. В Dockerfile между ними есть разница, она разобрана ниже.
Свой Dockerfile
Положи файл с именем Dockerfile в корень сборки, и при builder: auto образ соберётся по нему. Корень сборки - это корень репозитория или архива, а если задана root_directory, то этот каталог.
Что ожидает платформа
- Файл называется ровно
Dockerfile, с заглавной буквы. Именаdockerfile,ContainerfileиDockerfile.prodплатформа не подхватывает, как и файл не в корне сборки. Приautoона в этом случае определит язык сама, а приdockerfileверсия упадёт сdockerfile_missing. - Команду запуска платформа берёт из самого Dockerfile, из
CMDилиENTRYPOINT: в настройках приложения она при этом запрещена. - Образ может работать от root. Права внутри контейнера те же, что в обычном контейнере Docker, кроме отправки сырых сетевых пакетов.
- Порт веб-приложения платформа берёт из настройки приложения, а не из строки
EXPOSE. Слушай тот порт, который указан в настройках, он же передаётся в переменнойPORT. Подробнее - в разделе Порт, протокол и проверка готовности. - Сборка идёт до 16 минут, потом платформа её останавливает. Образ, который не помещается в лимит, закрывает версию причиной
image_too_large.
Контекст сборки
Контекстом служит корень сборки целиком. Пути в COPY и ADD считаются от него, и файлы выше него недоступны. У приложения из монорепозитория поэтому задай root_directory: "apps/web" и копируй пути относительно apps/web, а не от корня репозитория.
Переменные в Dockerfile
Переменная сборки приходит аргументом, секрет сборки приходит только монтированием в шаг RUN:
FROM node:22-alpine
WORKDIR /app
ARG VITE_API_URL
COPY package*.json ./
RUN npm ci
COPY . .
RUN --mount=type=secret,id=SENTRY_AUTH_TOKEN \
SENTRY_AUTH_TOKEN="$(cat /run/secrets/SENTRY_AUTH_TOKEN)" npm run build
CMD ["node", "dist/server.js"]
Здесь VITE_API_URL берётся из build_env и читается строкой ARG, а SENTRY_AUTH_TOKEN из build_secrets доступен только этому шагу RUN. В слои образа секрет не попадает. Значение ARG остаётся в истории образа, поэтому ничего секретного в build_env класть нельзя. Переменные приложения из env и secrets при сборке не видны, а переменные сборки не попадают в работающее приложение: если значение нужно и там, и там, задай его в обоих наборах.
Что учесть при сборке
- Кэша слоёв между сборками нет: каждая сборка идёт с нуля. Шаг
RUN --mount=type=cacheработает, но кэш в нём при каждой сборке пустой. - Из сборки открыт интернет:
RUNможет скачивать пакеты и файлы. - Базовый образ в
FROMдолжен быть публичным: логина к закрытым реестрам у сборки нет. Образы с Docker Hub и GitHub Container Registry платформа держит рядом со сборкой, поэтому они скачиваются быстрее. - Выбрать стадию многостадийной сборки через
--targetи указать другой путь к Dockerfile нельзя: таких настроек у приложения нет.
Если сборка не прошла, причина и строка, на которой она сломалась, видны в логе сборки. Частые отказы и что с ними делать - на странице Типичные сбои и что делать.
Что дальше
- Сборка без Dockerfile - как платформа определяет язык и какие бывают отказы
- Переменные и секреты - переменные работающего приложения
- Порт, протокол и проверка готовности - на каком порту слушать
- Автодеплой по push - новая версия на каждый push и фильтр путей
- Лог сборки - что платформа пишет о выбранном способе сборки
- Версии и откат - как настройки попадают в версию
Страница в markdown, так её читает агент: /docs/deploy/build-settings.md