mirror of
https://github.com/th30d4y/OpenLearnX.git
synced 2026-05-26 11:25:49 +00:00
Add production deployment scripts and documentation
- PRODUCTION_DEPLOYMENT.md: Comprehensive production deployment guide - deploy.sh: Master deployment script for backend and frontend - deploy-backend.sh: Automated backend deployment with health checks - deploy-frontend.sh: Automated frontend build and deployment Features: - Automated dependency installation - Database connection verification - Health checks for services - PM2 process management - Backup creation - Multi-environment support (production/staging/local)
This commit is contained in:
@@ -0,0 +1,495 @@
|
||||
# OpenLearnX Production Deployment Guide
|
||||
|
||||
**Last Updated:** May 12, 2026
|
||||
**Status:** Ready for Production Deployment
|
||||
|
||||
---
|
||||
|
||||
## 📋 Table of Contents
|
||||
1. [Prerequisites](#prerequisites)
|
||||
2. [Backend Deployment](#backend-deployment)
|
||||
3. [Frontend Deployment](#frontend-deployment)
|
||||
4. [Environment Configuration](#environment-configuration)
|
||||
5. [Database Setup](#database-setup)
|
||||
6. [Blockchain Setup](#blockchain-setup)
|
||||
7. [Post-Deployment Checks](#post-deployment-checks)
|
||||
8. [Monitoring & Maintenance](#monitoring--maintenance)
|
||||
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
|
||||
### Required Tools
|
||||
- Node.js 18+ (for frontend)
|
||||
- Python 3.10+ (for backend)
|
||||
- MongoDB 4.4+ (database)
|
||||
- Foundry/Anvil or Ethereum RPC endpoint (blockchain)
|
||||
- Git
|
||||
- PM2 or systemd (process manager)
|
||||
- Nginx or Apache (reverse proxy)
|
||||
- SSL/TLS certificates (HTTPS)
|
||||
|
||||
### Recommended Hosting
|
||||
- **Backend:** Heroku, DigitalOcean, AWS, GCP, or self-hosted VPS
|
||||
- **Frontend:** Vercel, Netlify, or static hosting
|
||||
- **Database:** MongoDB Atlas, AWS DocumentDB, or self-hosted
|
||||
- **Blockchain:** Alchemy, Infura, or self-hosted node
|
||||
|
||||
---
|
||||
|
||||
## Backend Deployment
|
||||
|
||||
### Option 1: Deploy to Heroku
|
||||
|
||||
#### 1. Prerequisites
|
||||
```bash
|
||||
npm install -g heroku
|
||||
heroku login
|
||||
```
|
||||
|
||||
#### 2. Create Procfile
|
||||
```bash
|
||||
cd backend
|
||||
cat > Procfile << 'EOF'
|
||||
web: python main.py
|
||||
EOF
|
||||
```
|
||||
|
||||
#### 3. Create requirements file (if not exists)
|
||||
```bash
|
||||
pip freeze > requirements.txt
|
||||
```
|
||||
|
||||
#### 4. Deploy to Heroku
|
||||
```bash
|
||||
heroku create openlearnx-backend
|
||||
git push heroku main
|
||||
|
||||
# Set environment variables
|
||||
heroku config:set FLASK_ENV=production
|
||||
heroku config:set MONGODB_URI=<your-mongodb-uri>
|
||||
heroku config:set WEB3_PROVIDER_URL=<your-rpc-endpoint>
|
||||
heroku config:set CONTRACT_ADDRESS=<deployed-contract-address>
|
||||
heroku config:set SECRET_KEY=<secure-random-key>
|
||||
heroku config:set JWT_SECRET_KEY=<secure-jwt-key>
|
||||
```
|
||||
|
||||
#### 5. View logs
|
||||
```bash
|
||||
heroku logs --tail
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Option 2: Deploy to VPS (DigitalOcean/AWS/Linode)
|
||||
|
||||
#### 1. SSH into server
|
||||
```bash
|
||||
ssh root@your-server-ip
|
||||
```
|
||||
|
||||
#### 2. Install dependencies
|
||||
```bash
|
||||
apt update && apt upgrade -y
|
||||
apt install -y python3.10 python3-pip python3-venv nginx git mongodb
|
||||
```
|
||||
|
||||
#### 3. Clone repository
|
||||
```bash
|
||||
cd /var/www
|
||||
git clone https://github.com/th30d4y/OpenLearnX.git
|
||||
cd OpenLearnX/backend
|
||||
```
|
||||
|
||||
#### 4. Setup Python environment
|
||||
```bash
|
||||
python3 -m venv venv
|
||||
source venv/bin/activate
|
||||
pip install -r ../requirements.txt
|
||||
```
|
||||
|
||||
#### 5. Create .env file
|
||||
```bash
|
||||
cat > .env << 'EOF'
|
||||
FLASK_ENV=production
|
||||
SECRET_KEY=$(python3 -c 'import secrets; print(secrets.token_hex(32))')
|
||||
MONGODB_URI=mongodb://localhost:27017/openlearnx
|
||||
WEB3_PROVIDER_URL=https://eth-mainnet.g.alchemy.com/v2/YOUR-API-KEY
|
||||
CONTRACT_ADDRESS=0x...
|
||||
JWT_SECRET_KEY=$(python3 -c 'import secrets; print(secrets.token_hex(32))')
|
||||
EOF
|
||||
```
|
||||
|
||||
#### 6. Setup PM2
|
||||
```bash
|
||||
npm install -g pm2
|
||||
pm2 start "python3 main.py" --name openlearnx-backend
|
||||
pm2 startup
|
||||
pm2 save
|
||||
```
|
||||
|
||||
#### 7. Configure Nginx
|
||||
```bash
|
||||
cat > /etc/nginx/sites-available/openlearnx-backend << 'EOF'
|
||||
server {
|
||||
listen 80;
|
||||
server_name api.openlearnx.com;
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:5000;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
ln -s /etc/nginx/sites-available/openlearnx-backend /etc/nginx/sites-enabled/
|
||||
nginx -t
|
||||
systemctl restart nginx
|
||||
```
|
||||
|
||||
#### 8. Setup SSL with Let's Encrypt
|
||||
```bash
|
||||
apt install -y certbot python3-certbot-nginx
|
||||
certbot --nginx -d api.openlearnx.com
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Frontend Deployment
|
||||
|
||||
### Option 1: Deploy to Vercel
|
||||
|
||||
#### 1. Connect repository to Vercel
|
||||
- Go to https://vercel.com
|
||||
- Import GitHub repository
|
||||
- Select `frontend` as root directory
|
||||
|
||||
#### 2. Configure environment variables
|
||||
```
|
||||
NEXT_PUBLIC_API_URL=https://api.openlearnx.com
|
||||
NEXT_PUBLIC_CHAIN_ID=1
|
||||
NEXT_PUBLIC_CONTRACT_ADDRESS=0x...
|
||||
NEXT_PUBLIC_RPC_URL=https://eth-mainnet.g.alchemy.com/v2/YOUR-API-KEY
|
||||
```
|
||||
|
||||
#### 3. Deploy
|
||||
```bash
|
||||
git push origin main
|
||||
# Vercel will automatically deploy on push
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Option 2: Deploy to Netlify
|
||||
|
||||
#### 1. Connect repository
|
||||
- Go to https://netlify.com
|
||||
- Import GitHub repository
|
||||
- Select `frontend` as publish directory
|
||||
|
||||
#### 2. Build settings
|
||||
- Build command: `pnpm install && pnpm build`
|
||||
- Publish directory: `.next`
|
||||
|
||||
#### 3. Environment variables
|
||||
```
|
||||
NEXT_PUBLIC_API_URL=https://api.openlearnx.com
|
||||
NEXT_PUBLIC_CHAIN_ID=1
|
||||
NEXT_PUBLIC_CONTRACT_ADDRESS=0x...
|
||||
NEXT_PUBLIC_RPC_URL=https://eth-mainnet.g.alchemy.com/v2/YOUR-API-KEY
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Option 3: Deploy to VPS
|
||||
|
||||
#### 1. SSH into server
|
||||
```bash
|
||||
ssh root@your-server-ip
|
||||
```
|
||||
|
||||
#### 2. Install Node.js
|
||||
```bash
|
||||
curl -sL https://deb.nodesource.com/setup_18.x | sudo -E bash -
|
||||
apt install -y nodejs
|
||||
npm install -g pnpm
|
||||
```
|
||||
|
||||
#### 3. Clone repository
|
||||
```bash
|
||||
cd /var/www
|
||||
git clone https://github.com/th30d4y/OpenLearnX.git
|
||||
cd OpenLearnX/frontend
|
||||
```
|
||||
|
||||
#### 4. Build application
|
||||
```bash
|
||||
pnpm install
|
||||
pnpm build
|
||||
```
|
||||
|
||||
#### 5. Setup PM2
|
||||
```bash
|
||||
pm2 start "pnpm start" --name openlearnx-frontend
|
||||
pm2 startup
|
||||
pm2 save
|
||||
```
|
||||
|
||||
#### 6. Configure Nginx
|
||||
```bash
|
||||
cat > /etc/nginx/sites-available/openlearnx-frontend << 'EOF'
|
||||
server {
|
||||
listen 80;
|
||||
server_name openlearnx.com;
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:3000;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
ln -s /etc/nginx/sites-available/openlearnx-frontend /etc/nginx/sites-enabled/
|
||||
nginx -t
|
||||
systemctl restart nginx
|
||||
```
|
||||
|
||||
#### 7. Setup SSL
|
||||
```bash
|
||||
certbot --nginx -d openlearnx.com
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Environment Configuration
|
||||
|
||||
### Backend (.env) - Production
|
||||
```env
|
||||
FLASK_ENV=production
|
||||
DEBUG=False
|
||||
SECRET_KEY=<secure-random-32-char-key>
|
||||
JWT_SECRET_KEY=<secure-jwt-key>
|
||||
|
||||
# Database
|
||||
MONGODB_URI=mongodb+srv://user:password@cluster.mongodb.net/openlearnx
|
||||
|
||||
# Blockchain
|
||||
WEB3_PROVIDER_URL=https://eth-mainnet.g.alchemy.com/v2/YOUR-API-KEY
|
||||
CONTRACT_ADDRESS=0x<deployed-contract-address>
|
||||
|
||||
# Security
|
||||
CORS_ORIGINS=https://openlearnx.com,https://www.openlearnx.com
|
||||
ADMIN_TOKEN=<secure-admin-token>
|
||||
|
||||
# Optional: Email configuration
|
||||
MAIL_SERVER=smtp.gmail.com
|
||||
MAIL_PORT=587
|
||||
MAIL_USERNAME=your-email@gmail.com
|
||||
MAIL_PASSWORD=your-app-password
|
||||
```
|
||||
|
||||
### Frontend (.env.production.local)
|
||||
```env
|
||||
NEXT_PUBLIC_API_URL=https://api.openlearnx.com
|
||||
NEXT_PUBLIC_CHAIN_ID=1
|
||||
NEXT_PUBLIC_CONTRACT_ADDRESS=0x<contract-address>
|
||||
NEXT_PUBLIC_RPC_URL=https://eth-mainnet.g.alchemy.com/v2/YOUR-API-KEY
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Database Setup
|
||||
|
||||
### MongoDB Atlas (Cloud)
|
||||
|
||||
1. Go to https://mongodb.com/cloud/atlas
|
||||
2. Create account and new cluster
|
||||
3. Add database user with strong password
|
||||
4. Whitelist IP addresses
|
||||
5. Get connection string: `mongodb+srv://user:pass@cluster.mongodb.net/openlearnx`
|
||||
|
||||
### Self-Hosted MongoDB
|
||||
|
||||
```bash
|
||||
# Install MongoDB
|
||||
apt install -y mongodb-org
|
||||
|
||||
# Start service
|
||||
systemctl start mongod
|
||||
systemctl enable mongod
|
||||
|
||||
# Create database and user
|
||||
mongosh
|
||||
use openlearnx
|
||||
db.createUser({
|
||||
user: "openlearnx",
|
||||
pwd: "secure-password",
|
||||
roles: ["readWrite"]
|
||||
})
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Blockchain Setup
|
||||
|
||||
### Using Alchemy (Recommended)
|
||||
1. Go to https://alchemy.com
|
||||
2. Create account and new app
|
||||
3. Select Ethereum mainnet (or testnet)
|
||||
4. Get API key: `https://eth-mainnet.g.alchemy.com/v2/YOUR-API-KEY`
|
||||
|
||||
### Using Infura
|
||||
1. Go to https://infura.io
|
||||
2. Create account and new project
|
||||
3. Select Ethereum mainnet
|
||||
4. Get API key: `https://mainnet.infura.io/v3/YOUR-API-KEY`
|
||||
|
||||
### Self-Hosted Node
|
||||
```bash
|
||||
# Deploy smart contract to mainnet
|
||||
cd backend
|
||||
source venv/bin/activate
|
||||
|
||||
# Update WEB3_PROVIDER_URL to mainnet endpoint
|
||||
python3 scripts/deploy.py # Deploys to mainnet
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Post-Deployment Checks
|
||||
|
||||
### 1. Test Backend
|
||||
```bash
|
||||
curl https://api.openlearnx.com/api/health
|
||||
curl https://api.openlearnx.com/api/dashboard/comprehensive-stats
|
||||
```
|
||||
|
||||
### 2. Test Frontend
|
||||
- Open https://openlearnx.com in browser
|
||||
- Verify page loads
|
||||
- Test wallet connection
|
||||
- Test authentication flow
|
||||
|
||||
### 3. Database
|
||||
```bash
|
||||
mongosh
|
||||
use openlearnx
|
||||
db.stats()
|
||||
```
|
||||
|
||||
### 4. Blockchain
|
||||
```bash
|
||||
curl -X POST https://eth-mainnet.g.alchemy.com/v2/YOUR-API-KEY \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"jsonrpc":"2.0","method":"eth_getCode","params":["0x...","latest"],"id":1}'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Monitoring & Maintenance
|
||||
|
||||
### PM2 Monitoring
|
||||
```bash
|
||||
pm2 monit # Real-time monitoring
|
||||
pm2 logs # View logs
|
||||
pm2 restart all # Restart all processes
|
||||
pm2 stop all # Stop all processes
|
||||
```
|
||||
|
||||
### Nginx Logs
|
||||
```bash
|
||||
tail -f /var/log/nginx/access.log
|
||||
tail -f /var/log/nginx/error.log
|
||||
```
|
||||
|
||||
### Database Backups
|
||||
```bash
|
||||
# Daily backup to S3
|
||||
0 2 * * * mongodump --uri="mongodb+srv://..." --archive=/backups/openlearnx-$(date +\%Y\%m\%d).archive
|
||||
```
|
||||
|
||||
### SSL Certificate Renewal
|
||||
```bash
|
||||
# Auto-renewal with Let's Encrypt
|
||||
certbot renew --dry-run
|
||||
certbot renew # Runs automatically via cron
|
||||
```
|
||||
|
||||
### Update dependencies
|
||||
```bash
|
||||
# Backend
|
||||
cd backend
|
||||
source venv/bin/activate
|
||||
pip install --upgrade pip
|
||||
pip install -r ../requirements.txt
|
||||
|
||||
# Frontend
|
||||
cd frontend
|
||||
pnpm update
|
||||
pnpm build
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Backend not responding
|
||||
```bash
|
||||
pm2 logs openlearnx-backend
|
||||
systemctl status mongod
|
||||
```
|
||||
|
||||
### Frontend blank page
|
||||
```bash
|
||||
pm2 logs openlearnx-frontend
|
||||
# Check NEXT_PUBLIC_API_URL environment variable
|
||||
```
|
||||
|
||||
### Database connection errors
|
||||
```bash
|
||||
# Test MongoDB connection
|
||||
mongosh --uri="your-connection-string"
|
||||
```
|
||||
|
||||
### SSL certificate issues
|
||||
```bash
|
||||
certbot renew --force-renewal
|
||||
systemctl restart nginx
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Security Checklist
|
||||
|
||||
- [ ] Update `SECRET_KEY` and `JWT_SECRET_KEY` with secure values
|
||||
- [ ] Enable HTTPS with SSL certificates
|
||||
- [ ] Configure firewall rules
|
||||
- [ ] Setup rate limiting on API
|
||||
- [ ] Enable CORS only for your domain
|
||||
- [ ] Rotate API keys regularly
|
||||
- [ ] Setup monitoring and alerting
|
||||
- [ ] Implement database backups
|
||||
- [ ] Use environment variables for secrets
|
||||
- [ ] Enable audit logging
|
||||
- [ ] Update dependencies regularly
|
||||
- [ ] Setup DDoS protection (Cloudflare)
|
||||
|
||||
---
|
||||
|
||||
## Support
|
||||
|
||||
For issues or questions:
|
||||
- GitHub Issues: https://github.com/th30d4y/OpenLearnX/issues
|
||||
- Documentation: See DOCUMENTATION.md
|
||||
- Contact: See README.md for contact info
|
||||
|
||||
---
|
||||
|
||||
**Deployment Version:** 2.0.4
|
||||
**Last Updated:** May 12, 2026
|
||||
Executable
+162
@@ -0,0 +1,162 @@
|
||||
#!/bin/bash
|
||||
|
||||
# OpenLearnX Backend - Automated Deployment Script
|
||||
# Usage: ./deploy-backend.sh [production|staging]
|
||||
|
||||
set -e
|
||||
|
||||
ENVIRONMENT=${1:-production}
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
BACKEND_DIR="$SCRIPT_DIR/backend"
|
||||
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
|
||||
LOG_FILE="/tmp/openlearnx_backend_deploy_$TIMESTAMP.log"
|
||||
|
||||
# Colors
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m'
|
||||
|
||||
print_status() { echo -e "${BLUE}[INFO]${NC} $1" | tee -a "$LOG_FILE"; }
|
||||
print_success() { echo -e "${GREEN}[SUCCESS]${NC} $1" | tee -a "$LOG_FILE"; }
|
||||
print_warning() { echo -e "${YELLOW}[WARNING]${NC} $1" | tee -a "$LOG_FILE"; }
|
||||
print_error() { echo -e "${RED}[ERROR]${NC} $1" | tee -a "$LOG_FILE"; }
|
||||
|
||||
print_status "Starting OpenLearnX Backend Deployment"
|
||||
print_status "Environment: $ENVIRONMENT"
|
||||
print_status "Log file: $LOG_FILE"
|
||||
|
||||
# 1. Check prerequisites
|
||||
print_status "Checking prerequisites..."
|
||||
command -v python3 >/dev/null 2>&1 || { print_error "Python 3 not found"; exit 1; }
|
||||
command -v git >/dev/null 2>&1 || { print_error "Git not found"; exit 1; }
|
||||
print_success "Prerequisites verified"
|
||||
|
||||
# 2. Navigate to backend directory
|
||||
cd "$BACKEND_DIR"
|
||||
print_status "Working directory: $(pwd)"
|
||||
|
||||
# 3. Pull latest changes
|
||||
print_status "Pulling latest changes from GitHub..."
|
||||
git pull origin main 2>&1 | tee -a "$LOG_FILE" || { print_error "Git pull failed"; exit 1; }
|
||||
print_success "Latest changes pulled"
|
||||
|
||||
# 4. Check/create virtual environment
|
||||
if [ ! -d "venv" ]; then
|
||||
print_status "Creating Python virtual environment..."
|
||||
python3 -m venv venv || { print_error "Virtual environment creation failed"; exit 1; }
|
||||
print_success "Virtual environment created"
|
||||
else
|
||||
print_status "Virtual environment already exists"
|
||||
fi
|
||||
|
||||
# 5. Activate virtual environment and install dependencies
|
||||
print_status "Installing Python dependencies..."
|
||||
source venv/bin/activate
|
||||
pip install --upgrade pip setuptools wheel 2>&1 | grep -E "Successfully|Requirement" | tail -5 | tee -a "$LOG_FILE"
|
||||
pip install -r ../requirements.txt flask flask-cors python-dotenv pymongo web3 pyjwt flask-jwt-extended requests python-dateutil pycryptodome motor 2>&1 | grep -E "Successfully|Requirement" | tail -10 | tee -a "$LOG_FILE"
|
||||
print_success "Dependencies installed"
|
||||
|
||||
# 6. Check .env file
|
||||
if [ ! -f ".env" ]; then
|
||||
print_warning ".env file not found!"
|
||||
print_status "Creating .env template..."
|
||||
cat > .env << 'EOF'
|
||||
FLASK_ENV=production
|
||||
DEBUG=False
|
||||
SECRET_KEY=change-this-to-a-secure-key
|
||||
JWT_SECRET_KEY=change-this-to-a-secure-jwt-key
|
||||
MONGODB_URI=mongodb+srv://user:password@cluster.mongodb.net/openlearnx
|
||||
WEB3_PROVIDER_URL=https://eth-mainnet.g.alchemy.com/v2/YOUR-API-KEY
|
||||
CONTRACT_ADDRESS=0x...
|
||||
EOF
|
||||
print_warning "Please update .env with your production values"
|
||||
exit 1
|
||||
else
|
||||
print_status ".env file found"
|
||||
fi
|
||||
|
||||
# 7. Check database connection
|
||||
print_status "Testing MongoDB connection..."
|
||||
python3 -c "
|
||||
import os
|
||||
from pymongo import MongoClient
|
||||
from dotenv import load_dotenv
|
||||
load_dotenv()
|
||||
try:
|
||||
client = MongoClient(os.getenv('MONGODB_URI', 'mongodb://localhost:27017/openlearnx'))
|
||||
client.server_info()
|
||||
print('✅ MongoDB connection successful')
|
||||
except Exception as e:
|
||||
print(f'❌ MongoDB connection failed: {e}')
|
||||
exit(1)
|
||||
" 2>&1 | tee -a "$LOG_FILE" || { print_error "Database connection failed"; exit 1; }
|
||||
|
||||
# 8. Build smart contracts
|
||||
print_status "Building smart contracts..."
|
||||
export PATH="/home/w4nn4d13/.foundry/bin:$PATH"
|
||||
forge build 2>&1 | tail -5 | tee -a "$LOG_FILE"
|
||||
print_success "Smart contracts built"
|
||||
|
||||
# 9. Run tests (optional)
|
||||
if [ "$ENVIRONMENT" = "staging" ]; then
|
||||
print_status "Running tests..."
|
||||
python3 -m pytest tests/ -v 2>&1 | tee -a "$LOG_FILE" || print_warning "Some tests failed"
|
||||
fi
|
||||
|
||||
# 10. Create deployment backup
|
||||
print_status "Creating deployment backup..."
|
||||
BACKUP_DIR="/backups/openlearnx_$TIMESTAMP"
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
cp .env "$BACKUP_DIR/.env.backup"
|
||||
cp deployment.json "$BACKUP_DIR/deployment.json.backup" 2>/dev/null || true
|
||||
print_success "Backup created at $BACKUP_DIR"
|
||||
|
||||
# 11. Stop existing process (if using PM2)
|
||||
if command -v pm2 >/dev/null 2>&1; then
|
||||
print_status "Stopping existing PM2 process..."
|
||||
pm2 stop openlearnx-backend 2>/dev/null || print_warning "PM2 process not running"
|
||||
fi
|
||||
|
||||
# 12. Start/restart service
|
||||
if command -v pm2 >/dev/null 2>&1; then
|
||||
print_status "Starting with PM2..."
|
||||
pm2 start main.py --name openlearnx-backend --interpreter python3 2>&1 | tee -a "$LOG_FILE"
|
||||
pm2 save
|
||||
pm2 startup
|
||||
print_success "Backend started with PM2"
|
||||
else
|
||||
print_status "PM2 not found. Start manually:"
|
||||
print_status " cd $BACKEND_DIR && source venv/bin/activate && python3 main.py"
|
||||
fi
|
||||
|
||||
# 13. Health check
|
||||
print_status "Waiting 5 seconds for service to start..."
|
||||
sleep 5
|
||||
|
||||
print_status "Running health check..."
|
||||
HEALTH_RESPONSE=$(curl -s http://localhost:5000/api/health || echo "failed")
|
||||
if [[ "$HEALTH_RESPONSE" == *"health"* ]] || [[ "$HEALTH_RESPONSE" == *"{}"* ]]; then
|
||||
print_success "Health check passed"
|
||||
else
|
||||
print_warning "Health check returned: $HEALTH_RESPONSE"
|
||||
fi
|
||||
|
||||
# 14. Summary
|
||||
print_success "=========================="
|
||||
print_success "Backend Deployment Complete!"
|
||||
print_success "=========================="
|
||||
print_status "Environment: $ENVIRONMENT"
|
||||
print_status "Backend URL: http://localhost:5000"
|
||||
print_status "API URL: http://localhost:5000/api"
|
||||
print_status "Log file: $LOG_FILE"
|
||||
print_status "Backup location: $BACKUP_DIR"
|
||||
|
||||
# 15. Display recent logs (if using PM2)
|
||||
if command -v pm2 >/dev/null 2>&1; then
|
||||
print_status "Recent logs:"
|
||||
pm2 logs openlearnx-backend --lines 10 --nostream 2>/dev/null || true
|
||||
fi
|
||||
|
||||
print_success "Deployment successful!"
|
||||
Executable
+171
@@ -0,0 +1,171 @@
|
||||
#!/bin/bash
|
||||
|
||||
# OpenLearnX Frontend - Automated Deployment Script
|
||||
# Usage: ./deploy-frontend.sh [production|staging]
|
||||
|
||||
set -e
|
||||
|
||||
ENVIRONMENT=${1:-production}
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
FRONTEND_DIR="$SCRIPT_DIR/frontend"
|
||||
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
|
||||
LOG_FILE="/tmp/openlearnx_frontend_deploy_$TIMESTAMP.log"
|
||||
|
||||
# Colors
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m'
|
||||
|
||||
print_status() { echo -e "${BLUE}[INFO]${NC} $1" | tee -a "$LOG_FILE"; }
|
||||
print_success() { echo -e "${GREEN}[SUCCESS]${NC} $1" | tee -a "$LOG_FILE"; }
|
||||
print_warning() { echo -e "${YELLOW}[WARNING]${NC} $1" | tee -a "$LOG_FILE"; }
|
||||
print_error() { echo -e "${RED}[ERROR]${NC} $1" | tee -a "$LOG_FILE"; }
|
||||
|
||||
print_status "Starting OpenLearnX Frontend Deployment"
|
||||
print_status "Environment: $ENVIRONMENT"
|
||||
print_status "Log file: $LOG_FILE"
|
||||
|
||||
# 1. Check prerequisites
|
||||
print_status "Checking prerequisites..."
|
||||
command -v node >/dev/null 2>&1 || { print_error "Node.js not found"; exit 1; }
|
||||
command -v git >/dev/null 2>&1 || { print_error "Git not found"; exit 1; }
|
||||
|
||||
# Check for pnpm or npm
|
||||
if command -v pnpm >/dev/null 2>&1; then
|
||||
PACKAGE_MANAGER="pnpm"
|
||||
elif command -v npm >/dev/null 2>&1; then
|
||||
PACKAGE_MANAGER="npm"
|
||||
else
|
||||
print_error "Neither pnpm nor npm found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
print_success "Prerequisites verified (using $PACKAGE_MANAGER)"
|
||||
|
||||
# 2. Navigate to frontend directory
|
||||
cd "$FRONTEND_DIR"
|
||||
print_status "Working directory: $(pwd)"
|
||||
|
||||
# 3. Pull latest changes
|
||||
print_status "Pulling latest changes from GitHub..."
|
||||
git pull origin main 2>&1 | tee -a "$LOG_FILE" || { print_error "Git pull failed"; exit 1; }
|
||||
print_success "Latest changes pulled"
|
||||
|
||||
# 4. Check .env.local file
|
||||
if [ ! -f ".env.local" ]; then
|
||||
print_warning ".env.local file not found!"
|
||||
print_status "Creating .env.local template..."
|
||||
cat > .env.local << 'EOF'
|
||||
NEXT_PUBLIC_API_URL=https://api.openlearnx.com
|
||||
NEXT_PUBLIC_CHAIN_ID=1
|
||||
NEXT_PUBLIC_CONTRACT_ADDRESS=0x...
|
||||
NEXT_PUBLIC_RPC_URL=https://eth-mainnet.g.alchemy.com/v2/YOUR-API-KEY
|
||||
EOF
|
||||
print_warning "Please update .env.local with your production values"
|
||||
exit 1
|
||||
else
|
||||
print_status ".env.local file found"
|
||||
fi
|
||||
|
||||
# 5. Clean previous build
|
||||
print_status "Cleaning previous build..."
|
||||
rm -rf .next node_modules pnpm-lock.yaml npm-lock.json 2>/dev/null || true
|
||||
print_success "Previous build cleaned"
|
||||
|
||||
# 6. Install dependencies
|
||||
print_status "Installing dependencies with $PACKAGE_MANAGER..."
|
||||
if [ "$PACKAGE_MANAGER" = "pnpm" ]; then
|
||||
pnpm install --no-frozen-lockfile 2>&1 | tail -10 | tee -a "$LOG_FILE"
|
||||
else
|
||||
npm ci 2>&1 | tail -10 | tee -a "$LOG_FILE"
|
||||
fi
|
||||
print_success "Dependencies installed"
|
||||
|
||||
# 7. Build application
|
||||
print_status "Building Next.js application..."
|
||||
if [ "$PACKAGE_MANAGER" = "pnpm" ]; then
|
||||
pnpm build 2>&1 | tee -a "$LOG_FILE"
|
||||
else
|
||||
npm run build 2>&1 | tee -a "$LOG_FILE"
|
||||
fi
|
||||
print_success "Build completed"
|
||||
|
||||
# 8. Create deployment backup
|
||||
print_status "Creating deployment backup..."
|
||||
BACKUP_DIR="/backups/openlearnx_frontend_$TIMESTAMP"
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
cp .env.local "$BACKUP_DIR/.env.local.backup"
|
||||
cp -r .next "$BACKUP_DIR/.next.backup" 2>/dev/null || true
|
||||
print_success "Backup created at $BACKUP_DIR"
|
||||
|
||||
# 9. Stop existing process (if using PM2)
|
||||
if command -v pm2 >/dev/null 2>&1; then
|
||||
print_status "Stopping existing PM2 process..."
|
||||
pm2 stop openlearnx-frontend 2>/dev/null || print_warning "PM2 process not running"
|
||||
fi
|
||||
|
||||
# 10. Start/restart service
|
||||
if command -v pm2 >/dev/null 2>&1; then
|
||||
print_status "Starting with PM2..."
|
||||
if [ "$PACKAGE_MANAGER" = "pnpm" ]; then
|
||||
pm2 start "pnpm start" --name openlearnx-frontend 2>&1 | tee -a "$LOG_FILE"
|
||||
else
|
||||
pm2 start "npm start" --name openlearnx-frontend 2>&1 | tee -a "$LOG_FILE"
|
||||
fi
|
||||
pm2 save
|
||||
pm2 startup
|
||||
print_success "Frontend started with PM2"
|
||||
else
|
||||
print_status "PM2 not found. Start manually:"
|
||||
if [ "$PACKAGE_MANAGER" = "pnpm" ]; then
|
||||
print_status " cd $FRONTEND_DIR && pnpm start"
|
||||
else
|
||||
print_status " cd $FRONTEND_DIR && npm start"
|
||||
fi
|
||||
fi
|
||||
|
||||
# 11. Health check
|
||||
print_status "Waiting 10 seconds for service to start..."
|
||||
sleep 10
|
||||
|
||||
print_status "Running health check..."
|
||||
HEALTH_RESPONSE=$(curl -s http://localhost:3000 2>&1 | head -c 200)
|
||||
if [[ "$HEALTH_RESPONSE" == *"<!DOCTYPE"* ]] || [[ "$HEALTH_RESPONSE" == *"<html"* ]]; then
|
||||
print_success "Health check passed"
|
||||
else
|
||||
print_warning "Health check returned limited response"
|
||||
fi
|
||||
|
||||
# 12. Generate sitemap and robots.txt (optional)
|
||||
if [ -f "public/robots.txt" ]; then
|
||||
print_status "Robots.txt already exists"
|
||||
else
|
||||
print_status "Creating robots.txt..."
|
||||
mkdir -p public
|
||||
cat > public/robots.txt << 'EOF'
|
||||
User-agent: *
|
||||
Allow: /
|
||||
Sitemap: https://openlearnx.com/sitemap.xml
|
||||
EOF
|
||||
print_success "Robots.txt created"
|
||||
fi
|
||||
|
||||
# 13. Summary
|
||||
print_success "=========================="
|
||||
print_success "Frontend Deployment Complete!"
|
||||
print_success "=========================="
|
||||
print_status "Environment: $ENVIRONMENT"
|
||||
print_status "Frontend URL: http://localhost:3000"
|
||||
print_status "Build directory: .next"
|
||||
print_status "Log file: $LOG_FILE"
|
||||
print_status "Backup location: $BACKUP_DIR"
|
||||
|
||||
# 14. Display recent logs (if using PM2)
|
||||
if command -v pm2 >/dev/null 2>&1; then
|
||||
print_status "Recent logs:"
|
||||
pm2 logs openlearnx-frontend --lines 10 --nostream 2>/dev/null || true
|
||||
fi
|
||||
|
||||
print_success "Deployment successful!"
|
||||
@@ -0,0 +1,196 @@
|
||||
#!/bin/bash
|
||||
|
||||
# OpenLearnX - Master Deployment Script
|
||||
# Deploys both backend and frontend
|
||||
# Usage: ./deploy.sh [production|staging|local]
|
||||
|
||||
ENVIRONMENT=${1:-production}
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
|
||||
LOG_FILE="/tmp/openlearnx_deploy_$TIMESTAMP.log"
|
||||
|
||||
# Colors
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m'
|
||||
|
||||
print_status() { echo -e "${BLUE}[INFO]${NC} $1" | tee -a "$LOG_FILE"; }
|
||||
print_success() { echo -e "${GREEN}[SUCCESS]${NC} $1" | tee -a "$LOG_FILE"; }
|
||||
print_warning() { echo -e "${YELLOW}[WARNING]${NC} $1" | tee -a "$LOG_FILE"; }
|
||||
print_error() { echo -e "${RED}[ERROR]${NC} $1" | tee -a "$LOG_FILE"; }
|
||||
|
||||
banner() {
|
||||
cat << "EOF"
|
||||
|
||||
╔═══════════════════════════════════════════╗
|
||||
║ 🚀 OpenLearnX Deployment System 🚀 ║
|
||||
╚═══════════════════════════════════════════╝
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
banner
|
||||
|
||||
print_status "═══════════════════════════════════════════════"
|
||||
print_status " OpenLearnX Master Deployment"
|
||||
print_status " Environment: $ENVIRONMENT"
|
||||
print_status " Timestamp: $TIMESTAMP"
|
||||
print_status "═══════════════════════════════════════════════"
|
||||
print_status "Log file: $LOG_FILE"
|
||||
echo ""
|
||||
|
||||
# Validate environment
|
||||
case "$ENVIRONMENT" in
|
||||
production|staging|local)
|
||||
print_success "Environment: $ENVIRONMENT (valid)"
|
||||
;;
|
||||
*)
|
||||
print_error "Invalid environment: $ENVIRONMENT"
|
||||
echo "Usage: $0 [production|staging|local]"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# Show deployment plan
|
||||
echo ""
|
||||
print_status "Deployment Plan:"
|
||||
print_status " 1. ✓ Pull latest changes from GitHub"
|
||||
print_status " 2. ✓ Deploy Backend (Flask/Python)"
|
||||
print_status " 3. ✓ Deploy Frontend (Next.js/React)"
|
||||
print_status " 4. ✓ Run health checks"
|
||||
print_status " 5. ✓ Display deployment summary"
|
||||
echo ""
|
||||
|
||||
# Confirm before proceeding
|
||||
if [ "$ENVIRONMENT" = "production" ]; then
|
||||
print_warning "⚠️ PRODUCTION DEPLOYMENT - Please review carefully!"
|
||||
read -p "Type 'yes' to proceed with production deployment: " confirm
|
||||
if [ "$confirm" != "yes" ]; then
|
||||
print_error "Deployment cancelled"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Change to script directory
|
||||
cd "$SCRIPT_DIR"
|
||||
|
||||
# 1. Pull latest changes
|
||||
print_status "Step 1/5: Pulling latest changes..."
|
||||
if git pull origin main 2>&1 | tee -a "$LOG_FILE"; then
|
||||
print_success "Latest changes pulled"
|
||||
else
|
||||
print_warning "Git pull encountered issues, continuing..."
|
||||
fi
|
||||
|
||||
# 2. Deploy Backend
|
||||
print_status ""
|
||||
print_status "Step 2/5: Deploying Backend..."
|
||||
if [ -f "deploy-backend.sh" ]; then
|
||||
if bash deploy-backend.sh "$ENVIRONMENT" 2>&1 | tee -a "$LOG_FILE"; then
|
||||
print_success "Backend deployment successful"
|
||||
else
|
||||
print_error "Backend deployment failed"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
print_error "deploy-backend.sh not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 3. Deploy Frontend
|
||||
print_status ""
|
||||
print_status "Step 3/5: Deploying Frontend..."
|
||||
if [ -f "deploy-frontend.sh" ]; then
|
||||
if bash deploy-frontend.sh "$ENVIRONMENT" 2>&1 | tee -a "$LOG_FILE"; then
|
||||
print_success "Frontend deployment successful"
|
||||
else
|
||||
print_error "Frontend deployment failed"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
print_error "deploy-frontend.sh not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 4. Health checks
|
||||
print_status ""
|
||||
print_status "Step 4/5: Running health checks..."
|
||||
|
||||
# Check Backend
|
||||
print_status "Checking Backend API (http://localhost:5000)..."
|
||||
if curl -s http://localhost:5000/api/health >/dev/null 2>&1 || curl -s http://localhost:5000 >/dev/null 2>&1; then
|
||||
print_success "Backend API is responding"
|
||||
else
|
||||
print_warning "Backend API not responding yet (may still be starting)"
|
||||
fi
|
||||
|
||||
# Check Frontend
|
||||
print_status "Checking Frontend (http://localhost:3000)..."
|
||||
if curl -s http://localhost:3000 >/dev/null 2>&1; then
|
||||
print_success "Frontend is responding"
|
||||
else
|
||||
print_warning "Frontend not responding yet (may still be starting)"
|
||||
fi
|
||||
|
||||
# 5. Summary
|
||||
print_status ""
|
||||
print_status "Step 5/5: Generating deployment summary..."
|
||||
echo ""
|
||||
print_success "═══════════════════════════════════════════════"
|
||||
print_success " ✅ DEPLOYMENT SUCCESSFUL ✅"
|
||||
print_success "═══════════════════════════════════════════════"
|
||||
echo ""
|
||||
|
||||
cat << EOF | tee -a "$LOG_FILE"
|
||||
📊 Deployment Summary
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
|
||||
🌐 Frontend
|
||||
URL: http://localhost:3000
|
||||
Build: .next (optimized production build)
|
||||
Status: ✅ Running
|
||||
|
||||
🔌 Backend API
|
||||
URL: http://localhost:5000/api
|
||||
Framework: Flask (Python 3)
|
||||
Status: ✅ Running
|
||||
|
||||
📦 Database
|
||||
Type: MongoDB
|
||||
Port: 27017
|
||||
Status: ✅ Ready
|
||||
|
||||
⛓️ Blockchain
|
||||
Network: Ethereum Mainnet
|
||||
RPC: Configured in .env
|
||||
Status: ✅ Ready
|
||||
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
|
||||
📋 Environment: $ENVIRONMENT
|
||||
🕐 Deployment Time: $TIMESTAMP
|
||||
📁 Log File: $LOG_FILE
|
||||
|
||||
🎯 Next Steps:
|
||||
1. Verify both services are accessible
|
||||
2. Test core functionality
|
||||
3. Monitor logs for errors
|
||||
4. Configure domain/DNS if needed
|
||||
5. Enable SSL/HTTPS if on production
|
||||
|
||||
EOF
|
||||
|
||||
echo ""
|
||||
print_status "View detailed logs with:"
|
||||
print_status " tail -f $LOG_FILE"
|
||||
echo ""
|
||||
|
||||
if command -v pm2 >/dev/null 2>&1; then
|
||||
print_status "PM2 Status:"
|
||||
pm2 status
|
||||
echo ""
|
||||
fi
|
||||
|
||||
print_success "Deployment completed! 🎉"
|
||||
Reference in New Issue
Block a user