Файлът .env съхранява променливи на средата в прост формат ключ-стойност и отделя конфигурацията от изходния код на приложението. Според The Twelve-Factor App (2011), конфигурацията трябва строго да се отделя от кода и .env файловете станаха стандарт на този подход. .env File позволява заместване на различни стойности на API ключове, URL на сървъра и флагове за компилиране без прекомпилиране на проекта.
Основни моменти
.env File е конфигурационен файл, в който се съхраняват променливи на средата в прост текстов формат KEY=VALUE. Всеки ред съдържа една променлива: име на ключа и неговата стойност, разделени със знак за равенство.
.env файловете решават фундаментален проблем на съвременната разработка: различни среди (локална, тестова, продукционна) изискват напълно различни настройки. URL адресът на API сървъра на локалната машина е http://localhost:8080, на продукционния сървър — https://api.production.com. Ако тези стойности са директно вградени в кода на приложението, всяко компилиране за друга среда изисква промяна на изходния код.
Практиката за съхраняване на конфигурацията извън основния код на приложението е стандартизирана в манифеста The Twelve-Factor App (2011), който посочи променливите на средата като единствен правилен начин за конфигуриране на приложение. Според проучване на JetBrains Developer Ecosystem (2024), повече от 67% от мобилните разработчици използват .env файлове в своите проекти.
За мобилната разработка .env дава допълнително предимство: стойностите се заместват на етапа на компилиране чрез Gradle (Android) или xcconfig (iOS), което позволява създаване на отделни компилации за разработка, стейджинг и продукция без промяна на изходния код.
.env е особено полезен при работа в екип: всеки разработчик създава свой локален .env с настройки за своята среда (път до локална база данни, debug API ключове), а общите настройки се фиксират в .env.example в хранилището. Това елиминира ситуацията, когато след git pull компилацията на разработчика се чупи поради липса на променлива на средата, за която не е знаел. Новият член на екипа просто копира .env.example в .env и попълва своите локални стойности.
Форматът .env е максимално прост: всеки ред е една променлива във вид KEY=VALUE. Интервалите около знака за равенство обикновено се игнорират, но в повечето библиотеки се считат за част от стойността, така че е по-добре да ги избягвате.
Коментарите започват със символ # — целият ред след него се игнорира. Празните редове също се пропускат. Ако стойността съдържа интервали, тя се поставя в двойни или единични кавички.
# Основни настройки на средата
APP_NAME=MyMobileApp
APP_ENV=development
# API конфигурация
API_BASE_URL=http://localhost:3000/api
API_TIMEOUT=30000
# Чувствителни данни
DB_PASSWORD=secret_password_123
JWT_SECRET=your_jwt_secret_key
Всички променливи в .env са низове, но библиотеките за зареждане могат да ги конвертират в нужния тип. За екраниране на специални символи се използват обратни наклонени черти и кавички. Ако стойността съдържа символ # като част от текста, трябва да се екранира като \#.
KEY=value или KEY="value with spaces"PORT=8080DEBUG=trueKEY=line1\
line2DB_URL=${DB_HOST}:${DB_PORT}При зареждане на .env библиотеките могат да извършват интерполация на променливи — заместване на стойности на едни ключове вътре в други. Например променливата DATABASE_URL=postgres://${DB_USER}:${DB_PASS}@localhost/db ще разшири DB_USER и DB_PASS от същия файл.
Начинът на свързване на .env зависи от платформата. Android използва добавки за Gradle, iOS — конфигурационни файлове xcconfig, а междуплатформените решения като Flutter — специализирани библиотеки.
В Android .env се зарежда чрез добавката gradle-dotenv. Добавката чете .env от корена на проекта и добавя стойности в BuildConfig, след което те са достъпни в Kotlin или Java код чрез генерирани полета.
// build.gradle.kts (app level)
plugins {
id("co.uzzu.dotenv") version "4.0.0"
}
android {
buildFeatures {
buildConfig = true
}
}
kotlin {
// Достъп в кода: BuildConfig.API_BASE_URL
buildConfigField("String", "API_BASE_URL",
"\"" + dotenv.get("API_BASE_URL") + "\"")
}
В iOS променливите на средата обикновено се конфигурират чрез xcconfig файлове. За зареждане на .env в Swift се използва библиотека DotEnv или вграденият механизъм Info.plist с персонализирани ключове.
// Зареждане на .env в Swift проект
import DotEnv
struct AppConfig {
static func load() {
let env = DotEnv(Bundle.main)
env.load()
let apiURL = ProcessInfo.processInfo
.environment["API_BASE_URL"] ??
"https://default.api.com"
}
}
За Flutter съществува пакет flutter_dotenv, който зарежда променливи от .env по време на инициализация на приложението. Файлът .env се поставя в корена на проекта, а променливите стават достъпни чрез класа dotenv.
// pubspec.yaml
dependencies:
flutter_dotenv: ^5.1
// main.dart — зареждане при стартиране
import 'package:flutter_dotenv/flutter_dotenv.dart';
void main() async {
await dotenv.load(fileName: '.env');
var apiUrl = dotenv.get('API_BASE_URL');
runApp(MyApp(baseUrl: apiUrl));
}
И трите подхода обединява общ принцип: .env се зарежда на етапа на компилиране или при стартиране на приложението, стойностите се кешират и използват в кода чрез генерирани константи. Това предотвратява попадането на чувствителни данни в хранилището.
За React Native се използва пакетът react-native-config, който на етапа на компилиране автоматично генерира клас BuildConfig за Android и константи в Info.plist за iOS от един .env файл в корена на проекта. Това е особено удобно за стартъпи, които използват Expo или bare workflow: достатъчен е един .env на кореново ниво и всички платформи получават еднакви променливи на средата без дублиране на конфигурации.
Въпреки всички предимства, .env не е пълноценно решение за съхраняване на тайни в продукционна среда. Той осигурява базово ниво на защита, но при неправилна употреба може да доведе до изтичане на поверителни данни.
Най-важното правило — .env никога не трябва да попада в системата за контрол на версиите. Файлът се добавя в .gitignore веднага след създаване, а в хранилището се публикува само примерният файл .env.example с празни или фиктивни стойности.
# .env.example — публикува се в хранилището
APP_NAME=
APP_ENV=development
API_BASE_URL=http://localhost:3000
API_TIMEOUT=30000
# DB_PASSWORD — не се посочва дори в примера!
# JWT_SECRET — не се посочва дори в примера!
# .gitignore
# Dotenv файлове
.env
.env*.local
За продукционни проекти се препоръчва използването на професионални решения за управление на тайни. .env в продукция е допустим само ако файлът се намира извън document-root на сървъра и има строги права за достъп.
Според Snyk State of Open Source Security (2024), изтичането на .env файлове чрез хранилища е причина за повече от 12% от всички инциденти с разкриване на API ключове сред анкетираните компании. Използването на отделен мениджър за тайни позволява намаляване на този риск до нула.
Допълнителна защита се постига чрез внедряване на pre-commit hooks с инструменти като husky и lint-staged, които проверяват дали разработчикът случайно е добавил .env към commit. Инструменти като git-secrets (AWS) и talisman сканират всеки commit за модели на API ключове, токени и пароли, блокирайки commit при откриване. За CI pipeline-и се препоръчва добавяне на проверка detect-secrets — автоматичен скенер, който няма да допусне .env файл в хранилището дори при грешка на разработчика.
Често задавани въпроси
Не, .env не трябва да се публикува в Git. Файлът съдържа чувствителни данни и трябва да бъде добавен в .gitignore. Вместо него в хранилището се поставя .env.example с шаблон на всички необходими променливи.
.env — реалният файл с продукционни стойности, който никога не се публикува. Файлът .env.example съдържа същите ключове, но с празни или фиктивни стойности — той се публикува в хранилището като образец за нови разработчици.
Може, но не се препоръчва без допълнителна защита. Ако .env се използва на продукционен сървър, файлът трябва да бъде разположен извън document-root на уеб сървъра с права за достъп 600 (само собственик). За критични проекти се предпочитат мениджъри за тайни.
Чрез добавката gradle-dotenv (co.uzzu.dotenv). Добавката чете .env от корена на проекта и експортира стойности в BuildConfig. Променливите стават достъпни в кода като BuildConfig.VARIABLE_NAME на етапа на компилиране.
Да, много анализатори поддържат интерполация във формат ${VAR_NAME}. Например URL=${HOST}:${PORT} ще замести стойностите на HOST и PORT от същия файл. Тази функционалност обаче зависи от конкретната библиотека за зареждане.
Резюме
Ще разработим мобилно приложение под ключ
IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също