- Full grant strategy framework for renewable energy & green hydrogen - AI-powered grant studio, partner outreach, financial modeling - Umami analytics with data-performance tracking - Live Degelas metrics connected to solar.degelas.be - Trilingual (EN/FR/AR) with i18n support - Dockerized with Nginx frontend + Express API proxy
8.2 KiB
8.2 KiB
VPS Deployment Guide
Prerequisites
- Ubuntu 22.04 LTS VPS (or similar)
- Domain name pointing to your VPS IP
- SSH access to the VPS
- Docker & Docker Compose installed
Step 1: Server Setup
1.1 Update System
sudo apt update && sudo apt upgrade -y
1.2 Install Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker $USER
# Log out and back in for group changes to take effect
1.3 Install Docker Compose
sudo apt install docker-compose-plugin -y
1.4 Configure Firewall (UFW)
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow ssh
sudo ufw allow http
sudo ufw allow https
sudo ufw enable
1.5 Install fail2ban (SSH protection)
sudo apt install fail2ban -y
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
Step 2: Clone Repository
cd /opt
sudo git clone <your-repo-url> atlasgreen
cd atlasgreen
Step 3: Configure Environment
# Copy example env file
cp .env.example .env
# Edit with your values
nano .env
Required Variables
# OpenAI API key (required for AI features)
OPENAI_API_KEY=sk-your-actual-key-here
# Degelas API (optional - mock data used if not set)
DEGELAS_API_URL=https://api.degelas.be
DEGELAS_API_KEY=dgl-your-key-here
# Production: set to your actual domain
CLIENT_ORIGIN=https://yourdomain.com
# Logging
LOG_LEVEL=info
Step 4: SSL Certificate (Let's Encrypt)
4.1 Install Certbot
sudo apt install certbot python3-certbot-nginx -y
4.2 Obtain Certificate
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com
4.3 Auto-Renewal Test
sudo certbot renew --dry-run
4.4 Update nginx.conf for HTTPS
Create /etc/nginx/sites-available/atlasgreen:
server {
listen 80;
server_name yourdomain.com www.yourdomain.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name yourdomain.com www.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
# SSL configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# Include the rest of your nginx.conf content here
# (root, location blocks, etc.)
}
4.5 Enable Site
sudo ln -s /etc/nginx/sites-available/atlasgreen /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
Step 5: Deploy with Docker Compose
5.1 Build and Start
cd /opt/atlasgreen
sudo docker compose up -d --build
5.2 Verify Deployment
# Check containers are running
sudo docker compose ps
# Check logs
sudo docker compose logs -f
# Test API health
curl http://localhost/api/health
Expected output:
{"status":"ok","timestamp":"2026-01-15T..."}
5.3 Test Website
Open https://yourdomain.com in your browser.
Step 6: Monitoring Setup
6.1 Log Rotation
Create /etc/logrotate.d/atlasgreen:
/var/log/nginx/atlasgreen/*.log {
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 0640 www-data adm
sharedscripts
postrotate
[ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid`
endscript
}
6.2 Uptime Monitoring
Sign up for free monitoring:
- UptimeRobot: https://uptimerobot.com (50 checks free)
- Pingdom: https://pingdom.com (1 check free)
Configure to monitor https://yourdomain.com/api/health
6.3 Disk Space Alerts
# Add to crontab (crontab -e)
0 6 * * * if [ $(df / | tail -1 | awk '{print $5}' | sed 's/%//') -gt 80 ]; then echo "Disk space warning!" | mail -s "Disk Alert" your@email.com; fi
Step 7: Backup Strategy
7.1 Automated Backups
Create /opt/atlasgreen/backup.sh:
#!/bin/bash
set -e
BACKUP_DIR="/backups/atlasgreen"
DATE=$(date +%Y%m%d_%H%M%S)
# Create backup directory
mkdir -p $BACKUP_DIR
# Backup .env (critical!)
cp .env $BACKUP_DIR/env_$DATE
# Backup docker volumes (if any)
# docker run --rm -v atlasgreen_data:/data -v $BACKUP_DIR:/backup alpine tar czf /backup/data_$DATE.tar.gz /data
# Backup docker-compose.yml
cp docker-compose.yml $BACKUP_DIR/compose_$DATE
# Keep only last 7 backups
find $BACKUP_DIR -type f -mtime +7 -delete
echo "Backup completed: $DATE"
Make executable:
chmod +x /opt/atlasgreen/backup.sh
7.2 Schedule Backups
# Add to crontab (crontab -e)
0 2 * * * /opt/atlasgreen/backup.sh >> /var/log/atlasgreen_backup.log 2>&1
7.3 Test Restore
Periodically test restoring from backup on a test server.
Step 8: Security Hardening
8.1 SSH Hardening
Edit /etc/ssh/sshd_config:
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
AllowUsers your_username
Restart SSH:
sudo systemctl restart sshd
8.2 Automatic Security Updates
sudo apt install unattended-upgrades -y
sudo dpkg-reconfigure -plow unattended-upgrades
8.3 Docker Security Scan
# Install Trivy (vulnerability scanner)
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin
# Scan images
trivy image atlas-green-frontend:latest
trivy image atlas-green-api:latest
Troubleshooting
Container Won't Start
# Check logs
sudo docker compose logs api-server
sudo docker compose logs frontend
# Check if port is in use
sudo lsof -i :80
sudo lsof -i :3001
# Restart containers
sudo docker compose restart
API Returns 502 Bad Gateway
# Check if API server is running
sudo docker compose ps
# Check API logs
sudo docker compose logs api-server
# Check nginx config
sudo nginx -t
# Check nginx logs
sudo tail -f /var/log/nginx/error.log
SSL Certificate Issues
# Check cert status
sudo certbot certificates
# Renew if needed
sudo certbot renew
# Reload nginx
sudo systemctl reload nginx
Disk Space Full
# Check disk usage
df -h
# Clean up old Docker images
sudo docker image prune -a
# Clean up old containers
sudo docker container prune
# Check log sizes
sudo du -sh /var/log/*
Performance Tuning
Nginx Worker Processes
Edit /etc/nginx/nginx.conf:
worker_processes auto;
worker_rlimit_nofile 65535;
events {
worker_connections 4096;
use epoll;
multi_accept on;
}
Docker Resource Limits
Edit docker-compose.yml:
services:
api-server:
deploy:
resources:
limits:
cpus: '1.0'
memory: 512M
reservations:
cpus: '0.25'
memory: 128M
frontend:
deploy:
resources:
limits:
cpus: '0.5'
memory: 256M
Maintenance Commands
Update Application
cd /opt/atlasgreen
git pull
sudo docker compose up -d --build
View Logs
# All services
sudo docker compose logs -f
# Specific service
sudo docker compose logs -f api-server
# Last 100 lines
sudo docker compose logs --tail=100
Restart Services
# All services
sudo docker compose restart
# Specific service
sudo docker compose restart api-server
Check Health
# API health
curl http://localhost/api/health
# Check containers
sudo docker compose ps
# Check disk space
df -h
# Check memory
free -h
Rollback Procedure
If deployment fails:
1. Stop New Deployment
sudo docker compose down
2. Revert Code
cd /opt/atlasgreen
git checkout <previous-commit>
3. Rebuild
sudo docker compose up -d --build
4. Verify
sudo docker compose logs -f
curl http://localhost/api/health
Contact & Support
| Issue | Action |
|---|---|
| Server down | Check VPS provider console, reboot if needed |
| SSL expired | Run sudo certbot renew |
| Disk full | Clean logs, prune Docker, expand disk |
| API errors | Check logs, restart API container |
| Database issues | N/A (no database in this app) |
Deployment Version: 1.0
Last Updated: January 2026