# Complete Deployment Architecture ## Overview This document describes the complete deployment architecture for all services running on geeplo.com. ## Services Overview ### 1. **Juntete** - Group Expense Tracking - **URL**: https://geeplo.com/juntete - **Frontend**: Next.js (Port 3000) - **Backend**: FastAPI (Port 8000) - **Database**: SQLite with volume persistence - **Features**: - Multi-currency expense tracking - Receipt upload functionality - Percentage-based expense splitting - Offline-capable with sync ### 2. **Jenkins** - CI/CD Pipeline - **URL**: https://geeplo.com/jenkins/ - **Container**: jenkins/jenkins:lts-jdk21 - **Port**: 8080 (internal) - **Features**: - Automated deployment pipeline - Poll SCM for changes - Health checks - Automated container orchestration ### 3. **Authentik** - SSO/Authentication - **URL**: https://geeplo.com/auth/ - **Container**: ghcr.io/goauthentik/server:2025.10.1 - **Ports**: 9000 (HTTP), 9443 (HTTPS) - **Components**: - Server (authentik-deploy-server-1) - Worker (authentik-deploy-worker-1) ### 4. **Landing Page** - **URL**: https://geeplo.com/ - **Container**: nginx:alpine - **Port**: 80 (internal) ### 5. **PostgreSQL** - Database Server - **Container**: postgres:18-alpine - **Port**: 5432 - **Features**: - DataShield database - Automated backups ## Nginx Routing Architecture ### HTTP (Port 80) - All traffic redirected to HTTPS (except /health check) - Health check endpoint: `http://geeplo.com/health` ### HTTPS (Port 443) All services accessible through reverse proxy with SSL/TLS: ``` geeplo.com/ ├── / → Landing Page ├── /juntete/ → Juntete Frontend │ ├── /juntete/api/ → Juntete Backend (rewritten to /api/) │ ├── /juntete/uploads/→ Juntete Uploads (rewritten to /uploads/) │ └── /juntete/_next/ → Next.js Assets ├── /jenkins/ → Jenkins CI/CD └── /auth/ → Authentik SSO ├── /auth/static/ → Authentik Static Assets └── /auth/media/ → Authentik Media Files ``` ### Upstream Configuration All services use connection pooling with keepalive connections: - jenkins_backend (keepalive: 32) - authentik_backend (keepalive: 32) - juntete_frontend (keepalive: 32) - juntete_backend (keepalive: 32) - landing_page (keepalive: 32) ## Docker Networks ### services-network Connected containers: - nginx-proxy - jenkins - authentik-deploy-server-1 - authentik-deploy-worker-1 - landing-page ### juntete-deploy_juntete-network Connected containers: - nginx-proxy - juntete-deploy-frontend-1 - juntete-deploy-backend-1 ### postgres-deploy_datashield-network Connected containers: - authentik-deploy-server-1 - postgres-postgres - datashield-backup ## SSL/TLS Configuration ### Certificates - **Provider**: Let's Encrypt - **Location**: `/etc/letsencrypt/live/geeplo.com/` - **Files**: - fullchain.pem (certificate chain) - privkey.pem (private key) - chain.pem (trusted certificate) ### SSL Settings - **Protocols**: TLSv1.2, TLSv1.3 - **Ciphers**: HIGH:!aNULL:!MD5 - **Session Cache**: 10m shared - **Session Timeout**: 10m ### Security Headers All responses include: - `Strict-Transport-Security: max-age=31536000; includeSubDomains; preload` - `X-Frame-Options: SAMEORIGIN` - `X-Content-Type-Options: nosniff` - `X-XSS-Protection: 1; mode=block` - `Referrer-Policy: strict-origin-when-cross-origin` ## Jenkins CI/CD Pipeline ### Configuration File **Location**: `/Users/william.persico/Desktop/github/juntete/Jenkinsfile` ### Pipeline Stages 1. **Build Images** - Uses `docker compose -f docker-compose.production.yml build --no-cache` - Rebuilds both frontend and backend images from scratch 2. **Stop Old Containers** - Gracefully stops existing containers - Uses `docker compose -f docker-compose.production.yml down` 3. **Start New Containers** - Starts updated containers in detached mode - Uses `docker compose -f docker-compose.production.yml up -d` 4. **Wait for Startup** - 30-second delay for services to initialize - Ensures containers are fully operational 5. **Health Check** - Verifies containers are running - Checks backend health: `http://localhost:8000/health` - Checks frontend: `http://localhost:3000/juntete` ### Post-Build Actions - Always displays container status - Shows recent logs (last 20 lines) for backend and frontend - Reports success/failure status ### Trigger - **Type**: Poll SCM - **Schedule**: Every 2 minutes - **Branch**: main ## File Locations ### On Server (192.168.1.124) - Nginx config: `/home/geeplo/services/nginx/nginx.conf` - Nginx backup: `/home/geeplo/services/nginx/nginx.conf.backup` - Jenkins workspace: `/home/geeplo/services/jenkins_home/workspace/juntete-deploy/` ### In Repository - Main Jenkinsfile: `/Jenkinsfile` - Production compose: `/docker-compose.production.yml` - Backend Dockerfile: `/backend/Dockerfile` - Frontend Dockerfile: `/frontend/Dockerfile` - Next.js config: `/frontend/next.config.js` - API client: `/frontend/lib/api.ts` ## Deployment Workflow ### Automated Deployment (via Jenkins) 1. Developer pushes code to GitHub main branch 2. Jenkins polls repository every 2 minutes 3. On change detection: - Pulls latest code - Builds Docker images (no cache) - Stops old containers - Starts new containers - Runs health checks - Reports status ### Manual Deployment (if needed) ```bash # SSH to server ssh geeplo@192.168.1.124 # Navigate to workspace cd /home/geeplo/services/jenkins_home/workspace/juntete-deploy # Pull latest code git pull origin main # Rebuild and restart sudo docker compose -f docker-compose.production.yml build --no-cache sudo docker compose -f docker-compose.production.yml down sudo docker compose -f docker-compose.production.yml up -d # Check status sudo docker compose -f docker-compose.production.yml ps ``` ## Container Port Mappings | Service | Internal Port | External Port | Notes | |---------|--------------|---------------|-------| | juntete-frontend | 3000 | 3000 | Next.js app | | juntete-backend | 8000 | 8000 | FastAPI | | jenkins | 8080 | - | Via nginx proxy only | | authentik-server | 9000, 9443 | 9000, 9443 | Direct + nginx | | postgres | 5432 | 5432 | Database | | nginx-proxy | 80, 443 | 80, 443 | Main gateway | | landing-page | 80 | - | Via nginx proxy only | ## Environment Variables ### Juntete Frontend - `NEXT_PUBLIC_BASE_PATH`: `/juntete` (default) - `BACKEND_URL`: `http://backend:8000` (Docker internal) ### Juntete Backend - `DEBUG`: `false` (production) - `DATABASE_URL`: SQLite file path - `UPLOAD_DIR`: `/app/uploads` ## Data Persistence ### Docker Volumes - `sqlite_data`: Juntete database (`/app/data/juntete.db`) - `receipts_data`: Receipt uploads (`/app/uploads/receipts`) - `postgres_data`: PostgreSQL data ### Backups - PostgreSQL backups managed by datashield-backup container - Nginx config backed up before each update - Git repository serves as code backup ## Testing Service Availability ### Quick Test ```bash # Test all services curl -k https://geeplo.com/ # Landing page curl -k https://geeplo.com/juntete # Juntete app curl -k https://geeplo.com/jenkins/ # Jenkins curl -k https://geeplo.com/auth/ # Authentik ``` ### Detailed Health Check ```bash # Backend health curl -k http://localhost:8000/health # Frontend health curl -k http://localhost:3000/juntete # Nginx logs sudo docker logs nginx-proxy --tail 50 # Service status sudo docker ps ``` ## Troubleshooting ### Nginx Issues ```bash # Check nginx configuration sudo docker exec nginx-proxy nginx -t # Reload nginx sudo docker exec nginx-proxy nginx -s reload # View nginx logs sudo docker logs nginx-proxy --tail 100 # Restart nginx sudo docker restart nginx-proxy ``` ### Juntete Issues ```bash # View logs sudo docker logs juntete-deploy-frontend-1 --tail 50 sudo docker logs juntete-deploy-backend-1 --tail 50 # Restart services cd /home/geeplo/services/jenkins_home/workspace/juntete-deploy sudo docker compose -f docker-compose.production.yml restart ``` ### Jenkins Issues ```bash # View Jenkins logs sudo docker logs jenkins --tail 100 # Restart Jenkins sudo docker restart jenkins # Access Jenkins directly http://192.168.1.124:8080/jenkins (if port exposed) ``` ### Network Issues ```bash # List networks sudo docker network ls # Inspect network sudo docker network inspect services-network sudo docker network inspect juntete-deploy_juntete-network # Connect container to network sudo docker network connect services-network ``` ## Security Considerations ### Firewall Rules - Only ports 80 and 443 should be exposed externally - All other services accessed via nginx reverse proxy - SSH access limited to specific IPs (if configured) ### SSL/TLS - All HTTP traffic automatically redirected to HTTPS - Strong cipher suites enabled - HSTS enabled with preload - Certificate auto-renewal via certbot ### Access Control - Jenkins: Requires authentication - Authentik: Provides SSO for all services - Database: Internal network only ## Monitoring ### Health Endpoints - System health: https://geeplo.com/health - Juntete backend: http://localhost:8000/health (internal) - All services monitored via health checks in Jenkins pipeline ### Logs All logs accessible via `docker logs`: - nginx-proxy - juntete-deploy-frontend-1 - juntete-deploy-backend-1 - jenkins - authentik-deploy-server-1 ## Maintenance ### Regular Tasks 1. **Monitor Jenkins builds**: Check for failed deployments 2. **Review logs**: Look for errors or warnings 3. **SSL renewal**: Certbot handles auto-renewal 4. **Backup verification**: Test restore procedures 5. **Security updates**: Keep containers updated ### Update Nginx Configuration ```bash # 1. Edit local config vim /tmp/nginx-new.conf # 2. Upload to server scp /tmp/nginx-new.conf geeplo@192.168.1.124:/tmp/nginx-new.conf # 3. Backup current config ssh geeplo@192.168.1.124 "sudo cp /home/geeplo/services/nginx/nginx.conf /home/geeplo/services/nginx/nginx.conf.backup" # 4. Test new config ssh geeplo@192.168.1.124 "sudo docker cp /tmp/nginx-new.conf nginx-proxy:/tmp/nginx.conf.test && sudo docker exec nginx-proxy nginx -t -c /tmp/nginx.conf.test" # 5. Apply new config ssh geeplo@192.168.1.124 "sudo cp /tmp/nginx-new.conf /home/geeplo/services/nginx/nginx.conf && sudo docker exec nginx-proxy nginx -s reload" ``` ## Service URLs Summary | Service | URL | Status | |---------|-----|--------| | Landing Page | https://geeplo.com/ | ✓ 200 | | Juntete App | https://geeplo.com/juntete | ✓ 200 | | Jenkins CI/CD | https://geeplo.com/jenkins/ | ✓ 200 | | Authentik SSO | https://geeplo.com/auth/ | ✓ 302 | ## Recent Changes ### 2025-11-22 1. **Nginx Configuration** - Redesigned complete routing for all services - Added Jenkins at /jenkins/ - Added Authentik at /auth/ - Improved upstream connection pooling - Enhanced SSL/TLS configuration 2. **Jenkinsfile Updates** - Migrated from `docker-compose` to `docker compose` - Fixed frontend health check port (3002 → 3000) - Added separate Wait for Startup stage - Improved logging and status reporting 3. **API Configuration** - Fixed frontend API base URL to default to `/juntete` - Updated Next.js rewrites for proper routing - Backend configured with `root_path="/juntete"` ## Contact & Support For issues or questions: 1. Check Jenkins build logs: https://geeplo.com/jenkins/ 2. Review container logs: `sudo docker logs ` 3. Check nginx configuration: `sudo docker exec nginx-proxy nginx -t` --- **Last Updated**: 2025-11-22 **Maintained By**: Development Team **Server**: geeplo.com (192.168.1.124)