ENV-переменные (переменные окружения) - это способ хранить пароли, токены и API-ключи отдельно от кода, в защищенном месте, откуда их не увидит никто, кто просто откроет ваш репозиторий. Простыми словами: вместо того чтобы вписать ключ прямо в файл со скриптом, вы кладете его в отдельный .env файл или в настройки хостинга, а код обращается к нему по имени.
В этой статье разберем, что такое env переменные на практике, как создать первый .env файл за 5 минут и куда класть ключи при деплое на Railway, Vercel и Timeweb, чтобы не повторить историю с заблокированным аккаунтом из-за утекшего ключа.
ENV-переменные хранят API-ключи, пароли и токены отдельно от кода в файле .env или в настройках хостинга. Ключ читается по имени через process.env или os.environ, а сам секрет никогда не попадает в Git. В статье: пошаговая настройка .env, сравнение Railway, Vercel и Timeweb, готовый промпт для проверки проекта на утечки.
Что такое env переменные простыми словами?
Env переменная - это пара "имя и значение", которую операционная система или хостинг передают приложению при запуске, а не хранят внутри кода программы.
Разработчики из туториала про базовые команды сравнивают их с подписанными коробками на столе: на коробке написано имя, а внутри лежит значение. Программа спрашивает "дай мне значение из коробки JAVA_HOME" и получает путь к нужной папке, при этом сама коробка физически не лежит в файле с кодом.
На практике это выглядит так. У вас есть код, который отправляет запрос к OpenAI. Ключ для этого запроса нужен один: OPENAI_API_KEY. Вместо того чтобы вписать сам ключ строкой в файл main.py или index.js, вы кладете его в переменную окружения. Код обращается к process.env.OPENAI_API_KEY в Node.js или os.environ.get('OPENAI_API_KEY') в Python и получает значение в момент запуска. Файл с кодом при этом остается чистым: секрета там физически нет, и его можно спокойно выложить на GitHub, показать на созвоне или скопировать в чат.

Зачем вообще нужен отдельный файл .env?
Файл .env хранит переменные локально, на вашем компьютере, и не отправляется в Git благодаря записи в .gitignore.
.env - это обычный текстовый файл в корне проекта, куда построчно записываются пары ключ и значение: API_KEY=sk-abc123. Библиотека dotenv (для Node.js) или python-dotenv (для Python) читает этот файл при старте приложения и раскладывает значения по process.env или os.environ, будто вы вписали их вручную в терминал.
Без .env пришлось бы каждый раз задавать переменные командой set или export в терминале вручную, а они бы исчезали при закрытии окна. С файлом .env переменные подгружаются автоматически при каждом запуске npm run dev или python app.py, и их не нужно вспоминать заново. Один нюанс: файл .env работает только локально. На сервере хостинг обычно сам подставляет переменные из своей панели, и .env там просто не нужен, о чем ниже.

Почему API-ключ в коде это причина №1 взлома?
Открытые API-ключи в публичных репозиториях GitHub - основная причина взлома проектов и счетов на тысячи долларов, потому что боты сканируют новые пуши за секунды.
AI-сгенерированный код содержит в 2,74 раза больше уязвимостей безопасности, чем код, написанный человеком вручную, и открытые ключи в этой статистике занимают верхние строчки. Причина простая: вайбкодер просит нейросеть "подключи OpenAI API", получает рабочий код с ключом прямо внутри файла, и если потом пушит проект в публичный репозиторий, ключ уходит вместе с историей коммитов.
Дальше все происходит быстро. По документации Railway, секреты полагается хранить отдельно от кода именно потому, что репозиторий может стать публичным случайно, например при смене видимости или форке. Боты, которые постоянно сканируют GitHub на новые коммиты, ищут строки вида sk-, API_KEY=, TOKEN= и проверяют их на валидность автоматически. Если ключ живой и привязан к платному тарифу OpenAI или AWS, счет может вырасти до тысяч долларов за одну ночь, пока вы спите.
Максим: «У меня был случай, слил бюджет на API, потому что не рассчитал unit-экономику по запросам. Теперь под каждый новый проект сразу считаю, сколько стоит один вызов и сколько запросов может отправить один пользователь за день. Без этого расчета цифры в конце месяца бьют неожиданно.»

