nodbox
Разделы документации

Переменные и секреты

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

Переменные и секреты - настройки, которые приложение читает из окружения при запуске: адрес базы, ключ внешнего сервиса, режим работы. Секрет отличается от обычной переменной тем, что платформа хранит его значение зашифрованным и не возвращает никогда: ни в панели, ни по API. Правка набора ничего не деплоит, она доезжает до приложения со следующей версией.

Чем секрет отличается от переменной

Приложение читает оба набора одинаково, как переменные окружения: process.env.NAME в Node.js, os.environ["NAME"] в Python. Разница в том, что платформа делает со значением.

Переменная Секрет
Поле в API env secrets
Что отдаёт API имя и значение только имя
Что показывает панель значения под точками, кнопка «Показать значения» «Значение скрыто - показать его платформа не может»
Хранение значение лежит в настройках приложения значение хранится зашифрованным
Как правится в API набор заменяется целиком присланное накладывается поверх прежнего

Что из этого следует на практике:

  • Значение секрета видит только само приложение. Платформа показать его не может, поэтому правка секрета - это новое значение, а не редактирование прежнего.
  • Обычные переменные видит любой, у кого есть право читать приложение: токен с правом «читать» получает их значения в ответе на GET /api/v1/applications/{id}. Пароли, токены и ключи клади в секреты.
  • Платформа не вырезает значения секретов из логов приложения. Если приложение само напечатает секрет, он попадёт в логи как есть. Не печатай переменные окружения целиком.
  • Сборке переменные и секреты приложения не видны: у неё свои, они описаны в разделе Настройки сборки и свой Dockerfile.

Как задать в панели

На странице приложения открой вкладку «Окружение». На ней две карточки: «Переменные окружения» и «Секреты». Те же карточки есть при создании приложения: первая версия снимет их сразу.

Чтобы добавить переменную:

  1. Нажми «Добавить переменную».
  2. Впиши имя, например LOG_LEVEL, и значение.
  3. Нажми «Добавить», а потом «Сохранить окружение».

Секрет добавляется так же кнопкой «Добавить секрет». Изменения копятся в черновике, пока не нажата кнопка «Сохранить окружение»: переменные и секреты уходят на платформу одним сохранением. После него панель пишет «Окружение сохранено» и напоминает, что набор применится со следующей версией.

Несколько правил поля:

  • Значение многострочное. Enter переносит строку, Ctrl + Enter или ⌘ + Enter добавляет переменную. Переводы строк и пробелы по краям сохраняются как есть, поэтому закрытый ключ или сертификат можно вставить целиком. Под значением панель показывает, сколько в нём строк и знаков и стоит ли в конце перевод строки.
  • Имя переменной не правится. Чтобы переименовать, удали переменную и добавь заново.
  • Над списком панель считает занятые имена: например, «3 переменные и 1 секрет из 100».

Как менять и удалять секрет:

  • Рядом с именем нажми «Задать новое» и введи значение. Пока поле пустое, прежнее значение остаётся на месте. Кнопка «Отмена» убирает поле.
  • Значок корзины помечает секрет к удалению: в строке появляется «Удалится при сохранении», а «Вернуть» отменяет пометку.
  • Новый секрет с пустым значением панель не принимает: имя без значения приложению ничего не даст.

Чтобы превратить переменную в секрет, удали её из переменных и добавь секретом под тем же именем. Одно имя не бывает и переменной, и секретом, поэтому сохранить нужно оба изменения разом: так делает одна кнопка «Сохранить окружение».

Как задать по API

Переменные и секреты лежат в полях env и secrets приложения. Их можно прислать при создании, POST /api/v1/applications, и поменять запросом PATCH /api/v1/applications/{id}:

{
  "env": {
    "NODE_ENV": "production",
    "LOG_LEVEL": "info"
  },
  "secrets": {
    "STRIPE_KEY": "значение секрета",
    "OLD_TOKEN": null
  }
}

Поля правятся по-разному, и это важно не перепутать:

  • env заменяется целиком. Присланный объект и есть новый набор: переменные, которых в нём нет, исчезнут. {} убирает все переменные, а если поле не прислать, набор не тронут. Чтобы добавить одну переменную, пришли весь набор вместе с ней.
  • secrets накладывается поверх прежнего набора. Присланное имя получает новое значение, null под именем стирает секрет, неназванные остаются как были. Пустая строка - это значение, а не удаление. При создании приложения null в секретах не принимается: стирать нечего.

