docs: add architecture, deployment guides and update dev environment docs
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
226
docs/deployment.md
Normal file
226
docs/deployment.md
Normal file
@@ -0,0 +1,226 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user