Porter provisiona un cluster EKS en tu cuenta AWS y gestiona los despliegues. Tu equipo solo hace git push o lanza el CLI.
Configura Porter conectado a tu cuenta AWS. Porter provisiona el cluster EKS automáticamente.
porter app update nutriflow-api# 1. Instalar Porter CLI brew install porter-dev/porter/porter # 2. Autenticarse porter auth login # 3. Configurar proyecto y cluster (obtenlos del dashboard) porter config set-project --project nutriflow-prod-01 porter config set-cluster --cluster eks-eu-west-1-nutriflow # 4. Provisionar base de datos PostgreSQL 16 en RDS propio porter addon create postgresql \ --name nutriflow-main-db \ --version 16 \ --plan db.t4g.medium \ --storage 100 # 5. Provisionar Redis para caché de sesiones porter addon create redis \ --name nutriflow-cache \ --version 7 \ --plan cache.t4g.small # 6. Inyectar connection strings como secretos porter app env set nutriflow-api \ DATABASE_URL=$(porter addon get nutriflow-main-db --connection-string) porter app env set nutriflow-api \ REDIS_URL=$(porter addon get nutriflow-cache --connection-string) # 7. Primer despliegue porter app update nutriflow-api
Configuración declarativa con API web (autoscaling), worker de PDFs y cron de backup diario.
version: v2 apps: nutriflow-api: build: method: pack # Cloud Native Buildpacks — sin Dockerfile necesario context: . builder: heroku/builder:22 services: # ───── API Web (Express) ───────────────────────────── web: type: web port: 3000 cpus: 0.5 memory: 512Mi replicas: min: 2 # Alta disponibilidad: nunca menos de 2 max: 10 # Escala hasta 10 en picos de uso autoscaling: enabled: true targetCPU: 60 targetMemory: 70 health_check: enabled: true path: /health initialDelaySeconds: 15 domains: - name: api.nutriflow.app # ───── Worker generación de PDFs (CPU-intensivo) ───── pdf-worker: type: worker cpus: 1.5 # Más CPU: Puppeteer/WeasyPrint consume bastante memory: 1.5Gi replicas: min: 1 max: 4 autoscaling: enabled: true targetCPU: 70 command: "node dist/workers/pdf-generator.js" # ───── Cron backup + resumen diario ────────────────── daily-backup: type: job cpus: 0.25 memory: 256Mi command: "node dist/cron/backup-and-report.js" schedule: "0 2 * * *" # 02:00 UTC (03:00 Madrid) timeout: 600 # 10 minutos máximo env: NODE_ENV: production LOG_LEVEL: info TZ: Europe/Madrid # Secretos — valores nunca en git, se inyectan desde Porter DATABASE_URL: secret: true REDIS_URL: secret: true JWT_SECRET: secret: true SENDGRID_API_KEY: secret: true S3_BUCKET_REPORTS: secret: true predeploy: - "npx prisma migrate deploy" # Migraciones ANTES del nuevo pod
Cada PR crea un entorno aislado con su propia base de datos para que QA valide antes del merge.
previews: enabled: true apps: nutriflow-api: build: method: pack builder: heroku/builder:22 services: web: type: web port: 3000 cpus: 0.25 # Recursos reducidos para previews memory: 256Mi replicas: min: 1 max: 1 predeploy: - "npx prisma migrate deploy" - "npx prisma db seed" # Datos de ejemplo para QA addons: - type: postgresql name: preview-db plan: db.t4g.micro # Instancia mínima, se destruye al cerrar PR
Pipeline completo: tests, build y deploy automático a producción en push a main.
name: Deploy NutriFlow a Porter on: push: branches: [main] pull_request: types: [opened, synchronize, reopened] jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: { node-version: '20' } - run: npm ci - run: npm test - run: npm run build deploy-production: needs: test if: github.ref == 'refs/heads/main' runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Deploy a Porter (producción) uses: porter-dev/porter-cli-action@v0.1.0 with: command: app update nutriflow-api env: PORTER_TOKEN: ${{ secrets.PORTER_TOKEN }} PORTER_PROJECT: ${{ secrets.PORTER_PROJECT }} PORTER_CLUSTER: ${{ secrets.PORTER_CLUSTER }} deploy-preview: needs: test if: github.event_name == 'pull_request' runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Deploy entorno preview para PR uses: porter-dev/porter-cli-action@v0.1.0 with: command: preview update env: PORTER_TOKEN: ${{ secrets.PORTER_TOKEN }} PORTER_PROJECT: ${{ secrets.PORTER_PROJECT }} PORTER_CLUSTER: ${{ secrets.PORTER_CLUSTER }}
Equivalentes a Heroku para el equipo de NutriFlow, sin necesidad de saber Kubernetes.
| Operación | Heroku (antes) | Porter (ahora) | Estado |
|---|---|---|---|
| Desplegar | git push heroku main |
porter app update nutriflow-api |
igual de simple |
| Ver logs | heroku logs -t |
porter app logs nutriflow-api --service web -f |
tiempo real |
| Comando one-off | heroku run node seed.js |
porter app run nutriflow-api -- node dist/seed.js |
idéntico |
| Escalar réplicas | heroku ps:scale web=3 |
porter app update nutriflow-api --service web --replicas 3 |
más potente |
| Variables de entorno | heroku config:set KEY=val |
porter app env set nutriflow-api KEY=val |
equivalente |
| Estado de la app | heroku ps |
porter app get nutriflow-api |
más detallado |
# Ver estado de todos los servicios porter app get nutriflow-api # Seguir logs del worker de PDFs porter app logs nutriflow-api --service pdf-worker --follow # Ejecutar migración manual de emergencia porter app run nutriflow-api -- npx prisma migrate deploy # Abrir REPL en el entorno de producción porter app run nutriflow-api -- node -e "require('./dist/repl')" # Ver todos los addons y su estado porter addon list # Rotar un secreto porter app env set nutriflow-api --secret JWT_SECRET=nuevovalor_aqui # Listar entornos preview activos porter preview list
Todo corre en tu cuenta AWS. La factura llega de Amazon, no de Heroku. Monitorea en la consola AWS Cost Explorer.
✓ Autoscaling real (hasta 10 pods)
✓ Datos en tu cuenta (compliance HIPAA-like)
✓ Preview environments para QA
✓ Sin límites de dyno hours
- Exportar dump completo de Heroku Postgres
- Listar todas las variables de entorno (
heroku config) - Documentar addons activos (Scheduler, etc.)
- Crear cuenta AWS y activar MFA
- Elegir región eu-west-1 para cumplimiento GDPR
- Configurar AWS Budgets alert a 200€
- Crear porter.yaml y hacer primer despliegue en staging
- Importar dump a RDS (
pg_restore) - Verificar health check
/healthresponde 200 - Migrar DNS de api.nutriflow.app a Porter
- Smoke test con Postman en producción nueva
- Mantener Heroku activo 1 semana como fallback