| .settings | ||
| src | ||
| .classpath | ||
| .gitignore | ||
| .project | ||
| docker-compose.yml | ||
| Dockerfile | ||
| pom.xml | ||
| README.md | ||
Gestión de secretos en distintos entornos (Java + Docker + CI/CD)
Este documento resume cómo manejar de manera segura credenciales y secretos en distintos entornos: desarrollo local, Docker, docker-compose y CI/CD (GitHub Actions).
1. Desarrollo local (Java)
Leer secretos usando System.getenv():
String user = System.getenv("DB_USER");
String password = System.getenv("DB_PASSWORD");
if (user == null || password == null) {
throw new RuntimeException("Faltan variables de entorno DB_USER / DB_PASSWORD");
}
Definir las variables en la sesión activa:
Windows (PowerShell):
$env:DB_USER="mi_usuario"
$env:DB_PASSWORD="mi_password"
Linux / Mac / WSL:
export DB_USER=mi_usuario
export DB_PASSWORD=mi_password
Las variables solo existen en la sesión activa. Configura persistencia si es necesario (
.bashrc,.zshrc, variables de entorno del sistema).
2. Dockerfile
Nunca incluir secretos directamente. Solo se declaran variables vacías como documentación:
# Documentación de variables esperadas en runtime
ENV DB_USER=""
ENV DB_PASSWORD=""
Los valores reales se pasan al ejecutar el contenedor. La aplicación sigue usando System.getenv() para leerlos.
3. Docker (runtime)
Opción A — En línea:
docker run -e DB_USER=mi_usuario -e DB_PASSWORD=mi_password -p 8080:8080 mi-imagen
Opción B — Archivo .env (recomendado):
Archivo .env:
DB_USER=mi_usuario
DB_PASSWORD=mi_password
docker run --env-file .env -p 8080:8080 mi-imagen
Añade
.enva.gitignorepara que nunca se suba al repositorio.
4. Docker Compose
Opción A — env_file:
version: "3.8"
services:
app:
build: .
ports:
- "8080:8080"
env_file:
- .env
depends_on:
- db
db:
image: mysql:8
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: mi_base_datos
ports:
- "3306:3306"
Opción B — Interpolación de variables:
services:
app:
build: .
ports:
- "8080:8080"
environment:
- DB_USER=${DB_USER}
- DB_PASSWORD=${DB_PASSWORD}
depends_onsolo espera a que el contenedor arranque, no a que MySQL esté listo para aceptar conexiones. Considera usar healthchecks o lógica de retry en la aplicación.
5. CI/CD — GitHub Actions
Definir los secretos en el repositorio: Settings → Secrets and variables → Actions.
name: Build & Deploy
on:
push:
branches: [ "main" ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build Docker image
run: docker build -t mi-app .
- name: Run container with secrets
run: |
docker run \
-e DB_USER=${{ secrets.DB_USER }} \
-e DB_PASSWORD=${{ secrets.DB_PASSWORD }} \
mi-app
Nunca uses
echo ${{ secrets.DB_PASSWORD }}en los logs: GitHub lo enmascara, pero es una mala práctica.
6. Buenas prácticas generales
- No subir
.enval repositorio. - No hardcodear credenciales en
config.propertiesni en el código. - No incluir secretos en la imagen Docker.
- Documentar las variables necesarias sin poner valores reales (p. ej., en el
README). - Para producción avanzada: considerar Secret Manager (AWS Secrets Manager, HashiCorp Vault, Azure Key Vault).
7. Tabla comparativa por entorno
| Entorno | Mecanismo | Dónde se definen | ¿Se sube al repo? |
|---|---|---|---|
| Desarrollo local | System.getenv() |
Variables de sesión / sistema | No |
| Dockerfile | ENV (vacío) |
El propio Dockerfile | Sí (sin valores) |
| Docker runtime | -e / --env-file |
Línea de comandos / .env |
No (.env en .gitignore) |
| Docker Compose | env_file / environment |
.env / docker-compose.yml |
No (.env en .gitignore) |
| GitHub Actions | secrets.* |
Settings del repositorio | No (gestionado por GitHub) |