Как создать первый .env файл и подключить его к проекту?
Создать .env занимает пять минут: файл в корне проекта, .gitignore, установка dotenv и чтение переменных в коде.
Пошагово это выглядит так, и разница между Node.js и Python минимальна.
Шаг 1. Создайте файл .env. В корне проекта, рядом с package.json или requirements.txt, создайте файл с именем .env. Внутри построчно: OPENAI_API_KEY=sk-ваш-ключ, без кавычек и пробелов вокруг знака равно.
Шаг 2. Добавьте .env в .gitignore. Откройте или создайте файл .gitignore и впишите туда .env отдельной строкой. Так Git никогда не будет отслеживать этот файл, даже если вы наберете git add .
Шаг 3. Подключите dotenv. В Node.js: npm install dotenv, затем в начале главного файла require('dotenv').config(). В Python: pip install python-dotenv, затем from dotenv import load_dotenv и load_dotenv() в начале скрипта.
Шаг 4. Прочитайте переменную в коде. Node.js: process.env.OPENAI_API_KEY. Python: os.environ.get('OPENAI_API_KEY'). Если вернулся undefined или None, значит переменная не подгрузилась, и дальше по коду часто вылезает ошибка вроде "token must be str, not NoneType".
Шаг 5. Создайте .env.example. Скопируйте .env, уберите реальные значения, оставьте только имена переменных с пустой строкой после знака равно, и сохраните как .env.example. Этот файл спокойно коммитится в Git и показывает другому разработчику, какие переменные нужны проекту, без единого реального секрета.
Если работаете в Cursor, Windsurf или Claude Code, попросите ассистента сгенерировать .env.example автоматически по вашему .env, это займет один промпт и убережет от ручных опечаток в названиях переменных.

Что обязательно добавить в .gitignore?
.gitignore должен содержать минимум .env, node_modules и любые файлы с ключами, чтобы Git физически не мог их закоммитить.
Стандартный .gitignore для вайбкод-проекта на Node.js выглядит примерно так: .env, .env.local, node_modules, *.log, .DS_Store. Для Python добавляется __pycache__, venv и *.pyc. Логика простая: если файла нет в .gitignore, Git его увидит и предложит закоммитить при первом же git add ., а вернуть коммит из истории репозитория заднем числом невозможно без переписывания всей истории.
Отдельно стоит проверить файлы вроде config.json или credentials.py, если в проекте когда-то хранили ключи там, до перехода на .env. AI-ассистенты в IDE вроде Cursor или Windsurf часто создают такие файлы автоматически при первой настройке интеграции, и про них легко забыть при чистке проекта перед публикацией на GitHub.

Куда класть переменные на Railway, Vercel и Timeweb?
На хостинге .env файл не нужен: переменные вводятся вручную в панели управления и хостинг сам прокидывает их в приложение при каждом деплое.
Логика одна для всех трех платформ: находите раздел Variables или Environment Variables в настройках проекта, вводите те же имена переменных, что и в локальном .env, но со значениями для продакшена. Разница только в интерфейсе и деталях.
| Платформа | Где искать | Особенность |
|---|---|---|
| Railway | Service -> вкладка Variables | Есть Sealed Variables: значение скрывается после сохранения, даже от команды |
| Vercel | Settings -> Environment Variables | Разделяет Production, Preview и Development, можно задать разные значения для каждого |
| Timeweb Cloud | App Platform -> раздел "Переменные" при настройке приложения | Регистр имени переменной важен, значение можно вводить в любом регистре |
На Railway после сохранения переменной автоматически запускается новый деплой с обновленными значениями, а старый остается живым до прохождения проверки здоровья. На Vercel изменение переменной само по себе деплой не запускает, нужно вручную нажать Redeploy или запушить новый коммит, иначе старое значение продолжит работать в проде. На Timeweb Cloud, судя по документации App Platform, переменные задаются на шаге настройки приложения и применяются при следующей сборке контейнера.
Общее правило для всех трех: никогда не префиксуйте секретный ключ как NEXT_PUBLIC_ или VITE_, потому что такие переменные попадают прямо в код браузера и видны любому, кто откроет DevTools.

