Saltar al contenido principal

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á:

  1. ✅ Desplegar en Railway
  2. ✅ Desplegar en Heroku
  3. ✅ Comprender las opciones de AWS
  4. ✅ Configurar una base de datos gestionada
  5. ✅ Elegir la plataforma adecuada

1. Comparación de Plataformas​

PlataformaDificultadCostoIdeal para
Railway⭐ FácilGratis → $5/mesProyectos personales, startups
Heroku⭐ Fácil$7/mesApps simples
Render⭐ FácilGratis → $7/mesAlternativa a Heroku
AWS ECS⭐⭐⭐ ComplejoVariableEnterprise
Kubernetes⭐⭐⭐⭐ AvanzadoVariableMicroservicios

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

  1. Ir a railway.app
  2. "New Project" → "Deploy from GitHub repo"
  3. Seleccione su repositorio
  4. 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​

  1. En el proyecto Railway: "New" → "Database" → "PostgreSQL"
  2. 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​

  1. Ir a render.com
  2. "New" → "Web Service"
  3. Conectar GitHub
  4. Configurar:
    • Build Command: mvn clean package -DskipTests
    • Start Command: java -jar target/*.jar

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


⬅️ Volver al Módulo 12