feat: add Digital Ocean deployment configuration
- Create docker-compose.digitalocean.yml for registry-based deployment - Add .env.digitalocean.example template for cloud deployment - Add comprehensive DIGITAL_OCEAN_DEPLOYMENT.md guide - Configure image pulling from Gitea registry - Include SSL setup with Caddy/Traefik - Add backup, monitoring, and security instructions Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
46
.env.digitalocean.example
Normal file
46
.env.digitalocean.example
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
# ==========================================
|
||||||
|
# VIP Coordinator - Digital Ocean Environment
|
||||||
|
# ==========================================
|
||||||
|
# Copy this file to .env.digitalocean and fill in your values
|
||||||
|
# Then deploy with: docker-compose -f docker-compose.digitalocean.yml --env-file .env.digitalocean up -d
|
||||||
|
|
||||||
|
# ==========================================
|
||||||
|
# Gitea Registry Configuration
|
||||||
|
# ==========================================
|
||||||
|
# Your local Gitea server (accessible from Digital Ocean)
|
||||||
|
# If Gitea is on your LAN, you'll need to expose it or use a VPN
|
||||||
|
GITEA_REGISTRY=YOUR_PUBLIC_GITEA_URL:3000
|
||||||
|
IMAGE_TAG=latest
|
||||||
|
|
||||||
|
# ==========================================
|
||||||
|
# Database Configuration
|
||||||
|
# ==========================================
|
||||||
|
POSTGRES_DB=vip_coordinator
|
||||||
|
POSTGRES_USER=vip_user
|
||||||
|
POSTGRES_PASSWORD=CHANGE_ME_TO_STRONG_PASSWORD_12345
|
||||||
|
|
||||||
|
# ==========================================
|
||||||
|
# Auth0 Configuration
|
||||||
|
# ==========================================
|
||||||
|
# Get these from your Auth0 dashboard
|
||||||
|
# IMPORTANT: Update Auth0 callbacks to use your production domain
|
||||||
|
AUTH0_DOMAIN=dev-s855cy3bvjjbkljt.us.auth0.com
|
||||||
|
AUTH0_AUDIENCE=https://vip-coordinator-api
|
||||||
|
AUTH0_ISSUER=https://dev-s855cy3bvjjbkljt.us.auth0.com/
|
||||||
|
AUTH0_CLIENT_ID=JXEVOIfS5eYCkeKbbCWIkBYIvjqdSP5d
|
||||||
|
|
||||||
|
# ==========================================
|
||||||
|
# Frontend Configuration
|
||||||
|
# ==========================================
|
||||||
|
# Port 80 for HTTP (will be behind reverse proxy for HTTPS)
|
||||||
|
FRONTEND_PORT=80
|
||||||
|
|
||||||
|
# ==========================================
|
||||||
|
# Optional: External APIs
|
||||||
|
# ==========================================
|
||||||
|
AVIATIONSTACK_API_KEY=
|
||||||
|
|
||||||
|
# ==========================================
|
||||||
|
# Optional: Database Seeding
|
||||||
|
# ==========================================
|
||||||
|
RUN_SEED=false
|
||||||
459
DIGITAL_OCEAN_DEPLOYMENT.md
Normal file
459
DIGITAL_OCEAN_DEPLOYMENT.md
Normal file
@@ -0,0 +1,459 @@
|
|||||||
|
# VIP Coordinator - Digital Ocean Deployment Guide
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
This guide walks you through deploying VIP Coordinator to Digital Ocean using pre-built Docker images from your Gitea registry.
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
- [ ] Digital Ocean account
|
||||||
|
- [ ] Docker images pushed to Gitea registry (completed ✅)
|
||||||
|
- [ ] Domain name (recommended) or will use droplet IP
|
||||||
|
- [ ] Auth0 account configured
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
```
|
||||||
|
Internet
|
||||||
|
│
|
||||||
|
├─> Your Domain (optional)
|
||||||
|
│
|
||||||
|
↓
|
||||||
|
[Digital Ocean Droplet]
|
||||||
|
│
|
||||||
|
├─> Caddy/Traefik (Reverse Proxy + SSL)
|
||||||
|
│ ↓
|
||||||
|
├─> Frontend Container (port 80)
|
||||||
|
│ ↓
|
||||||
|
├─> Backend Container (port 3000)
|
||||||
|
│ ↓
|
||||||
|
├─> PostgreSQL Container
|
||||||
|
│ ↓
|
||||||
|
└─> Redis Container
|
||||||
|
```
|
||||||
|
|
||||||
|
## Step 1: Create Digital Ocean Droplet
|
||||||
|
|
||||||
|
### Recommended Specifications
|
||||||
|
|
||||||
|
**Minimum (Testing):**
|
||||||
|
- **Size:** Basic Droplet - $12/month
|
||||||
|
- **RAM:** 2GB
|
||||||
|
- **CPU:** 1 vCPU
|
||||||
|
- **Storage:** 50GB SSD
|
||||||
|
- **Region:** Choose closest to your users
|
||||||
|
|
||||||
|
**Recommended (Production):**
|
||||||
|
- **Size:** General Purpose - $24/month
|
||||||
|
- **RAM:** 4GB
|
||||||
|
- **CPU:** 2 vCPUs
|
||||||
|
- **Storage:** 80GB SSD
|
||||||
|
- **Region:** Choose closest to your users
|
||||||
|
|
||||||
|
### Create Droplet
|
||||||
|
|
||||||
|
1. Go to [Digital Ocean](https://cloud.digitalocean.com/droplets/new)
|
||||||
|
2. **Choose Image:** Ubuntu 24.04 LTS x64
|
||||||
|
3. **Choose Size:** Select based on recommendations above
|
||||||
|
4. **Choose Region:** Select closest region
|
||||||
|
5. **Authentication:** SSH keys (recommended) or password
|
||||||
|
6. **Hostname:** `vip-coordinator`
|
||||||
|
7. **Tags:** `production`, `vip-coordinator`
|
||||||
|
8. **Backups:** Enable weekly backups (recommended)
|
||||||
|
9. Click **Create Droplet**
|
||||||
|
|
||||||
|
## Step 2: Initial Server Setup
|
||||||
|
|
||||||
|
### SSH into Droplet
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ssh root@YOUR_DROPLET_IP
|
||||||
|
```
|
||||||
|
|
||||||
|
### Update System
|
||||||
|
|
||||||
|
```bash
|
||||||
|
apt update && apt upgrade -y
|
||||||
|
```
|
||||||
|
|
||||||
|
### Create Non-Root User
|
||||||
|
|
||||||
|
```bash
|
||||||
|
adduser vipcoord
|
||||||
|
usermod -aG sudo vipcoord
|
||||||
|
usermod -aG docker vipcoord # Will add docker group later
|
||||||
|
```
|
||||||
|
|
||||||
|
### Configure Firewall (UFW)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Enable UFW
|
||||||
|
ufw default deny incoming
|
||||||
|
ufw default allow outgoing
|
||||||
|
|
||||||
|
# Allow SSH
|
||||||
|
ufw allow OpenSSH
|
||||||
|
|
||||||
|
# Allow HTTP and HTTPS
|
||||||
|
ufw allow 80/tcp
|
||||||
|
ufw allow 443/tcp
|
||||||
|
|
||||||
|
# Enable firewall
|
||||||
|
ufw enable
|
||||||
|
|
||||||
|
# Check status
|
||||||
|
ufw status
|
||||||
|
```
|
||||||
|
|
||||||
|
## Step 3: Install Docker
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Install Docker
|
||||||
|
curl -fsSL https://get.docker.com -o get-docker.sh
|
||||||
|
sh get-docker.sh
|
||||||
|
|
||||||
|
# Add user to docker group
|
||||||
|
usermod -aG docker vipcoord
|
||||||
|
|
||||||
|
# Install Docker Compose
|
||||||
|
apt install docker-compose-plugin -y
|
||||||
|
|
||||||
|
# Verify installation
|
||||||
|
docker --version
|
||||||
|
docker compose version
|
||||||
|
```
|
||||||
|
|
||||||
|
## Step 4: Configure Gitea Registry Access
|
||||||
|
|
||||||
|
### Option A: Public Gitea (Recommended)
|
||||||
|
|
||||||
|
If your Gitea is publicly accessible:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Login to Gitea registry
|
||||||
|
docker login YOUR_PUBLIC_GITEA_URL:3000 -u kyle
|
||||||
|
# Enter your Gitea token: 2f4370ce710a4a1f84e8bf6c459fe63041376c0e
|
||||||
|
```
|
||||||
|
|
||||||
|
### Option B: Gitea on LAN (Requires VPN/Tunnel)
|
||||||
|
|
||||||
|
If your Gitea is on LAN (192.168.68.53):
|
||||||
|
|
||||||
|
**Solutions:**
|
||||||
|
1. **Tailscale VPN** (Recommended)
|
||||||
|
- Install Tailscale on both your local machine and Digital Ocean droplet
|
||||||
|
- Access Gitea via Tailscale IP
|
||||||
|
|
||||||
|
2. **SSH Tunnel**
|
||||||
|
```bash
|
||||||
|
# On your local machine
|
||||||
|
ssh -L 3000:192.168.68.53:3000 root@YOUR_DROPLET_IP
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Expose Gitea Publicly** (Not Recommended for Security)
|
||||||
|
- Configure port forwarding on your router
|
||||||
|
- Use dynamic DNS service
|
||||||
|
- Set up Cloudflare tunnel
|
||||||
|
|
||||||
|
### Option C: Alternative - Push to Docker Hub
|
||||||
|
|
||||||
|
If Gitea access is complex, push images to Docker Hub instead:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# On your local machine
|
||||||
|
docker tag 192.168.68.53:3000/kyle/vip-coordinator/backend:latest kyle/vip-coordinator-backend:latest
|
||||||
|
docker tag 192.168.68.53:3000/kyle/vip-coordinator/frontend:latest kyle/vip-coordinator-frontend:latest
|
||||||
|
|
||||||
|
docker push kyle/vip-coordinator-backend:latest
|
||||||
|
docker push kyle/vip-coordinator-frontend:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
Then update `docker-compose.digitalocean.yml` to use Docker Hub images.
|
||||||
|
|
||||||
|
## Step 5: Deploy Application
|
||||||
|
|
||||||
|
### Copy Files to Droplet
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# On your local machine
|
||||||
|
scp docker-compose.digitalocean.yml root@YOUR_DROPLET_IP:/home/vipcoord/
|
||||||
|
scp .env.digitalocean.example root@YOUR_DROPLET_IP:/home/vipcoord/
|
||||||
|
```
|
||||||
|
|
||||||
|
### Configure Environment
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# On droplet
|
||||||
|
cd /home/vipcoord
|
||||||
|
|
||||||
|
# Copy and edit environment file
|
||||||
|
cp .env.digitalocean.example .env.digitalocean
|
||||||
|
nano .env.digitalocean
|
||||||
|
```
|
||||||
|
|
||||||
|
**Update these values:**
|
||||||
|
```env
|
||||||
|
# If using LAN Gitea via Tailscale
|
||||||
|
GITEA_REGISTRY=100.x.x.x:3000
|
||||||
|
|
||||||
|
# If using public Gitea
|
||||||
|
GITEA_REGISTRY=gitea.yourdomain.com:3000
|
||||||
|
|
||||||
|
# If using Docker Hub
|
||||||
|
# Comment out GITEA_REGISTRY and update image names in docker-compose
|
||||||
|
|
||||||
|
# Strong database password
|
||||||
|
POSTGRES_PASSWORD=YOUR_STRONG_PASSWORD_HERE
|
||||||
|
|
||||||
|
# Auth0 configuration (same as before)
|
||||||
|
AUTH0_DOMAIN=dev-s855cy3bvjjbkljt.us.auth0.com
|
||||||
|
AUTH0_CLIENT_ID=JXEVOIfS5eYCkeKbbCWIkBYIvjqdSP5d
|
||||||
|
AUTH0_AUDIENCE=https://vip-coordinator-api
|
||||||
|
AUTH0_ISSUER=https://dev-s855cy3bvjjbkljt.us.auth0.com/
|
||||||
|
```
|
||||||
|
|
||||||
|
### Start Services
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Start all services
|
||||||
|
docker compose -f docker-compose.digitalocean.yml --env-file .env.digitalocean up -d
|
||||||
|
|
||||||
|
# Check status
|
||||||
|
docker compose -f docker-compose.digitalocean.yml ps
|
||||||
|
|
||||||
|
# View logs
|
||||||
|
docker compose -f docker-compose.digitalocean.yml logs -f
|
||||||
|
```
|
||||||
|
|
||||||
|
## Step 6: Set Up Reverse Proxy with SSL
|
||||||
|
|
||||||
|
### Option A: Caddy (Recommended - Easiest)
|
||||||
|
|
||||||
|
Create `Caddyfile`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nano Caddyfile
|
||||||
|
```
|
||||||
|
|
||||||
|
```caddy
|
||||||
|
your-domain.com {
|
||||||
|
reverse_proxy localhost:80
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Run Caddy:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker run -d \
|
||||||
|
--name caddy \
|
||||||
|
-p 80:80 \
|
||||||
|
-p 443:443 \
|
||||||
|
-v /home/vipcoord/Caddyfile:/etc/caddy/Caddyfile \
|
||||||
|
-v caddy_data:/data \
|
||||||
|
-v caddy_config:/config \
|
||||||
|
--restart unless-stopped \
|
||||||
|
caddy:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
Caddy automatically handles:
|
||||||
|
- SSL certificate from Let's Encrypt
|
||||||
|
- HTTP to HTTPS redirect
|
||||||
|
- Certificate renewal
|
||||||
|
|
||||||
|
### Option B: Traefik
|
||||||
|
|
||||||
|
Create `docker-compose.traefik.yml`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
traefik:
|
||||||
|
image: traefik:v2.10
|
||||||
|
command:
|
||||||
|
- "--api.insecure=true"
|
||||||
|
- "--providers.docker=true"
|
||||||
|
- "--entrypoints.web.address=:80"
|
||||||
|
- "--entrypoints.websecure.address=:443"
|
||||||
|
- "--certificatesresolvers.letsencrypt.acme.email=your@email.com"
|
||||||
|
- "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
|
||||||
|
- "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web"
|
||||||
|
ports:
|
||||||
|
- "80:80"
|
||||||
|
- "443:443"
|
||||||
|
volumes:
|
||||||
|
- "/var/run/docker.sock:/var/run/docker.sock:ro"
|
||||||
|
- "./letsencrypt:/letsencrypt"
|
||||||
|
restart: unless-stopped
|
||||||
|
```
|
||||||
|
|
||||||
|
## Step 7: Configure Auth0
|
||||||
|
|
||||||
|
Update Auth0 application settings:
|
||||||
|
|
||||||
|
1. Go to [Auth0 Dashboard](https://manage.auth0.com/)
|
||||||
|
2. Select your application
|
||||||
|
3. **Allowed Callback URLs:** Add `https://your-domain.com`
|
||||||
|
4. **Allowed Web Origins:** Add `https://your-domain.com`
|
||||||
|
5. **Allowed Logout URLs:** Add `https://your-domain.com`
|
||||||
|
6. Click **Save Changes**
|
||||||
|
|
||||||
|
## Step 8: Database Backups
|
||||||
|
|
||||||
|
### Automated Daily Backups
|
||||||
|
|
||||||
|
Create backup script:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nano /home/vipcoord/backup-db.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
#!/bin/bash
|
||||||
|
BACKUP_DIR="/home/vipcoord/backups"
|
||||||
|
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
|
||||||
|
|
||||||
|
mkdir -p $BACKUP_DIR
|
||||||
|
|
||||||
|
docker exec vip-coordinator-postgres pg_dump -U vip_user vip_coordinator | gzip > $BACKUP_DIR/vip_coordinator_$TIMESTAMP.sql.gz
|
||||||
|
|
||||||
|
# Keep only last 7 days
|
||||||
|
find $BACKUP_DIR -name "vip_coordinator_*.sql.gz" -mtime +7 -delete
|
||||||
|
```
|
||||||
|
|
||||||
|
Make executable and add to cron:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
chmod +x /home/vipcoord/backup-db.sh
|
||||||
|
|
||||||
|
# Add to crontab (daily at 2 AM)
|
||||||
|
crontab -e
|
||||||
|
# Add this line:
|
||||||
|
0 2 * * * /home/vipcoord/backup-db.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
## Step 9: Monitoring and Logging
|
||||||
|
|
||||||
|
### View Logs
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# All services
|
||||||
|
docker compose -f docker-compose.digitalocean.yml logs -f
|
||||||
|
|
||||||
|
# Specific service
|
||||||
|
docker compose -f docker-compose.digitalocean.yml logs -f backend
|
||||||
|
|
||||||
|
# Last 100 lines
|
||||||
|
docker compose -f docker-compose.digitalocean.yml logs --tail=100 backend
|
||||||
|
```
|
||||||
|
|
||||||
|
### Check Container Health
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker ps
|
||||||
|
docker compose -f docker-compose.digitalocean.yml ps
|
||||||
|
```
|
||||||
|
|
||||||
|
### Monitor Resources
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Real-time resource usage
|
||||||
|
docker stats
|
||||||
|
|
||||||
|
# Disk usage
|
||||||
|
df -h
|
||||||
|
docker system df
|
||||||
|
```
|
||||||
|
|
||||||
|
## Step 10: Updating Application
|
||||||
|
|
||||||
|
When you push new images to Gitea:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# On droplet
|
||||||
|
cd /home/vipcoord
|
||||||
|
|
||||||
|
# Pull latest images
|
||||||
|
docker compose -f docker-compose.digitalocean.yml pull
|
||||||
|
|
||||||
|
# Restart with new images
|
||||||
|
docker compose -f docker-compose.digitalocean.yml down
|
||||||
|
docker compose -f docker-compose.digitalocean.yml up -d
|
||||||
|
|
||||||
|
# Verify
|
||||||
|
docker compose -f docker-compose.digitalocean.yml ps
|
||||||
|
docker compose -f docker-compose.digitalocean.yml logs -f
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Application Not Accessible
|
||||||
|
|
||||||
|
1. Check firewall: `ufw status`
|
||||||
|
2. Check containers: `docker ps`
|
||||||
|
3. Check logs: `docker compose logs -f`
|
||||||
|
4. Check Auth0 callback URLs match your domain
|
||||||
|
|
||||||
|
### Database Connection Issues
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check postgres is running
|
||||||
|
docker exec vip-coordinator-postgres pg_isready -U vip_user
|
||||||
|
|
||||||
|
# Check backend can connect
|
||||||
|
docker compose logs backend | grep -i database
|
||||||
|
```
|
||||||
|
|
||||||
|
### SSL Certificate Issues
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Caddy logs
|
||||||
|
docker logs caddy
|
||||||
|
|
||||||
|
# Force certificate renewal
|
||||||
|
docker exec caddy caddy reload --config /etc/caddy/Caddyfile
|
||||||
|
```
|
||||||
|
|
||||||
|
## Security Checklist
|
||||||
|
|
||||||
|
- [ ] Firewall configured (only 22, 80, 443 open)
|
||||||
|
- [ ] SSH key authentication (disable password auth)
|
||||||
|
- [ ] Non-root user for application
|
||||||
|
- [ ] Strong database password
|
||||||
|
- [ ] Auth0 callbacks restricted to production domain
|
||||||
|
- [ ] Automated backups configured
|
||||||
|
- [ ] SSL/TLS enabled
|
||||||
|
- [ ] Regular system updates scheduled
|
||||||
|
- [ ] Fail2ban installed for SSH protection
|
||||||
|
- [ ] Docker containers run as non-root users
|
||||||
|
|
||||||
|
## Cost Estimation
|
||||||
|
|
||||||
|
**Monthly Costs:**
|
||||||
|
- Droplet (4GB): $24/month
|
||||||
|
- Backups (20%): ~$5/month
|
||||||
|
- **Total:** ~$29/month
|
||||||
|
|
||||||
|
**Optional:**
|
||||||
|
- Domain name: $10-15/year
|
||||||
|
- Digital Ocean Managed Database (if scaling): $15/month+
|
||||||
|
|
||||||
|
## Support
|
||||||
|
|
||||||
|
- **Digital Ocean Docs:** https://docs.digitalocean.com/
|
||||||
|
- **Docker Docs:** https://docs.docker.com/
|
||||||
|
- **Auth0 Docs:** https://auth0.com/docs
|
||||||
|
|
||||||
|
## Next Steps
|
||||||
|
|
||||||
|
1. Set up domain name (optional but recommended)
|
||||||
|
2. Configure monitoring (Uptime Robot, etc.)
|
||||||
|
3. Set up log aggregation (Digital Ocean Monitoring, Papertrail)
|
||||||
|
4. Configure automated updates
|
||||||
|
5. Add staging environment for testing
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Deployment completed!** 🚀
|
||||||
|
|
||||||
|
Your VIP Coordinator is now live at `https://your-domain.com`
|
||||||
137
docker-compose.digitalocean.yml
Normal file
137
docker-compose.digitalocean.yml
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
# ==========================================
|
||||||
|
# VIP Coordinator - Digital Ocean Deployment
|
||||||
|
# ==========================================
|
||||||
|
# This compose file pulls pre-built images from Gitea registry
|
||||||
|
# No local builds required - perfect for cloud deployment
|
||||||
|
|
||||||
|
services:
|
||||||
|
# PostgreSQL Database
|
||||||
|
postgres:
|
||||||
|
image: postgres:16-alpine
|
||||||
|
container_name: vip-coordinator-postgres
|
||||||
|
environment:
|
||||||
|
POSTGRES_DB: ${POSTGRES_DB:-vip_coordinator}
|
||||||
|
POSTGRES_USER: ${POSTGRES_USER:-vip_user}
|
||||||
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?POSTGRES_PASSWORD must be set}
|
||||||
|
volumes:
|
||||||
|
- vip-coordinator-postgres-data:/var/lib/postgresql/data
|
||||||
|
networks:
|
||||||
|
- vip-coordinator-network
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-vip_user}"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
|
start_period: 10s
|
||||||
|
restart: unless-stopped
|
||||||
|
logging:
|
||||||
|
driver: "json-file"
|
||||||
|
options:
|
||||||
|
max-size: "10m"
|
||||||
|
max-file: "3"
|
||||||
|
|
||||||
|
# Redis Cache
|
||||||
|
redis:
|
||||||
|
image: redis:7-alpine
|
||||||
|
container_name: vip-coordinator-redis
|
||||||
|
volumes:
|
||||||
|
- vip-coordinator-redis-data:/data
|
||||||
|
networks:
|
||||||
|
- vip-coordinator-network
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "redis-cli", "ping"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 3s
|
||||||
|
retries: 5
|
||||||
|
start_period: 5s
|
||||||
|
restart: unless-stopped
|
||||||
|
logging:
|
||||||
|
driver: "json-file"
|
||||||
|
options:
|
||||||
|
max-size: "10m"
|
||||||
|
max-file: "3"
|
||||||
|
command: redis-server --appendonly yes
|
||||||
|
|
||||||
|
# NestJS Backend API (from Gitea registry)
|
||||||
|
backend:
|
||||||
|
image: ${GITEA_REGISTRY:-192.168.68.53:3000}/kyle/vip-coordinator/backend:${IMAGE_TAG:-latest}
|
||||||
|
container_name: vip-coordinator-backend
|
||||||
|
environment:
|
||||||
|
# Database Configuration
|
||||||
|
DATABASE_URL: postgresql://${POSTGRES_USER:-vip_user}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB:-vip_coordinator}
|
||||||
|
|
||||||
|
# Redis Configuration
|
||||||
|
REDIS_URL: redis://redis:6379
|
||||||
|
|
||||||
|
# Auth0 Configuration
|
||||||
|
AUTH0_DOMAIN: ${AUTH0_DOMAIN:?AUTH0_DOMAIN must be set}
|
||||||
|
AUTH0_AUDIENCE: ${AUTH0_AUDIENCE:?AUTH0_AUDIENCE must be set}
|
||||||
|
AUTH0_ISSUER: ${AUTH0_ISSUER:?AUTH0_ISSUER must be set}
|
||||||
|
|
||||||
|
# Application Configuration
|
||||||
|
NODE_ENV: production
|
||||||
|
PORT: 3000
|
||||||
|
|
||||||
|
# Optional: AviationStack API (for flight tracking)
|
||||||
|
AVIATIONSTACK_API_KEY: ${AVIATIONSTACK_API_KEY:-}
|
||||||
|
|
||||||
|
# Optional: Database seeding
|
||||||
|
RUN_SEED: ${RUN_SEED:-false}
|
||||||
|
depends_on:
|
||||||
|
postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
redis:
|
||||||
|
condition: service_healthy
|
||||||
|
networks:
|
||||||
|
- vip-coordinator-network
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3000/api/v1/health"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
start_period: 40s
|
||||||
|
restart: unless-stopped
|
||||||
|
logging:
|
||||||
|
driver: "json-file"
|
||||||
|
options:
|
||||||
|
max-size: "10m"
|
||||||
|
max-file: "3"
|
||||||
|
|
||||||
|
# React Frontend (Nginx) (from Gitea registry)
|
||||||
|
frontend:
|
||||||
|
image: ${GITEA_REGISTRY:-192.168.68.53:3000}/kyle/vip-coordinator/frontend:${IMAGE_TAG:-latest}
|
||||||
|
container_name: vip-coordinator-frontend
|
||||||
|
ports:
|
||||||
|
- "${FRONTEND_PORT:-80}:80"
|
||||||
|
depends_on:
|
||||||
|
backend:
|
||||||
|
condition: service_healthy
|
||||||
|
networks:
|
||||||
|
- vip-coordinator-network
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost/health"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 3s
|
||||||
|
retries: 3
|
||||||
|
start_period: 5s
|
||||||
|
restart: unless-stopped
|
||||||
|
logging:
|
||||||
|
driver: "json-file"
|
||||||
|
options:
|
||||||
|
max-size: "10m"
|
||||||
|
max-file: "3"
|
||||||
|
|
||||||
|
# Named volumes for data persistence
|
||||||
|
volumes:
|
||||||
|
vip-coordinator-postgres-data:
|
||||||
|
name: vip-coordinator-postgres-data
|
||||||
|
vip-coordinator-redis-data:
|
||||||
|
name: vip-coordinator-redis-data
|
||||||
|
|
||||||
|
# Dedicated network for service communication
|
||||||
|
networks:
|
||||||
|
vip-coordinator-network:
|
||||||
|
name: vip-coordinator-network
|
||||||
|
driver: bridge
|
||||||
Reference in New Issue
Block a user