/
Proyecto: agrobot-platform
Guia de Despliegue v1.0
CULTIVA IA โ€” Skill: zeabur-despliegue-cloud

AgroBot en Zeabur
De Docker Compose a Cloud en 20 min

Migracion completa del stack FastAPI + Next.js + PostgreSQL + Redis a Zeabur con despliegues automaticos, preview deployments y escalado por temporada de cosecha.

FastAPI (Python 3.12) Next.js 14 PostgreSQL Gestionado Redis Gestionado Auto-scaling SSL Automatico Preview PRs
Tiempo de Despliegue
~3 min
vs 25 min en VPS manual
Servicios Migrados
4
API, Web, PostgreSQL, Redis
Entornos Activos
3
Prod / Staging / Preview PRs
Config Manual
0
Auto-deteccion de frameworks
๐Ÿ—บ

Plan de Migracion desde Docker Compose

PASO 1
1
Instalar CLI y autenticar con GitHub
Instala la CLI de Zeabur, inicia sesion y conecta el repositorio agrobot-io/agrobot-platform.
~2 min
2
Crear proyecto y desplegar servicios gestionados
PostgreSQL y Redis desde el Marketplace de Zeabur. Las connection strings se inyectan automaticamente como variables de entorno.
~3 min
3
Desplegar FastAPI (backend)
Zeabur detecta Python y usa Nixpacks. Subir zeabur.toml para override del comando de inicio con Gunicorn.
~5 min
4
Desplegar Next.js (frontend)
Auto-deteccion de Next.js. Configura NEXT_PUBLIC_API_URL apuntando al servicio FastAPI.
~3 min
5
Configurar dominios y ramas
Apuntar DNS de api.agrobot.io y app.agrobot.io. Zeabur genera SSL automaticamente.
~5 min + propagacion DNS
6
Configurar auto-scaling para cosecha
Ajustar min_instances=1 y max_instances=8 en septiembre-noviembre.
~2 min
โš™

Archivos de Configuracion Zeabur

PASO 2
backend/zeabur.toml TOML
# AgroBot โ€” API FastAPI (Python 3.12)
# Zeabur detecta Python automaticamente via requirements.txt

[build]
command = "pip install -r requirements.txt"

[runtime]
# Override: gunicorn con workers async para FastAPI
command = "gunicorn app.main:app -k uvicorn.workers.UvicornWorker --workers 4 --bind 0.0.0.0:$PORT"

[env]
PYTHON_VERSION  = "3.12"
APP_ENV         = "production"
LOG_LEVEL       = "info"
# DATABASE_URL y REDIS_URL son inyectadas automaticamente por Zeabur Marketplace

[scaling]
min_instances = 1
max_instances = 8  # Escala hasta x8 en temporada alta (sep-nov)

[health_check]
path     = "/health"
interval = "30s"
timeout  = "10s"
frontend/zeabur.toml TOML
# AgroBot โ€” Frontend Next.js 14
# Auto-deteccion de Next.js via package.json

[build]
command = "npm run build"
output  = ".next"

[runtime]
command = "npm start"

[env]
NODE_ENV             = "production"
NEXT_PUBLIC_API_URL  = "https://api.agrobot.io"
NEXT_PUBLIC_APP_NAME = "AgroBot"

[scaling]
min_instances = 1
max_instances = 4

[health_check]
path     = "/"
interval = "60s"
๐Ÿ’ป

Comandos CLI de Despliegue

PASO 3
Terminal โ€” Despliegue inicial BASH
# 1. Instalar CLI de Zeabur
npm install -g zeabur

# 2. Autenticar (abre navegador para OAuth con GitHub)
zeabur auth login

# 3. Desplegar el backend FastAPI desde /backend
cd backend
zeabur deploy --name agrobot-api --region sin1   # Singapore (latencia baja para EU+LATAM)

# 4. Variables de entorno de la API
zeabur env set AGROBOT_SECRET_KEY "$(openssl rand -hex 32)"
zeabur env set SENTRY_DSN "https://xxxxx@o123.ingest.sentry.io/456"
# DATABASE_URL y REDIS_URL son auto-inyectadas por el Marketplace

# 5. Dominio personalizado para la API
zeabur domain add api.agrobot.io
# Output: CNAME api.agrobot.io โ†’ agrobot-api.zeabur.app
# SSL Let's Encrypt provisionado automaticamente

# 6. Desplegar frontend Next.js desde /frontend
cd ../frontend
zeabur deploy --name agrobot-web --region sin1
zeabur domain add app.agrobot.io

# 7. Verificar estado de servicios
zeabur env list
zeabur domain list
๐Ÿ—„

Servicios Gestionados โ€” Marketplace Zeabur

PASO 4
๐Ÿ˜
PostgreSQL 16
Backups diarios automaticos. Connection string inyectada como DATABASE_URL.
Activo โ€” 4.2 GB
โšก
Redis 7
Cache de sesiones y colas de tareas Celery. Inyectado como REDIS_URL.
Activo โ€” 128 MB
๐Ÿ”
Meilisearch
Busqueda full-text de parcelas, cultivos y alertas de plagas.
Provisionando...
๐Ÿ“Š
Umami Analytics
Analytics de uso del dashboard sin cookies para cumplir RGPD agricola.
Programado
๐Ÿชฃ
MinIO
Almacenamiento S3 para imagenes de drones y reportes PDF de cosecha.
Programado
๐Ÿค–
n8n Workflows
Automatizacion: alertas de riego, reportes semanales a cooperativas, notifs WhatsApp.
Programado
โœ…
Variables auto-inyectadas por Zeabur Al agregar PostgreSQL y Redis desde el Marketplace, Zeabur inyecta automaticamente DATABASE_URL, REDIS_URL y POSTGRES_PASSWORD en todos los servicios del proyecto. No es necesario copiar ni gestionar credenciales manualmente.
๐ŸŒฟ

