399 lines
9.0 KiB
Markdown
399 lines
9.0 KiB
Markdown
# Environment Configuration Guide
|
|
|
|
## Overview
|
|
|
|
Banatie uses a monorepo structure with **two separate environment configurations**:
|
|
- **Development** (`apps/api-service/`) - Infrastructure in Docker, API runs locally
|
|
- **Production** (`prod-env/`) - All services run in Docker containers
|
|
|
|
---
|
|
|
|
## Services & Ports
|
|
|
|
| Service | Port(s) | Description | Container Name |
|
|
|-----------------|--------------|------------------------------|----------------------------|
|
|
| PostgreSQL | 5460 → 5432 | Database | banatie-postgres(-dev) |
|
|
| MinIO API | 9000 → 9000 | Object storage (S3) | banatie-storage(-dev) |
|
|
| MinIO Console | 9001 → 9001 | Storage management UI | banatie-storage(-dev) |
|
|
| API Service | 3000 → 3000 | REST API (prod only) | banatie-app |
|
|
| Landing Page | 3001 → 3000 | Public website (prod only) | banatie-landing |
|
|
| Studio Platform | 3002 | SaaS (future) | - |
|
|
| Admin Dashboard | 3003 | Administration (future) | - |
|
|
|
|
**Port Format**: `host:container` (e.g., `5460:5432` means host port 5460 maps to container port 5432)
|
|
|
|
---
|
|
|
|
## Runtime Modes
|
|
|
|
### Development Mode (`apps/api-service/`)
|
|
|
|
**Use Case**: Active development with hot reload
|
|
|
|
**Structure**:
|
|
```
|
|
apps/api-service/
|
|
├── docker-compose.yml # Infrastructure only (postgres, minio)
|
|
├── .env # Dev config (localhost endpoints)
|
|
└── secrets.env # API keys (not in git)
|
|
```
|
|
|
|
**Launch**:
|
|
```bash
|
|
cd apps/api-service
|
|
pnpm dev
|
|
```
|
|
|
|
**What happens**:
|
|
1. Starts infrastructure: postgres, minio (Docker)
|
|
2. API runs locally with `tsx --watch` (hot reload)
|
|
3. Connects via port forwarding: `localhost:5460`, `localhost:9000`
|
|
|
|
**Configuration**:
|
|
- Database: `localhost:5460`
|
|
- MinIO: `localhost:9000`
|
|
- Hot reload enabled
|
|
- Uses local `.env` + `secrets.env`
|
|
|
|
---
|
|
|
|
### Production Mode (`prod-env/`)
|
|
|
|
**Use Case**: Production deployment, local testing
|
|
|
|
**Structure**:
|
|
```
|
|
prod-env/
|
|
├── docker-compose.yml # All services (postgres, minio, api, landing)
|
|
├── .env # Prod config (Docker hostnames)
|
|
├── secrets.env # API keys (not in git)
|
|
└── README.md # Deployment instructions
|
|
```
|
|
|
|
**Launch**:
|
|
```bash
|
|
cd prod-env
|
|
docker compose up -d
|
|
```
|
|
|
|
**What happens**:
|
|
1. All services run in Docker containers
|
|
2. Internal Docker network: `postgres:5432`, `minio:9000`
|
|
3. Host access via port forwarding
|
|
4. Production-optimized builds
|
|
|
|
**Configuration**:
|
|
- Database: `postgres:5432` (internal)
|
|
- MinIO: `minio:9000` (internal)
|
|
- Production build (TypeScript compiled)
|
|
- Uses prod `.env` + `secrets.env`
|
|
|
|
---
|
|
|
|
## Environment Files
|
|
|
|
### Development `.env` (`apps/api-service/.env`)
|
|
|
|
**Purpose**: Local development configuration
|
|
|
|
```env
|
|
# Connects to Docker via port forwarding
|
|
DATABASE_URL=postgresql://banatie_user:banatie_secure_password@localhost:5460/banatie_db
|
|
MINIO_ENDPOINT=localhost:9000
|
|
```
|
|
|
|
✅ **Committed to git** (no secrets)
|
|
|
|
---
|
|
|
|
### Production `.env` (`prod-env/.env`)
|
|
|
|
**Purpose**: Production Docker configuration
|
|
|
|
```env
|
|
# Internal Docker network hostnames
|
|
DATABASE_URL=postgresql://banatie_user:banatie_secure_password@postgres:5432/banatie_db
|
|
MINIO_ENDPOINT=minio:9000
|
|
```
|
|
|
|
✅ **Committed to git** (no secrets)
|
|
|
|
---
|
|
|
|
### Secrets (`secrets.env`)
|
|
|
|
**Purpose**: Sensitive API keys and credentials
|
|
|
|
```env
|
|
# Required
|
|
GEMINI_API_KEY=your_key_here
|
|
|
|
# Optional (generated by API)
|
|
MASTER_KEY=will_be_generated
|
|
API_KEY=will_be_generated
|
|
```
|
|
|
|
❌ **NOT committed to git**
|
|
✅ Template available: `secrets.env.example`
|
|
|
|
---
|
|
|
|
## Key Configuration Differences
|
|
|
|
| Variable | Dev (`apps/api-service/.env`) | Prod (`prod-env/.env`) |
|
|
|----------|-------------------------------|------------------------|
|
|
| `DATABASE_URL` | `localhost:5460` | `postgres:5432` |
|
|
| `MINIO_ENDPOINT` | `localhost:9000` | `minio:9000` |
|
|
| `RESULTS_DIR` | `./results` | `/app/results` |
|
|
| `UPLOADS_DIR` | `./uploads/temp` | `/app/uploads/temp` |
|
|
| `IS_DOCKER` | not set | `true` |
|
|
|
|
---
|
|
|
|
## How db.ts Loads Config
|
|
|
|
The `apps/api-service/src/db.ts` file has smart loading:
|
|
|
|
```typescript
|
|
// 1. Load .env only if NOT in Docker
|
|
if (existsSync(envPath) && !process.env['IS_DOCKER']) {
|
|
config({ path: envPath });
|
|
}
|
|
|
|
// 2. Always load secrets.env if exists
|
|
if (existsSync(secretsPath)) {
|
|
config({ path: secretsPath });
|
|
}
|
|
```
|
|
|
|
- **Dev mode**: Loads `apps/api-service/.env` + `secrets.env`
|
|
- **Prod mode**: Uses Docker env vars + `secrets.env`
|
|
|
|
---
|
|
|
|
## Docker Network
|
|
|
|
- **Network Name**: `banatie-network` (prod), `banatie-dev-network` (dev)
|
|
- **Internal DNS**: Containers reach each other by service name
|
|
- **Host Access**: Use `localhost` with mapped ports
|
|
|
|
---
|
|
|
|
## Database Credentials
|
|
|
|
**PostgreSQL**:
|
|
- Host (dev): `localhost:5460`
|
|
- Host (prod): `postgres:5432`
|
|
- Database: `banatie_db`
|
|
- User: `banatie_user`
|
|
- Password: `banatie_secure_password`
|
|
|
|
**MinIO**:
|
|
- Endpoint (dev): `http://localhost:9000`
|
|
- Endpoint (prod): `http://minio:9000`
|
|
- Console: `http://localhost:9001`
|
|
- Root User: `banatie_admin`
|
|
- Root Password: `banatie_storage_secure_key_2024`
|
|
- Service Account: `banatie_service` / `banatie_service_key_2024`
|
|
- Bucket: `banatie`
|
|
|
|
---
|
|
|
|
## Storage Layout
|
|
|
|
**MinIO Structure**:
|
|
```
|
|
banatie/
|
|
├── {orgSlug}/
|
|
│ └── {projectSlug}/
|
|
│ ├── generated/
|
|
│ │ └── {year-month}/
|
|
│ │ └── {filename}.{ext}
|
|
│ └── uploads/
|
|
│ └── {year-month}/
|
|
│ └── {filename}.{ext}
|
|
```
|
|
|
|
**Local Volumes** (both modes):
|
|
- Database: `data/postgres/`
|
|
- MinIO: `data/storage/drive{1-4}/` (SNMD mode)
|
|
- Results: `data/results/`
|
|
- Uploads: `data/uploads/`
|
|
|
|
---
|
|
|
|
## Quick Commands
|
|
|
|
### Development
|
|
|
|
```bash
|
|
# Start dev environment
|
|
cd apps/api-service
|
|
pnpm dev
|
|
|
|
# Stop infrastructure
|
|
pnpm infra:down
|
|
|
|
# View logs
|
|
pnpm infra:logs
|
|
```
|
|
|
|
### Production
|
|
|
|
```bash
|
|
# Start all services
|
|
cd prod-env
|
|
docker compose up -d
|
|
|
|
# View logs
|
|
docker compose logs -f app # API
|
|
docker compose logs -f landing # Landing
|
|
docker compose logs -f postgres # DB
|
|
|
|
# Stop all
|
|
docker compose down
|
|
|
|
# Rebuild after code changes
|
|
docker compose up -d --build
|
|
```
|
|
|
|
### Database Access
|
|
|
|
```bash
|
|
# From host (both modes)
|
|
psql -h localhost -p 5460 -U banatie_user -d banatie_db
|
|
|
|
# From Docker container (prod only)
|
|
docker exec -it banatie-postgres psql -U banatie_user -d banatie_db
|
|
```
|
|
|
|
---
|
|
|
|
## Health Checks
|
|
|
|
All services have health checks:
|
|
|
|
- **PostgreSQL**: `pg_isready -U banatie_user -d banatie_db`
|
|
- **MinIO**: `curl -f http://localhost:9000/minio/health/live`
|
|
|
|
Intervals: 30s, timeout: 10s, retries: 3, start period: 40s
|
|
|
|
---
|
|
|
|
## Troubleshooting
|
|
|
|
### Port Already in Use
|
|
|
|
Check what's using the port:
|
|
```bash
|
|
lsof -i :5460 # PostgreSQL
|
|
lsof -i :9000 # MinIO
|
|
lsof -i :3000 # API
|
|
```
|
|
|
|
### Database Connection Refused
|
|
|
|
1. Check containers are running:
|
|
```bash
|
|
docker ps | grep banatie
|
|
```
|
|
|
|
2. Check health status:
|
|
```bash
|
|
docker compose ps # In respective directory
|
|
```
|
|
|
|
3. Verify port in `.env` matches mode:
|
|
- Dev: `localhost:5460`
|
|
- Prod: `postgres:5432`
|
|
|
|
### MinIO Connection Refused
|
|
|
|
1. Check MinIO is healthy:
|
|
```bash
|
|
docker logs banatie-storage(-dev)
|
|
```
|
|
|
|
2. Verify endpoint in `.env`:
|
|
- Dev: `localhost:9000`
|
|
- Prod: `minio:9000`
|
|
|
|
3. Check storage-init completed:
|
|
```bash
|
|
docker logs banatie-storage-init(-dev)
|
|
```
|
|
|
|
### "No such file or directory" for secrets.env
|
|
|
|
Create from template:
|
|
```bash
|
|
# Dev
|
|
cd apps/api-service
|
|
cp secrets.env.example secrets.env
|
|
# Edit with your GEMINI_API_KEY
|
|
|
|
# Prod
|
|
cd prod-env
|
|
cp secrets.env.example secrets.env
|
|
# Edit with your GEMINI_API_KEY
|
|
```
|
|
|
|
---
|
|
|
|
## Migration Guide
|
|
|
|
### From Old Structure to New
|
|
|
|
The project was reorganized to separate dev/prod configs:
|
|
|
|
**Before**:
|
|
```
|
|
/.env # Confusing mix of localhost/docker
|
|
/docker-compose.yml # Unclear if dev or prod
|
|
```
|
|
|
|
**After**:
|
|
```
|
|
/apps/api-service/
|
|
├── docker-compose.yml # Dev infrastructure
|
|
└── .env # Dev config (localhost)
|
|
|
|
/prod-env/
|
|
├── docker-compose.yml # Prod all services
|
|
└── .env # Prod config (docker hostnames)
|
|
```
|
|
|
|
**Changes**:
|
|
1. Port: `5434` → `5460` (everywhere)
|
|
2. Secrets: Moved to `secrets.env` (not in git)
|
|
3. `db.ts`: Removed `override: true`, added `IS_DOCKER` check
|
|
4. Dockerfile: `Dockerfile.mono` → `Dockerfile`
|
|
|
|
---
|
|
|
|
## Best Practices
|
|
|
|
1. **Never commit `secrets.env`** - Use templates
|
|
2. **Use correct config for mode** - Dev vs Prod `.env`
|
|
3. **Test locally before deploy** - Use `prod-env` locally
|
|
4. **Monitor health checks** - Ensure services are healthy
|
|
5. **Backup data directory** - Especially `data/postgres/`
|
|
|
|
---
|
|
|
|
## Next Steps
|
|
|
|
- ✅ Document environment configuration
|
|
- ✅ Separate dev/prod configurations
|
|
- ✅ Update port from 5434 to 5460
|
|
- ✅ Move secrets to separate file
|
|
- 🔜 Test dev mode
|
|
- 🔜 Test prod mode locally
|
|
- 🔜 Deploy to VPS
|
|
|
|
---
|
|
|
|
**Last Updated**: 2025-01-12
|
|
**Author**: Claude Code
|
|
**Version**: 2.0 (Post-reorganization)
|