Как проверить что ключи уже не утекли на GitHub?
Проверить утечку можно вручную по истории коммитов или одним промптом попросить AI-ассистента просканировать весь проект.
Если проект уже существует какое-то время и вы не уверены, не засветился ли ключ раньше, самый быстрый способ - скормить весь проект AI-ассистенту в Cursor, Windsurf или Claude Code с прямой задачей найти секреты. Вот рабочий промпт, который можно скопировать целиком:
Проверь весь проект на открытые секреты. Найди: API-ключи, токены, пароли,
connection strings которые прописаны прямо в коде (не в .env). Для каждой
находки: покажи файл и строку / замени на process.env.НАЗВАНИЕ_ПЕРЕМЕННОЙ /
добавь переменную в .env.example с пустым значением. После — создай
.env.example файл со всеми переменными (без реальных значений).
Проверь что .env есть в .gitignore.Если ключ все же нашелся в истории коммитов на GitHub, простое удаление файла ситуацию не спасает: старое значение остается доступным через историю репозитория. Единственный надежный шаг - зайти в панель сервиса, который выдал ключ (OpenAI, Stripe, база данных), отозвать старый ключ и выпустить новый, обновив значение в .env и в панели хостинга.
Какие ошибки чаще всего допускают новички с env переменными?
Самые частые ошибки: забыть добавить .env в .gitignore, перезапутать имя переменной, забыть перезапустить приложение после изменения.
Опечатка в имени переменной - самая частая причина ошибки "token must be str, not NoneType" или undefined в консоли. Имя OPENAI_API_KEY в .env и OPENAI_APIKEY в коде для компьютера это два разных ключа, и он молча вернет пустое значение вместо явной ошибки. Второй по частоте случай: изменили значение в .env, но забыли перезапустить dev-сервер, из-за чего в памяти приложения все еще висит старое значение.
Третья ошибка типична для тех, кто переносит .bat или shell-скрипт с временными переменными на постоянную основу: команда set ИМЯ=значение в Windows задает переменную только для текущей сессии терминала, и после закрытия окна она пропадает без следа. Для постоянных значений на Windows их нужно вписывать через системные настройки, а на Mac и Linux, где по умолчанию сейчас используется Zsh, а не Bash, постоянные переменные прописываются в файл .zshrc, а не в устаревший .bash_profile.

Итог: что нужно запомнить про env переменные
Секреты живут в .env локально и в панели хостинга в проде, .env всегда в .gitignore, а в коде остаются только имена переменных, а не их значения. Такая связка занимает пять минут настройки в начале проекта и избавляет от паники при случайной публикации репозитория.
Если каталог инструментов интересен ближе, посмотрите обзоры Cursor, Windsurf и Claude Code в каталоге AI-инструментов VibeCoderz, все три умеют находить открытые секреты по одному промпту из этой статьи.
Глоссарий
| Термин | Что значит |
|---|---|
| ENV-переменная | Пара "имя и значение", которую приложение читает при запуске, а не хранит в коде |
| .env | Текстовый файл в корне проекта с переменными для локальной разработки |
| .env.example | Копия .env без реальных значений, безопасная для коммита в Git |
| dotenv | Библиотека, которая загружает переменные из .env в process.env или os.environ |
| .gitignore | Файл со списком того, что Git никогда не должен отслеживать |
| process.env | Объект в Node.js, где хранятся все переменные окружения приложения |
| Secret / секрет | Любое чувствительное значение: API-ключ, пароль, токен, connection string |
Частые вопросы про env переменные
Что такое env переменные простыми словами?
Это пара ключ и значение, которая хранится не в коде, а в отдельном файле .env или в настройках хостинга. Код обращается к переменной по имени и получает значение при запуске, а сам секрет в файлах проекта не виден.
Обязательно ли использовать dotenv?
Для локальной разработки на Node.js и Python да, потому что операционная система сама .env файлы не читает. На Railway, Vercel и Timeweb dotenv не нужен, хостинг сам прокидывает переменные в приложение.
Что будет если случайно закоммитить .env в GitHub?
Боты сканируют публичные репозитории за секунды после пуша и ищут строки вида API_KEY, SECRET, TOKEN. Если ключ живой, им могут воспользоваться раньше, чем вы заметите утечку в истории коммитов.
Как понять что переменная не подгрузилась?
В Node.js process.env.ИМЯ вернет undefined, в Python os.environ.get вернет None. Обычно причина в опечатке имени, неправильном расположении .env файла или забытом перезапуске приложения.
Нужно ли одинаковое имя переменной на всех платформах?
Да, имя переменной в коде должно совпадать с именем в панели Railway, Vercel или Timeweb. Значение при этом может отличаться для разработки и для продакшена.
Можно ли так же хранить пароль от базы данных?
Да, DATABASE_URL и любые пароли хранятся точно так же, как API-ключи: в .env локально и в разделе Variables у хостинга в проде.
Что делать если ключ уже утек?
Сначала отозвать ключ у сервиса, который его выдал, и выпустить новый. Удаление файла из последнего коммита не спасает, потому что старое значение остается в истории репозитория.
Разобраться с безопасностью проекта детальнее можно на консультации с Максимом, а полный каталог AI IDE и инструментов для вайбкодинга смотрите в каталоге VibeCoderz.
Обновлено: июль 2026.