Estrategia de Ramas y Entornos

PASO 5
Rama Git Entorno URL Auto-deploy Base de Datos
main PRODUCCION api.agrobot.io / app.agrobot.io โœ“ En cada push PostgreSQL prod
develop STAGING staging-api.agrobot.io โœ“ En cada push PostgreSQL staging
feature/* / fix/* PREVIEW pr-{n}-api.zeabur.app โœ“ Por PR abierta Efimera (se borra con PR)
๐Ÿ’ก
Preview Deployments para el equipo de 4 devs Cada PR abierta recibe un entorno efimero con URL unica. Los 4 desarrolladores de AgroBot pueden revisar cambios en produccion real antes del merge, sin contaminar staging. Zeabur destruye el entorno automaticamente al cerrar la PR.
๐Ÿ”Œ

Script de Automatizacion via API GraphQL

PASO 6
scripts/zeabur-ci.ts TypeScript
/**
 * AgroBot โ€” Zeabur CI/CD Automation Script
 * Usado en GitHub Actions para reiniciar servicios tras migraciones DB
 */

const ZEABUR_API  = "https://gateway.zeabur.com/graphql";
const ZEABUR_TOKEN = process.env.ZEABUR_TOKEN!;

const PROJECT_ID      = "proj_agrobot_production";
const API_SERVICE_ID  = "svc_agrobot_api";
const WEB_SERVICE_ID  = "svc_agrobot_web";

async function zeaburQuery(query: string, variables?: Record<string, any>) {
  const res = await fetch(ZEABUR_API, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "Authorization": `Bearer ${ZEABUR_TOKEN}`,
    },
    body: JSON.stringify({ query, variables }),
  });
  const { data, errors } = await res.json();
  if (errors) throw new Error(errors[0].message);
  return data;
}

/** Reiniciar la API despues de migraciones Alembic */
async function restartAfterMigration() {
  console.log("[AgroBot CI] Reiniciando agrobot-api tras migracion DB...");
  await zeaburQuery(`
    mutation ($id: ObjectID!) {
      restartService(_id: $id)
    }
  `, { id: API_SERVICE_ID });
  console.log("โœ“ agrobot-api reiniciado correctamente");
}

/** Listar estado de todos los servicios del proyecto */
async function listProjectServices() {
  const data = await zeaburQuery(`
    query ($projectId: ObjectID!) {
      project(_id: $projectId) {
        services {
          _id name status
          domains { domain }
        }
      }
    }
  `, { projectId: PROJECT_ID });
  return data.project.services;
}

/** Escalar instancias para temporada de cosecha (sep-nov) */
async function scaleForHarvest(maxInstances: number = 8) {
  console.log(`[AgroBot] Escalando a max ${maxInstances} instancias...`);
  // Zeabur escala automaticamente entre min y max segun CPU/memoria
  // Este script actualiza el limite maximo via API
  await zeaburQuery(`
    mutation ($id: ObjectID!, $max: Int!) {
      updateServiceScaling(_id: $id, maxInstances: $max)
    }
  `, { id: API_SERVICE_ID, max: maxInstances });
}

// Entry point: ejecutar desde GitHub Actions
(async () => {
  const cmd = process.argv[2];
  if (cmd === "restart")    await restartAfterMigration();
  if (cmd === "status")     console.log(await listProjectServices());
  if (cmd === "scale-up")   await scaleForHarvest(8);
  if (cmd === "scale-down")  await scaleForHarvest(2);
})();
.github/workflows/deploy.yml YAML
name: AgroBot Deploy + Migrate
on:
  push:
    branches: [main, develop]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Ejecutar migraciones Alembic
        run: alembic upgrade head
        env:
          DATABASE_URL: ${{ secrets.DATABASE_URL }}

      - name: Reiniciar API en Zeabur
        run: npx ts-node scripts/zeabur-ci.ts restart
        env:
          ZEABUR_TOKEN: ${{ secrets.ZEABUR_TOKEN }}

      - name: Verificar salud del servicio
        run: curl -f https://api.agrobot.io/health
โœ…

Buenas Practicas Aplicadas

๐Ÿ”„
Dejar trabajar la auto-deteccion Para FastAPI y Next.js, Zeabur usa Nixpacks y detecta correctamente las dependencias de requirements.txt y package.json. Solo se usa zeabur.toml para el override del comando de inicio con Gunicorn, que Zeabur no puede inferir.
๐Ÿ”’
Nunca gestionar credenciales de base de datos manualmente Los servicios de Marketplace de Zeabur inyectan DATABASE_URL y REDIS_URL automaticamente. El equipo de AgroBot nunca necesita copiar passwords โ€” ni en local ni en CI.
๐Ÿ“ˆ
Escalado por temporada de cosecha (sep-nov) El script zeabur-ci.ts scale-up aumenta el techo de instancias a 8 antes de septiembre. Zeabur escala automaticamente dentro del rango segun CPU. En diciembre, scale-down lo reduce a 2 para controlar costes.