В ответе GET /api/v1/applications/{id} значения env лежат картой, а secrets - списком одних имён:

{
  "env": { "LOG_LEVEL": "info", "NODE_ENV": "production" },
  "secrets": ["STRIPE_KEY"]
}

Список вместо карты сделан намеренно: карту с null вместо значений можно было бы отправить обратно в PATCH и стереть все секреты разом.

Чтобы превратить переменную в секрет по API, пришли в одном запросе env без неё и secrets с ней. Запрос с secrets, имя в которых ещё занято переменной, отвечает 422.

Для POST хватает права токена «деплоить». PATCH требует два права сразу: «деплоить» и «менять мощность», потому что та же ручка правит размер приложения. Подробнее - в разделе Токены и права.

Когда изменения вступают в силу

Правка переменных и секретов работающее приложение не трогает. Каждая версия снимает набор в момент заказа и запускается с этим снимком, поэтому переменные, как и размер, живут вместе с версией.

Что из этого следует:

  • Поменял переменную или секрет - закажи новую версию. В панели это «Задеплоить снова» на странице приложения, по API - POST /api/v1/applications/{id}/revisions, а у приложения из репозитория версию заводит и push в ветку с включённым автодеплоем. Версия возьмёт значения, которые записаны в приложении в момент заказа.
  • Версия, которая уже заказана и собирается, правку, сделанную после заказа, не заметит. Закажи ещё одну.
  • Откат возвращает значения той версии, на которую ты откатился, а не сегодняшние. Если ты сменил пароль в базе, а потом откатился на версию со старым паролем, приложение стартует со старым. Значения секретов тоже входят в снимок версии.
  • Запуск остановленного приложения берёт сегодняшние значения, а не те, с которыми приложение работало до остановки.
  • Какие значения были у какой версии, платформа не показывает: в истории версий переменных нет. Сегодняшний набор виден на вкладке «Окружение».

Про откат подробнее - в разделе Версии и откат.

Имена и значения

Что Предел
Сколько имён 100 на переменные и секреты вместе
Длина имени до 128 знаков
Из чего имя латинские буквы, цифры и подчёркивание, первый знак - буква или подчёркивание
Длина значения до 4 096 знаков
Один набор на имя имя есть либо среди переменных, либо среди секретов

Остальное про значения:

  • Значение - любой текст в UTF-8: переводы строк, пробелы по краям и пустая строка допустимы и сохраняются как есть. Нулевой байт и текст в другой кодировке платформа не принимает.
  • Длина считается в знаках, а не в байтах.
  • По API значением может быть строка, число или true и false. Платформа записывает число или булево строкой, потому что окружение процесса знает только строки: 4 станет "4", а true станет "true". Массив, объект и null в env отвечают 422.

Нарушение любого предела отвечает 422 с текстом, который называет имя виноватой переменной. Панель проверяет имя и длину до отправки.

Имена, которые занимает платформа

Платформа сама ставит в окружение приложения PORT и все имена, которые начинаются с K_. Такие имена задать нельзя. Запрос с ними отвечает 422: «Имя PORT занято платформой: она подставляет эту переменную сама, и твоё значение потерялось бы». Панель говорит то же прямо в окне добавления.

PORT содержит порт приложения из его настроек. Другой порт задаётся настройкой приложения, а не переменной: Порт, протокол и проверка готовности. Имена на K_ служебные, и пользоваться ими не нужно.

Это правило действует для рантайма. У сборки свои занятые имена: PORT и K_ там свободны, зато заняты PATH, HOME и ещё несколько. Список - в разделе Настройки сборки и свой Dockerfile.

Подключение к базе

Платформа не подставляет строку подключения в приложение сама. У приложения может быть несколько баз, и три строки не могут называться одинаково DATABASE_URL, поэтому имя выбираешь ты.

Скопируй строку подключения базы, положи её в секрет под своим именем, например DATABASE_URL, и задеплой приложение. Строку, режимы TLS и путь к сертификату базы разбирает страница Подключение к базе.

Переменные сборки

Переменные и секреты на этой странице видит работающее приложение. Сборка видит другие: build_env и build_secrets. Одно и то же имя, например NODE_ENV, можно задать в обоих наборах с разными значениями: это две настройки двух разных этапов. Если значение нужно и сборке, и приложению, задай его в обоих местах. Как это устроено, разобрано в разделе Настройки сборки и свой Dockerfile.

Что дальше


Страница в markdown, так её читает агент: /docs/apps/env.md