5.2 KiB
5.2 KiB
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
# 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
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:
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
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:
cd ~/workspace/projects/banatie-service
git pull origin main
cd prod-env
docker compose up -d --build banatie-landing
Update API:
cd ~/workspace/projects/banatie-service
git pull origin main
cd prod-env
docker compose up -d --build banatie-api
Update Both:
git pull origin main
cd prod-env
docker compose up -d --build banatie-landing banatie-api
Full Restart:
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:
- Remove
/var/www/banatie.app/(old static files) - Replace banatie.app section in Caddyfile (static → reverse_proxy)
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
- No exposed ports - All traffic goes through Caddy with SSL
- Isolated PostgreSQL - Separate from VPS main database
- Secrets management -
secrets.envnot tracked in git - MinIO SNMD mode - Erasure coding for data protection
Troubleshooting
Check container status:
cd ~/workspace/projects/banatie-service/prod-env
docker compose ps
docker compose logs banatie-api
docker compose logs banatie-landing
Restart specific service:
docker compose restart banatie-api
Full rebuild:
docker compose down
docker compose build --no-cache
docker compose up -d
Check Caddy logs:
docker logs caddy