Mejores prácticas para archivos .env en producción (Guía 2026)
Gestionar variables de entorno es una de las preocupaciones de seguridad más subestimadas en el desarrollo de software. Un archivo .env mal configurado y enviado a un repositorio público ha causado algunas de las mayores brechas de datos en los últimos tiempos. Esta guía cubre todo lo que necesitas saber sobre el manejo correcto de archivos .env — desde las reglas básicas de formato hasta la gestión de secretos a nivel de producción.
¿Qué es un archivo .env?
Un archivo .env (pronunciado "dot env") es un archivo de configuración de texto plano que almacena variables de entorno para tu aplicación. Sigue un formato simple de KEY=VALUE y se carga al iniciar la aplicación mediante librerías como dotenv (Node.js), python-decouple (Python), godotenv (Go) o vlucas/phpdotenv (PHP).
La idea central detrás de los archivos .env proviene de la metodología Twelve-Factor App, que recomienda almacenar la configuración en el entorno en lugar de en el código. Esto significa que la misma base de código puede ejecutarse en desarrollo, staging y producción simplemente intercambiando el archivo .env — sin cambios en el código.
Elementos comunes almacenados en archivos .env incluyen cadenas de conexión a bases de datos, claves de API, credenciales de servicios de terceros, feature flags, números de puerto y configuraciones del modo de aplicación.
Reglas de formato del archivo .env
El formato .env es simple pero tiene reglas importantes que difieren ligeramente entre parsers. Seguirlas de manera consistente evita bugs sutiles:
Sintaxis básica KEY=VALUE
# Una variable por línea PORT=3000 NODE_ENV=production APP_NAME="My Application"
Entrecomillar valores
Los valores que contienen espacios, caracteres especiales o que necesitan preservar espacios en blanco al inicio/final deben estar entrecomillados. Tanto comillas simples como dobles son soportadas por la mayoría de los parsers, pero las comillas dobles son más portables:
# Necesario: espacios en el valor APP_DESCRIPTION="A production-ready web application" # Necesario: caracteres especiales como # o $ DB_PASSWORD="p@$$w0rd#2026" # Opcional pero inofensivo: valores simples PORT="3000"
Valores multilínea
Para claves privadas o certificados que abarcan múltiples líneas, usa valores entre comillas dobles con saltos de línea literales o la secuencia de escape \n (depende del parser):
# Saltos de línea literales dentro de comillas dobles (sintaxis dotenv v15+) PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY----- MIIEowIBAAKCAQEA... -----END RSA PRIVATE KEY-----" # Alternativa: saltos de línea escapados (más portable) PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQEA...\n-----END RSA PRIVATE KEY-----"
Comentarios
Las líneas que comienzan con # son comentarios y son ignoradas por los parsers. Los comentarios en línea (después de un valor en la misma línea) no son universalmente soportados y deben evitarse:
# Este es un comentario seguro en su propia línea PORT=3000 # EVITAR: los comentarios en línea pueden romper parsers # PORT=3000 # puerto del servidor web <-- el valor se convierte en "3000 # puerto del servidor web"
Convenciones de nombres para variables de entorno
Las convenciones de nombres consistentes hacen que tus archivos .env sean más fáciles de entender y auditar. Sigue estos patrones establecidos:
Usa SCREAMING_SNAKE_CASE
Los nombres de variables de entorno deben estar completamente en mayúsculas con palabras separadas por guiones bajos. Esta es la convención universalmente aceptada en todos los sistemas operativos y lenguajes:
# Correcto DATABASE_URL=postgres://... MAX_UPLOAD_SIZE_MB=50 STRIPE_SECRET_KEY=sk_live_... # Incorrecto # databaseUrl=postgres://... # maxUploadSize=50 # stripe-secret-key=sk_live_...
Prefija por servicio o área funcional
Agrupa las variables relacionadas con un prefijo común. Esto hace que el archivo sea escaneable y evita colisiones de nombres cuando se configuran múltiples servicios:
# Base de datos DB_HOST=localhost DB_PORT=5432 DB_NAME=myapp_production DB_USER=appuser DB_PASSWORD=your_strong_password # AWS AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG AWS_REGION=us-east-1 AWS_S3_BUCKET=my-app-assets # Stripe STRIPE_PUBLIC_KEY=pk_live_... STRIPE_SECRET_KEY=sk_live_... STRIPE_WEBHOOK_SECRET=whsec_...
Nunca hagas commit de .env a Git
Esta es la regla más crítica. Un archivo .env enviado a un repositorio público expone tus secretos a todo internet — y el historial de git es permanente. Incluso si eliminas el archivo en un commit posterior, los secretos permanecen accesibles en el historial.
Agrega .env a .gitignore primero
Antes de escribir una sola línea de código en un nuevo proyecto, agrega .env a tu .gitignore. Este es el primer archivo que debes crear:
# .gitignore # Archivos de entorno - NUNCA hagas commit de estos .env .env.local .env.development.local .env.test.local .env.production.local # Pero SÍ haz commit de la plantilla de ejemplo # !.env.example
Qué hacer si ya se hizo commit de .env
Si un archivo .env ya ha sido enviado a tu repositorio, sigue estos pasos inmediatamente:
- Rota todas las credenciales expuestas inmediatamente. Cada secreto en ese archivo debe considerarse comprometido, independientemente de si el repositorio es público o privado. Invalida claves de API, cambia contraseñas, rota tokens.
- Elimina el archivo del seguimiento de git:
git rm --cached .env - Agrega
.enva.gitignorey haz commit de ese cambio. - Reescribe el historial para limpiar el archivo. Para repositorios pequeños, usa BFG Repo Cleaner. Para repos con historial sensible, considera usar
git filter-repo. - Haz force-push del historial limpio:
git push --force --all - Si el repositorio fue público o ha sido forked o clonado, asume que los secretos están permanentemente comprometidos incluso después de reescribir el historial.
Crea una plantilla .env.example
El archivo .env.example (también llamado .env.sample o .env.template) es el complemento de tu entrada en .gitignore. Documenta cada variable que tu aplicación necesita sin exponer valores reales. Este archivo debe enviarse a tu repositorio.
# .env.example # Copia este archivo a .env y completa tus valores # Nunca hagas commit de .env — solo haz commit de este archivo # Aplicación NODE_ENV=development PORT=3000 APP_URL=http://localhost:3000 # Base de datos — obtén las credenciales de tu DBA o consola de la nube DATABASE_URL=postgres://user:password@localhost:5432/mydb # Stripe — encuéntralas en dashboard.stripe.com/apikeys STRIPE_PUBLIC_KEY=pk_test_your_key_here STRIPE_SECRET_KEY=sk_test_your_key_here # OpenAI — encuéntrala en platform.openai.com/api-keys OPENAI_API_KEY=sk-your_openai_key_here
Buenas prácticas para tu .env.example:
- Incluye cada variable que la aplicación necesita para ejecutarse, sin excepciones.
- Usa valores de placeholder que indiquen dónde obtener el valor real (por ejemplo,
sk_test_your_key_hereen lugar de solo una cadena vacía). - Agrega comentarios explicando las variables no obvias y dónde obtener las credenciales.
- Mantenlo sincronizado con el archivo
.envreal — actualízalo cada vez que agregues o elimines variables. - Opcionalmente incluye valores predeterminados seguros no secretos (como
PORT=3000) para que los nuevos desarrolladores puedan comenzar rápidamente.
También puedes usar Docker Compose para cargar un archivo .env compartido entre servicios:
# docker-compose.yml version: '3.8' services: app: build: . env_file: - .env ports: - "${PORT}:${PORT}" worker: build: ./worker env_file: - .env # variables compartidas - .env.worker # sobrecargas específicas del worker
Gestión de secretos en producción
Aquí está la verdad incómoda: no deberías usar archivos .env en producción. Los archivos en disco son una mala forma de gestionar secretos a escala. Pueden ser registrados accidentalmente en logs, incluidos en imágenes de contenedores, leídos por procesos comprometidos o dejados en servidores desmantelados.
Para cargas de trabajo en producción, usa un gestor de secretos dedicado:
| Herramienta | Mejor para | Características clave |
|---|---|---|
| AWS Secrets Manager | Apps alojadas en AWS | Rotación automática, IAM granular, logs de auditoría |
| AWS Parameter Store | Apps AWS, configs simples | Nivel gratuito, nombres jerárquicos, cifrado KMS |
| HashiCorp Vault | Multi-nube, auto-alojado | Secretos dinámicos, PKI, alquiler de credenciales de BD |
| Doppler | Equipos de desarrollo | Branching tipo Git para configs, CLI sync, integraciones |
| Google Secret Manager | Apps alojadas en GCP | Control de versiones, acceso basado en IAM, logs de auditoría |
| Azure Key Vault | Apps alojadas en Azure | Claves respaldadas por HSM, gestión de certificados, RBAC |
| Infisical | Equipos open-source | Auto-alojable, cifrado E2E, rotación de secretos |
El patrón para producción es inyectar secretos como variables de entorno al iniciar el contenedor a través de tu orquestador (Kubernetes Secrets, definiciones de tareas ECS, secretos de Fly.io), no enviando archivos .env con tus despliegues.
Carga de .env específica por framework
La mayoría de los frameworks modernos extienden el formato básico de .env con sus propias convenciones. Entender estas previene bugs de "¿por qué mi variable está undefined?":
Next.js
Next.js carga variables en este orden de prioridad: .env.local > .env.[environment] > .env. Solo las variables con prefijo NEXT_PUBLIC_ se exponen al navegador. Todas las demás permanecen solo del lado del servidor:
# Solo servidor (nunca se envía al navegador) DATABASE_URL=postgres://... OPENAI_API_KEY=sk-... # Expuesto al bundle del navegador (usar con precaución) NEXT_PUBLIC_APP_URL=https://myapp.com NEXT_PUBLIC_STRIPE_KEY=pk_live_...
Vite
Vite usa el prefijo VITE_ para exponer variables al código del lado del cliente. Las variables sin prefijo solo están disponibles en vite.config.js, no en el código de tu app:
# Solo accesible en vite.config.js SOME_BUILD_CONFIG=value # Accesible en código del cliente via import.meta.env.VITE_API_URL VITE_API_URL=https://api.myapp.com VITE_APP_TITLE="My App"
Create React App (CRA)
CRA requiere el prefijo REACT_APP_ para todas las variables personalizadas. Las variables sin este prefijo son ignoradas:
# Disponible como process.env.REACT_APP_API_URL REACT_APP_API_URL=https://api.myapp.com REACT_APP_VERSION=1.0.0 # Ignorado por CRA (sin prefijo) # SECRET_KEY=this-wont-be-bundled
Valida tu archivo .env
Incluso los desarrolladores experimentados cometen errores con archivos .env — una comilla faltante, un secreto enviado accidentalmente o una variable que sigue la convención de nombres incorrecta. Antes de hacer push a staging o producción, vale la pena ejecutar una validación rápida.
Nuestra herramienta Inspector ENV verifica tu archivo .env completamente en tu navegador (cero procesamiento del lado del servidor). Detecta secretos expuestos por patrón de nombre de clave, señala problemas de formato como valores sin entrecomillar con espacios o nombres de clave inválidos, y genera automáticamente un .env.example seguro con los secretos redactados.
Valida tu archivo .env ahora
Pega tu archivo .env para detectar secretos, verificar formato y generar un .env.example seguro. Todo el procesamiento es 100% en el navegador — tus secretos nunca salen de tu máquina.
Herramientas de desarrollo relacionadas
- Decodificador JWT — decodifica e inspecciona JSON Web Tokens en tu navegador
- Generador Docker Compose — crea archivos
docker-compose.ymlcon soporte de variables de entorno - Generador de Hash — genera hashes SHA-256 y otros para contraseñas y tokens
- Ver todas las herramientas gratuitas para desarrolladores