Variables de Entorno

Estándar para gestión de configuración, secretos y variables de entorno por ambiente.

Configuración — Gestión de variables de entorno y secretos

Propósito

Esta guía establece cómo gestionar la configuración de aplicaciones del DTI usando variables de entorno. El objetivo es mantener secretos seguros y permitir diferentes configuraciones por ambiente.

Estructura de archivos

proyecto/
├── .env.example          # Template con todas las variables (NO valores reales)
├── .env.development      # Valores para desarrollo local
├── .env.test             # Valores para testing
├── .env.staging          # Valores para ambiente staging
├── .gitignore            # Excluye .env
└── .env                  # Local (no commitear)

Template .env.example

# ===================
# Application
# ===================
APP_NAME="Mi Aplicación"
APP_ENV=development
DEBUG=true
ALLOWED_HOSTS=localhost,127.0.0.1

# ===================
# Database
# ===================
DATABASE_URL=postgresql://user:password@localhost:5432/mydb
DB_ENGINE=postgresql
DB_HOST=localhost
DB_PORT=5432
DB_NAME=mydb
DB_USER=user
DB_PASSWORD=changeme

# ===================
# Security
# ===================
SECRET_KEY=your-secret-key-here
JWT_SECRET=your-jwt-secret-here
GOOGLE_CLIENT_ID=your-client-id
GOOGLE_CLIENT_SECRET=your-client-secret

# ===================
# CORS
# ===================
CORS_ORIGINS=http://localhost:3000,http://localhost:8080

# ===================
# Email (opcional)
# ===================
EMAIL_HOST=smtp.gmail.com
EMAIL_PORT=587
EMAIL_USER=
EMAIL_PASSWORD=

Variables requeridas

Aplicación

VariableDescripciónEjemplo
APP_NAMENombre de la aplicaciónPIVOT API
APP_ENVAmbiente: development, staging, productionproduction
DEBUGModo debug (solo en dev)false
ALLOWED_HOSTSHosts permitidos separados por comaapi.unach.cl

Base de datos

VariableDescripciónEjemplo
DATABASE_URLConnection string completapostgresql://...
DB_HOSTHost de la base de datoslocalhost
DB_PORTPuerto5432

Seguridad

VariableDescripciónEjemplo
SECRET_KEYKey para encryption生成随机字符串
JWT_SECRETSecret para JWT tokens生成随机字符串
GOOGLE_CLIENT_IDOAuth Client IDxxx.apps.googleusercontent.com
GOOGLE_CLIENT_SECRETOAuth Client SecretGOCSPX-xxx

Gestión de secretos en GitLab CI/CD

Variables de CI/CD

En GitLab: Settings → CI/CD → Variables

VariableProtegidaMáscara
PRODUCTION_DATABASE_URL
PRODUCTION_SECRET_KEY
PRODUCTION_JWT_SECRET
STAGING_DATABASE_URLstaging

Ejemplo .gitlab-ci.yml

stages:
  - build
  - deploy

deploy-production:
  stage: deploy
  script:
    - echo "Deploying to production"
    - docker build -t $IMAGE_NAME .
    - docker run -e DATABASE_URL=$PRODUCTION_DATABASE_URL \
                 -e SECRET_KEY=$PRODUCTION_SECRET_KEY \
                 $IMAGE_NAME
  environment:
    name: production
    url: https://api.unach.cl
  only:
    - main

Validación al startup

# app/core/config.py - FastAPI
from pydantic import BaseModel, validator
from typing import List

class Settings(BaseModel):
    DATABASE_URL: str
    SECRET_KEY: str
    ALLOWED_HOSTS: List[str]

    @validator("SECRET_KEY")
    def secret_key_min_length(cls, v):
        if len(v) < 32:
            raise ValueError("SECRET_KEY debe tener al menos 32 caracteres")
        return v

    @validator("ALLOWED_HOSTS", pre=True)
    def parse_hosts(cls, v):
        if isinstance(v, str):
            return [h.strip() for h in v.split(",")]
        return v

settings = Settings()
// src/lib/config.ts - Next.js
const config = {
  databaseUrl: process.env.DATABASE_URL,
  secretKey: process.env.SECRET_KEY,
};

if (!config.secretKey) {
  throw new Error("SECRET_KEY is required");
}

No hacer

  • ❌ No commitear archivos .env
  • ❌ No hardcodear secretos en el código
  • ❌ No usar valores por defecto para producción
  • ❌ No exponer secretos en logs o errores

Sí hacer

  • ✅ Usar .env.example con valores dummy
  • ✅ Excluir .env de git con .gitignore
  • ✅ Usar secrets de GitLab para producción
  • ✅ Rotar secretos periódicamente (90 días)
  • ✅ Validar config al iniciar la aplicación

Ejemplo .gitignore

# Environment
.env
.env.local
.env.*.local

# Python
__pycache__/
*.py[cod]
venv/

# Node
node_modules/
npm-debug.log

Checklist

  • ¿El .env.example tiene todas las variables documentadas?
  • ¿El .gitignore excluye archivos .env?
  • ¿Los secretos están en GitLab CI/CD variables?
  • ¿Se validan las variables requeridas al startup?
  • ¿No hay secretos hardcodeados en el código?

Referencias