235 lines
5.2 KiB
Markdown
235 lines
5.2 KiB
Markdown
# Banatie Production Deployment Plan
|
|
|
|
## Architecture
|
|
|
|
### Isolated Banatie Stack (5 containers):
|
|
```
|
|
banatie-landing - Landing Page (node:20-alpine)
|
|
banatie-api - API Service (node:20-alpine)
|
|
banatie-postgres - PostgreSQL 15 (isolated from VPS PostgreSQL)
|
|
banatie-minio - MinIO storage (SNMD mode)
|
|
banatie-minio-init - Initialization (one-shot)
|
|
```
|
|
|
|
### Domains:
|
|
```
|
|
banatie.app → banatie-landing:3000
|
|
api.banatie.app → banatie-api:3000
|
|
storage.banatie.app → banatie-minio:9001 (MinIO Console)
|
|
```
|
|
|
|
### File Structure:
|
|
```
|
|
~/workspace/projects/banatie-service/ # Git repository (code + config)
|
|
├── apps/
|
|
│ ├── api-service/Dockerfile
|
|
│ └── landing/Dockerfile
|
|
├── packages/database/
|
|
└── prod-env/
|
|
├── docker-compose.yml # Production compose (run from here!)
|
|
├── .env # Config without secrets (in git)
|
|
└── secrets.env # Secrets (NOT in git)
|
|
|
|
/opt/services/data/banatie/ # Runtime data only
|
|
├── postgres/ # PostgreSQL data
|
|
├── storage/drive{1-4}/ # MinIO SNMD
|
|
├── logs/ # API logs
|
|
├── results/ # Generated images
|
|
└── uploads/ # Uploaded files
|
|
```
|
|
|
|
---
|
|
|
|
## Docker Images
|
|
|
|
| Container | Image | Internal Port |
|
|
|-----------|-------|---------------|
|
|
| banatie-landing | Built from apps/landing/Dockerfile | 3000 |
|
|
| banatie-api | Built from apps/api-service/Dockerfile | 3000 |
|
|
| banatie-postgres | postgres:15-alpine | 5432 |
|
|
| banatie-minio | quay.io/minio/minio:latest | 9000 (API), 9001 (Console) |
|
|
|
|
---
|
|
|
|
## Deployment Steps
|
|
|
|
### Step 1: Prepare VPS Directories
|
|
|
|
```bash
|
|
# Create runtime data directory
|
|
sudo mkdir -p /opt/services/data/banatie/{postgres,logs,results,uploads}
|
|
sudo mkdir -p /opt/services/data/banatie/storage/drive{1,2,3,4}
|
|
sudo chown -R $USER:$USER /opt/services/data/banatie
|
|
```
|
|
|
|
### Step 2: Configure Repository
|
|
|
|
```bash
|
|
cd ~/workspace/projects/banatie-service
|
|
|
|
# Create secrets.env (not in git)
|
|
cp prod-env/secrets.env.example prod-env/secrets.env
|
|
nano prod-env/secrets.env
|
|
# Fill in: GEMINI_API_KEY, etc.
|
|
```
|
|
|
|
### Step 3: Configure Caddy
|
|
|
|
Add to `/opt/services/configs/caddy/Caddyfile`:
|
|
```caddy
|
|
banatie.app, www.banatie.app {
|
|
reverse_proxy banatie-landing:3000
|
|
encode gzip
|
|
header {
|
|
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
|
|
X-Content-Type-Options "nosniff"
|
|
X-Frame-Options "DENY"
|
|
}
|
|
}
|
|
|
|
api.banatie.app {
|
|
reverse_proxy banatie-api:3000
|
|
encode gzip
|
|
header {
|
|
Strict-Transport-Security "max-age=31536000"
|
|
X-Content-Type-Options "nosniff"
|
|
}
|
|
}
|
|
|
|
storage.banatie.app {
|
|
reverse_proxy banatie-minio:9001
|
|
header {
|
|
Strict-Transport-Security "max-age=31536000"
|
|
}
|
|
}
|
|
```
|
|
|
|
### Step 4: First Launch
|
|
|
|
```bash
|
|
cd ~/workspace/projects/banatie-service/prod-env
|
|
|
|
# Start stack
|
|
docker compose up -d
|
|
|
|
# Check status
|
|
docker compose ps
|
|
|
|
# View logs
|
|
docker compose logs -f
|
|
|
|
# Restart Caddy to apply config
|
|
docker restart caddy
|
|
|
|
# Create master key
|
|
curl -X POST https://api.banatie.app/api/bootstrap/initial-key
|
|
```
|
|
|
|
---
|
|
|
|
## Update Process
|
|
|
|
### Update Landing:
|
|
```bash
|
|
cd ~/workspace/projects/banatie-service
|
|
git pull origin main
|
|
cd prod-env
|
|
docker compose up -d --build banatie-landing
|
|
```
|
|
|
|
### Update API:
|
|
```bash
|
|
cd ~/workspace/projects/banatie-service
|
|
git pull origin main
|
|
cd prod-env
|
|
docker compose up -d --build banatie-api
|
|
```
|
|
|
|
### Update Both:
|
|
```bash
|
|
git pull origin main
|
|
cd prod-env
|
|
docker compose up -d --build banatie-landing banatie-api
|
|
```
|
|
|
|
### Full Restart:
|
|
```bash
|
|
cd ~/workspace/projects/banatie-service/prod-env
|
|
docker compose down
|
|
docker compose up -d --build
|
|
```
|
|
|
|
**Downtime:** ~2-3 minutes for image build
|
|
|
|
---
|
|
|
|
## DNS Records (add in GoDaddy)
|
|
|
|
| Record | Type | Value |
|
|
|--------|------|-------|
|
|
| banatie.app | A | 62.146.239.118 |
|
|
| www | CNAME | banatie.app |
|
|
| api | A | 62.146.239.118 |
|
|
| storage | A | 62.146.239.118 |
|
|
|
|
---
|
|
|
|
## Migration from Static Landing
|
|
|
|
After successful Docker deployment:
|
|
1. Remove `/var/www/banatie.app/` (old static files)
|
|
2. Replace banatie.app section in Caddyfile (static → reverse_proxy)
|
|
3. `docker restart caddy`
|
|
|
|
---
|
|
|
|
## Network Architecture
|
|
|
|
### Internal Network (banatie-internal)
|
|
- All containers communicate internally
|
|
- No external port exposure
|
|
- PostgreSQL and MinIO API only accessible internally
|
|
|
|
### External Network (proxy-network)
|
|
- Shared with Caddy reverse proxy
|
|
- Landing, API, and MinIO Console exposed to Caddy
|
|
- SSL termination at Caddy
|
|
|
|
---
|
|
|
|
## Security Notes
|
|
|
|
1. **No exposed ports** - All traffic goes through Caddy with SSL
|
|
2. **Isolated PostgreSQL** - Separate from VPS main database
|
|
3. **Secrets management** - `secrets.env` not tracked in git
|
|
4. **MinIO SNMD mode** - Erasure coding for data protection
|
|
|
|
---
|
|
|
|
## Troubleshooting
|
|
|
|
### Check container status:
|
|
```bash
|
|
cd ~/workspace/projects/banatie-service/prod-env
|
|
docker compose ps
|
|
docker compose logs banatie-api
|
|
docker compose logs banatie-landing
|
|
```
|
|
|
|
### Restart specific service:
|
|
```bash
|
|
docker compose restart banatie-api
|
|
```
|
|
|
|
### Full rebuild:
|
|
```bash
|
|
docker compose down
|
|
docker compose build --no-cache
|
|
docker compose up -d
|
|
```
|
|
|
|
### Check Caddy logs:
|
|
```bash
|
|
docker logs caddy
|
|
```
|