.gitignore y variables de entorno
Nada sale tan barato como no cometer el error. Dos hábitos lo evitan casi siempre: sacar los secretos del código y decirle a Git qué no debe tocar.
Variables de entorno: el secreto vive fuera del código
El programa pide la contraseña al sistema operativo al arrancar, y el código se comparte sin la llave. En Python se leen con os.environ (de environment, "entorno"), un diccionario con las variables del proceso.
os.environ["NOMBRE"]
os.environ.get("NOMBRE", VALOR_POR_DEFECTO)| Forma | Qué hace | Cuándo |
|---|---|---|
os.environ["X"] | Devuelve el valor; si falta, lanza KeyError | Variables obligatorias |
os.environ.get("X") | Devuelve el valor o None | Para revisar y dar un mensaje claro |
os.environ.get("X", "dev") | Devuelve el valor o el por defecto | Nunca con una contraseña como valor por defecto |
import os
db_password = os.environ["DB_PASSWORD"]
api_key = os.environ.get("API_KEY")
if api_key is None:
raise SystemExit("Falta la variable API_KEY")Si la variable no existe:
Traceback (most recent call last):
File "app.py", line 3, in <module>
db_password = os.environ["DB_PASSWORD"]
KeyError: 'DB_PASSWORD'Nadie definió esa variable. Defínala en el entorno o en su .env local; escribir el valor en el código "para arreglarlo rápido" es justo como empiezan las fugas.
En desarrollo, los valores suelen vivir en un .env local que python-dotenv carga al iniciar; en producción los inyecta el servidor o un gestor como AWS Secrets Manager, Azure Key Vault o HashiCorp Vault. Ese .env es el archivo que se filtra.
.gitignore: la lista de lo que no se sube
.gitignore, en la raíz, lista lo que Git no debe rastrear. Créelo antes del primer commit:
# Secretos y configuración local
.env
.env.*
!.env.example
# Llaves y credenciales
*.pem
*.key
id_rsa*
credentials.json
# Registros y respaldos
*.log
*.sql| Patrón | Qué significa | Ejemplo |
|---|---|---|
# | Comentario | # Secretos |
* | Cualquier texto | *.pem |
! | Excepción: sí se sube | !.env.example |
/ al final | Solo carpetas | respaldos/ |
/ al inicio | Solo en la raíz | /config.json |
.env.example es la plantilla: nombres de variables con valores vacíos.
Ficha de git check-ignore
Comprueba si una ruta queda ignorada y por cuál regla.
git check-ignore [-v] [--no-index] RUTA...| Opción | Qué hace |
|---|---|
-v | Muestra archivo, línea y patrón que coincidió |
RUTA... | Una o varias rutas a comprobar |
--no-index | Evalúa la regla aunque el archivo ya esté rastreado |
$ git check-ignore -v .env
.gitignore:2:.env .env
$ git check-ignore -v app.py
$ echo $?
1Sin salida y código 1: "no ignorado". Un archivo ya rastreado tampoco muestra nada.
El detalle que se olvida: git rm --cached
.gitignore solo afecta a archivos que Git todavía no rastrea. Es el malentendido más común: alguien agrega .env al .gitignore y cree que resolvió, pero el .env sigue subiendo en cada cambio. Si ya entró en un commit, deje de rastrearlo con git rm --cached, que lo quita del índice y lo deja en disco:
$ git rm --cached .env
rm '.env'
$ git commit -m "Dejar de rastrear .env"Si responde fatal: pathspec '.env' did not match any files, la ruta está mal o Git no lo rastreaba. Si ya llegó al remoto, es una fuga (lección 4).