# Deployment Guide ## Overview GoodGo Platform AI consists of four deployable services: | Service | Technology | Default Port | |---------|-----------|-------------| | **API** | NestJS (Node.js) | 3000 | | **Web** | Next.js | 3001 | | **AI Services** | FastAPI (Python) | 8000 | | **Infrastructure** | Docker Compose | Various | ## Prerequisites - Docker Engine 24+ & Docker Compose v2 - Node.js 22 LTS - pnpm 10.27+ - Python 3.12 (for AI services, if running outside Docker) ## Environment Configuration Copy `.env.example` to `.env` and configure all required values: ```bash cp .env.example .env ``` ### Required Variables | Variable | Description | Example | |----------|-------------|---------| | `DATABASE_URL` | PostgreSQL connection string | `postgresql://user:pass@host:5432/goodgo` | | `JWT_SECRET` | JWT signing key (min 32 chars) | Generate with `openssl rand -hex 32` | | `JWT_REFRESH_SECRET` | Refresh token signing key | Generate with `openssl rand -hex 32` | | `REDIS_URL` | Redis connection string | `redis://localhost:6379` | | `TYPESENSE_API_KEY` | Typesense admin API key | Generate a secure random key | ### Optional Variables | Variable | Description | Default | |----------|-------------|---------| | `API_PORT` | API server port | `3000` | | `WEB_PORT` | Web app port | `3001` | | `NODE_ENV` | Environment mode | `development` | | `CORS_ORIGINS` | Allowed CORS origins | — | | `CLAUDE_API_KEY` | Claude API key (for content moderation) | — | | `NEXT_PUBLIC_MAPBOX_TOKEN` | Mapbox token (for maps) | — | | `VNPAY_*`, `MOMO_*`, `ZALOPAY_*` | Payment gateway credentials | — | ## Infrastructure Setup (Docker Compose) Start all infrastructure services: ```bash docker compose up -d ``` This starts: - **PostgreSQL 16 + PostGIS 3.4** (port 5432) - **Redis 7** (port 6379) - **Typesense 27** (port 8108) - **MinIO** (API: 9000, Console: 9001) - **AI Services** (port 8000) - **Prometheus** (port 9090) - **Grafana** (port 3002) Verify all services are healthy: ```bash docker compose ps ``` All services include health checks. Wait until all show `healthy` status. ## Database Setup ```bash # Generate Prisma client pnpm db:generate # Apply migrations pnpm db:migrate:deploy # Seed initial data (optional) pnpm db:seed ``` ## Building for Production ### API (NestJS) ```bash cd apps/api pnpm build ``` Output: `apps/api/dist/` Run in production: ```bash NODE_ENV=production node apps/api/dist/main.js ``` ### Web (Next.js) ```bash cd apps/web pnpm build ``` Output: `apps/web/.next/` Run in production: ```bash NODE_ENV=production pnpm --filter web start ``` ### AI Services (FastAPI) The AI service runs in Docker via `docker compose`. To build separately: ```bash cd libs/ai-services docker build -t goodgo-ai-services . docker run -p 8000:8000 --env-file ../../.env goodgo-ai-services ``` ## Production Checklist ### Security - [ ] Set strong, unique `JWT_SECRET` and `JWT_REFRESH_SECRET` (min 32 characters) - [ ] Set `NODE_ENV=production` - [ ] Configure `CORS_ORIGINS` to only allow your domain(s) - [ ] Change default database passwords - [ ] Change default MinIO credentials (`MINIO_USER`, `MINIO_PASSWORD`) - [ ] Change default Grafana credentials (`GRAFANA_ADMIN_USER`, `GRAFANA_ADMIN_PASSWORD`) - [ ] Use a strong, unique `TYPESENSE_API_KEY` - [ ] Enable SSL/TLS termination (reverse proxy) - [ ] Set `MINIO_USE_SSL=true` if MinIO is exposed publicly ### Database - [ ] Run `pnpm db:migrate:deploy` (not `db:migrate:dev`) - [ ] Enable PostgreSQL connection pooling (PgBouncer recommended) - [ ] Configure automated backups - [ ] Set appropriate `max_connections` in PostgreSQL config ### Monitoring - [ ] Verify Prometheus is scraping `/metrics` endpoint - [ ] Import Grafana dashboards from `monitoring/grafana/dashboards/` - [ ] Set up alerting rules for error rates and latency ### Performance - [ ] Configure Redis `maxmemory` and eviction policy - [ ] Set appropriate Typesense `--memory-limit` - [ ] Enable gzip/brotli compression in reverse proxy - [ ] Configure CDN for static assets (Next.js `/_next/static/`) ## Health Checks | Service | Endpoint | Expected Response | |---------|----------|-------------------| | API | `GET /metrics` | Prometheus metrics | | AI Services | `GET /health` | `{"status": "ok"}` | | Typesense | `GET /health` | `{"ok": true}` | | Redis | `redis-cli ping` | `PONG` | | PostgreSQL | `pg_isready -h host -p 5432` | Exit code 0 | ## Scaling Considerations ### Horizontal Scaling - **API**: Stateless — scale with multiple instances behind a load balancer - **Web**: Stateless — scale with multiple instances or deploy to Vercel/Cloudflare - **AI Services**: CPU-bound — scale based on valuation request volume - **Redis**: Use Redis Cluster for high availability - **PostgreSQL**: Read replicas for query-heavy workloads ### Recommended Architecture (Production) ``` ┌─────────────┐ │ Load Balancer│ │ (nginx/ALB) │ └──────┬──────┘ │ ┌────────────┼────────────┐ │ │ │ ┌─────▼──┐ ┌─────▼──┐ ┌─────▼──┐ │ API #1 │ │ API #2 │ │ API #N │ └────────┘ └────────┘ └────────┘ │ │ │ └────────────┼────────────┘ │ ┌────────────┼────────────┐ │ │ │ ┌─────▼──┐ ┌─────▼──┐ ┌─────▼─────┐ │ PG │ │ Redis │ │ Typesense │ │Primary │ │Cluster │ │ Cluster │ │+ Replica│ │ │ │ │ └────────┘ └────────┘ └────────────┘ ``` ## Rollback ### Application Rollback Deploy the previous container image or build artifact. The API and Web are stateless — no rollback-specific steps needed. ### Database Rollback Prisma does not support automatic down migrations. If a migration must be reverted: 1. Identify the migration in `prisma/migrations/` 2. Write a manual SQL rollback script 3. Apply via `psql` or a migration tool 4. Update `_prisma_migrations` table Always test migrations against a staging database before production deployment.