189 lines
4.6 KiB
Markdown
189 lines
4.6 KiB
Markdown
# 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, Eclipse, Docker, docker-compose y CI/CD (GitHub Actions).
|
|
|
|
---
|
|
|
|
## 1. Desarrollo local (Java)
|
|
|
|
Leer secretos usando `System.getenv()`:
|
|
|
|
```java
|
|
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 variables de entorno en la sesión activa
|
|
|
|
**Windows (PowerShell):**
|
|
```powershell
|
|
$env:DB_USER="mi_usuario"
|
|
$env:DB_PASSWORD="mi_password"
|
|
```
|
|
|
|
**Linux / Mac / WSL:**
|
|
```bash
|
|
export DB_USER=mi_usuario
|
|
export DB_PASSWORD=mi_password
|
|
```
|
|
|
|
> Las variables solo existen en la sesión activa. Para persistirlas, se pueden añadir a `.bashrc`, `.zshrc` o a las variables de entorno del sistema.
|
|
|
|
### En Eclipse (Run Configuration)
|
|
|
|
1. Click derecho sobre el proyecto → **Run As → Run Configurations…**
|
|
2. Selecciona tu aplicación → pestaña **Environment**
|
|
3. Añade las variables:
|
|
```
|
|
Name: DB_USER Value: mi_usuario
|
|
Name: DB_PASSWORD Value: mi_password
|
|
```
|
|
4. Apply → Run
|
|
|
|
> Esto hace que `System.getenv("DB_USER")` funcione al ejecutar la app desde Eclipse.
|
|
|
|
---
|
|
|
|
## 2. Dockerfile
|
|
|
|
Nunca incluir secretos directamente. Solo declarar variables vacías como documentación:
|
|
|
|
```dockerfile
|
|
# Documentación de variables esperadas en runtime
|
|
ENV DB_USER=""
|
|
ENV DB_PASSWORD=""
|
|
```
|
|
|
|
> La aplicación sigue leyendo los valores con `System.getenv()` en tiempo de ejecución. Los secretos reales se pasan al contenedor.
|
|
|
|
---
|
|
|
|
## 3. Docker (runtime)
|
|
|
|
**Opción A — Variables en línea:**
|
|
```bash
|
|
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
|
|
```
|
|
|
|
```bash
|
|
docker run --env-file .env -p 8080:8080 mi-imagen
|
|
```
|
|
|
|
> Añade `.env` a `.gitignore` para que nunca se suba al repositorio.
|
|
|
|
---
|
|
|
|
## 4. Docker Compose
|
|
|
|
Archivo `.env`:
|
|
```
|
|
DB_USER=mi_usuario
|
|
DB_PASSWORD=mi_password
|
|
DB_ROOT_PASSWORD=root
|
|
```
|
|
|
|
Archivo `docker-compose.yml`:
|
|
```yaml
|
|
version: "3.8"
|
|
|
|
services:
|
|
app:
|
|
build: .
|
|
ports:
|
|
- "8080:8080"
|
|
env_file:
|
|
- .env
|
|
depends_on:
|
|
- db
|
|
|
|
db:
|
|
image: mysql:latest
|
|
container_name: mysql_vdlp
|
|
hostname: mysql.vdlp
|
|
ports:
|
|
- "3306:3306"
|
|
env_file:
|
|
- .env
|
|
volumes:
|
|
- ./mysql/conf.d:/etc/mysql/conf.d
|
|
- ./mysql/init:/docker-entrypoint-initdb.d
|
|
- mysql_data:/var/lib/mysql
|
|
restart: always
|
|
|
|
volumes:
|
|
mysql_data:
|
|
```
|
|
|
|
> `depends_on` solo garantiza que el contenedor `db` haya **arrancado**, no que MySQL esté listo para aceptar conexiones. La aplicación puede fallar al inicio si intenta conectarse antes de que MySQL termine de inicializarse. Se recomienda añadir lógica de reintento en la aplicación.
|
|
|
|
---
|
|
|
|
## 5. CI/CD — GitHub Actions
|
|
|
|
Definir los secretos en el repositorio: **Settings → Secrets and variables → Actions**.
|
|
|
|
```yaml
|
|
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 logs. GitHub lo enmascara, pero sigue siendo mala práctica.
|
|
|
|
---
|
|
|
|
## 6. Buenas prácticas generales
|
|
|
|
- No subir `.env` al repositorio.
|
|
- No hardcodear credenciales en `config.properties` ni en el código.
|
|
- No incluir secretos en la imagen Docker.
|
|
- Documentar las variables necesarias sin poner valores reales (README, Dockerfile vacío).
|
|
- 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 |
|
|
| Eclipse | Run Configurations | Pestaña Environment en Run Config | No |
|
|
| Dockerfile | `ENV` (vacío) | El propio Dockerfile | Sí (sin valores) |
|
|
| Docker runtime | `-e` / `--env-file` | Línea de comandos / `.env` | No |
|
|
| Docker Compose | `env_file` | `.env` | No |
|
|
| GitHub Actions | `secrets.*` | Settings del repositorio | No |
|
|
|
|
|
|
---
|
|
Fuentes: [ChatGPT](https://chat.openai.com) + [Claude](https://claude.ai) |