Capítulo 4: Despliegue en la Nube
Introducción
Su aplicación está lista, Docker configurado, CI/CD en marcha. ¡Es hora de ponerla en línea! Este capítulo cubre las principales opciones de despliegue en la nube.
🎯 Objetivos del Capítulo
Al final de este capítulo, usted sabrá:
- ✅ Desplegar en Railway
- ✅ Desplegar en Heroku
- ✅ Comprender las opciones de AWS
- ✅ Configurar una base de datos gestionada
- ✅ Elegir la plataforma adecuada
1. Comparación de Plataformas
| Plataforma | Dificultad | Costo | Ideal para |
|---|---|---|---|
| Railway | ⭐ Fácil | Gratis → $5/mes | Proyectos personales, startups |
| Heroku | ⭐ Fácil | $7/mes | Apps simples |
| Render | ⭐ Fácil | Gratis → $7/mes | Alternativa a Heroku |
| AWS ECS | ⭐⭐⭐ Complejo | Variable | Enterprise |
| Kubernetes | ⭐⭐⭐⭐ Avanzado | Variable | Microservicios |
2. Railway (Recomendado para Empezar)
¿Por qué Railway?
- ✅ Interfaz sencilla
- ✅ Despliegue desde GitHub
- ✅ PostgreSQL integrado
- ✅ Gratis para comenzar
- ✅ Soporta Docker
Despliegue
Opción 1: Desde GitHub
- Ir a railway.app
- "New Project" → "Deploy from GitHub repo"
- Seleccione su repositorio
- Railway detecta automáticamente Spring Boot
Opción 2: Con Docker
# Instalar Railway CLI
npm i -g @railway/cli
# Login
railway login
# Crear un proyecto
railway init
# Desplegar
railway up
Configuración
# Variables de entorno (en Railway Dashboard)
SPRING_PROFILES_ACTIVE=prod
DATABASE_URL=${{Postgres.DATABASE_URL}}
Agregar PostgreSQL
- En el proyecto Railway: "New" → "Database" → "PostgreSQL"
- Las variables se inyectan automáticamente
railway.json
{
"$schema": "https://railway.app/railway.schema.json",
"build": {
"builder": "DOCKERFILE",
"dockerfilePath": "Dockerfile"
},
"deploy": {
"startCommand": "java -jar app.jar",
"healthcheckPath": "/actuator/health",
"restartPolicyType": "ON_FAILURE"
}
}
3. Heroku
Preparación
Procfile (en la raíz):
web: java -Dserver.port=$PORT -jar target/*.jar
system.properties:
java.runtime.version=17
Despliegue
# Instalar Heroku CLI
# https://devcenter.heroku.com/articles/heroku-cli
# Login
heroku login
# Crear la app
heroku create my-spring-app
# Agregar PostgreSQL
heroku addons:create heroku-postgresql:mini
# Desplegar
git push heroku main
# Ver logs
heroku logs --tail
Variables de Entorno
heroku config:set SPRING_PROFILES_ACTIVE=prod
heroku config:set JWT_SECRET=your-secret-key
# Ver todas las variables
heroku config
Con Docker
# Login al registry de Heroku
heroku container:login
# Build y push
heroku container:push web
# Desplegar
heroku container:release web
4. Render
Despliegue
- Ir a render.com
- "New" → "Web Service"
- Conectar GitHub
- Configurar:
- Build Command:
mvn clean package -DskipTests - Start Command:
java -jar target/*.jar
- Build Command:
render.yaml
services:
- type: web
name: my-spring-app
env: docker
dockerfilePath: ./Dockerfile
envVars:
- key: SPRING_PROFILES_ACTIVE
value: prod
- key: DATABASE_URL
fromDatabase:
name: mydb
property: connectionString
databases:
- name: mydb
plan: free
5. AWS (Opciones)
Elastic Beanstalk (Sencillo)
# Instalar EB CLI
pip install awsebcli
# Inicializar
eb init
# Crear el entorno
eb create production
# Desplegar
eb deploy
ECS con Fargate (Docker)
# Crear un cluster
aws ecs create-cluster --cluster-name my-cluster
# Crear una task definition (JSON)
aws ecs register-task-definition --cli-input-json file://task-definition.json
# Crear un servicio
aws ecs create-service \
--cluster my-cluster \
--service-name my-service \
--task-definition my-task \
--desired-count 2
task-definition.json
{
"family": "my-spring-app",
"containerDefinitions": [
{
"name": "app",
"image": "myuser/myapp:latest",
"portMappings": [
{
"containerPort": 8080,
"hostPort": 8080
}
],
"environment": [
{
"name": "SPRING_PROFILES_ACTIVE",
"value": "prod"
}
],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/my-app",
"awslogs-region": "us-east-1"
}
}
}
],
"requiresCompatibilities": ["FARGATE"],
"cpu": "256",
"memory": "512"
}
6. Base de Datos Gestionada
Railway PostgreSQL
# Configurado automáticamente
spring.datasource.url=${DATABASE_URL}
Heroku Postgres
# Heroku provee DATABASE_URL automáticamente
spring.datasource.url=${DATABASE_URL}
AWS RDS
spring.datasource.url=jdbc:postgresql://mydb.xxx.us-east-1.rds.amazonaws.com:5432/mydb
spring.datasource.username=${DB_USERNAME}
spring.datasource.password=${DB_PASSWORD}
Parsear DATABASE_URL
Algunas plataformas proveen una URL con el formato:
postgres://user:password@host:5432/dbname
Configuración Spring para parsear:
@Configuration
public class DatabaseConfig {
@Bean
@Profile("prod")
public DataSource dataSource() {
String databaseUrl = System.getenv("DATABASE_URL");
if (databaseUrl != null && databaseUrl.startsWith("postgres://")) {
// Parsear el formato Heroku/Railway
URI uri = URI.create(databaseUrl);
String username = uri.getUserInfo().split(":")[0];
String password = uri.getUserInfo().split(":")[1];
String jdbcUrl = "jdbc:postgresql://" + uri.getHost() + ":" + uri.getPort() + uri.getPath();
HikariDataSource ds = new HikariDataSource();
ds.setJdbcUrl(jdbcUrl);
ds.setUsername(username);
ds.setPassword(password);
return ds;
}
// Fallback
return DataSourceBuilder.create().build();
}
}
7. Checklist de Despliegue
Antes del Despliegue
□ Pruebas pasan localmente
□ Perfil de producción configurado
□ Secrets externalizados
□ Dockerfile probado
□ Health check configurado
□ Logs configurados
Variables de Entorno
# Esenciales
SPRING_PROFILES_ACTIVE=prod
DATABASE_URL=...
JWT_SECRET=...
# Opcionales
SERVER_PORT=8080
JAVA_OPTS="-Xmx512m"
Post-Despliegue
□ Aplicación accesible
□ Health check OK
□ Logs visibles
□ Base de datos conectada
□ Monitoring en marcha
8. Monitoring en Producción
Actuator
management.endpoints.web.exposure.include=health,info,prometheus
management.endpoint.health.show-details=when_authorized
Logging Cloud
# Logs JSON para cloud
logging.pattern.console={"timestamp":"%d","level":"%p","logger":"%c","message":"%m"}%n
Servicios de Monitoring
- Railway: Métricas integradas
- Heroku: Heroku Metrics
- AWS: CloudWatch
- Externo: Datadog, New Relic
9. Resumen
Recomendaciones por Caso de Uso
Proyecto personal / POC:
→ Railway (gratis, sencillo)
Startup / MVP:
→ Railway o Render ($5-20/mes)
PyME / Producción:
→ Heroku o AWS Elastic Beanstalk
Enterprise / Escalado:
→ AWS ECS / Kubernetes
Despliegue Exprés (Railway)
# 1. Tener un Dockerfile
# 2. Push en GitHub
# 3. En railway.app:
# - New Project → GitHub
# - Add PostgreSQL
# - Configurar variables
# 4. ¡Listo! 🚀
🎯 Próximo Paso
¡Manos a la obra! Dockericemos y despleguemos una aplicación.
➡️ TP12.1: Dockerización Completa