Add production deployment migration guide and configuration files
Added comprehensive migration documentation and configuration files for restructuring the application to split frontend/backend: New Documentation: - MIGRATION_GUIDE.md: Complete step-by-step migration instructions - MIGRATION_SUMMARY.md: Quick reference guide for deployment - MIGRATION_CHECKLIST.md: Printable checklist for migration day - DEPLOYMENT_RESTRUCTURE.md: Architecture overview and benefits New Configuration Files: - run_api_server.py: Production WSGI server wrapper using Waitress - ai_qc.service: Systemd service configuration for backend - apache_config.conf: Apache virtual host configuration template Updated Files: - requirements.txt: Added waitress>=2.1.2 for production WSGI server - README.md: Added deployment documentation section Migration Overview: - Split current monolithic structure into separate frontend/backend - Move backend to /opt/ai_qc/ (following server standards) - Keep frontend in /var/www/html/ai_qc/ (single index.html) - Use Apache reverse proxy to connect frontend to backend API - Implement systemd service for reliable backend process management Benefits: - Improved security (backend code not in web root) - Better separation of concerns - Follows industry best practices - Matches existing server app patterns (/opt/veo3, /opt/voice2text) - Easier independent updates of frontend/backend 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
824c7639ec
commit
b7b7f57b35
9 changed files with 1734 additions and 1 deletions
444
DEPLOYMENT_RESTRUCTURE.md
Normal file
444
DEPLOYMENT_RESTRUCTURE.md
Normal file
|
|
@ -0,0 +1,444 @@
|
|||
# Deployment Restructure Guide
|
||||
|
||||
## Overview
|
||||
This guide explains how to restructure the Visual AI QC application for production deployment by splitting frontend and backend components.
|
||||
|
||||
## Current vs. Proposed Structure
|
||||
|
||||
### Current Structure (All in one location)
|
||||
```
|
||||
/current/location/
|
||||
├── api_server.py # Backend
|
||||
├── web_ui.html # Frontend
|
||||
├── visual_qc_apps/ # Backend
|
||||
├── profiles/ # Backend
|
||||
├── brand_guidelines/ # Backend
|
||||
├── uploads/ # Backend data
|
||||
├── output/ # Backend data
|
||||
└── ... (all other files)
|
||||
```
|
||||
|
||||
### Proposed Structure (Split deployment)
|
||||
|
||||
#### **Frontend (Web Root: `/var/www/html/ai_qc/`)**
|
||||
```
|
||||
/var/www/html/ai_qc/
|
||||
└── index.html # Renamed from web_ui.html
|
||||
```
|
||||
|
||||
#### **Backend (Application Directory: `/opt/ai_qc/`)**
|
||||
```
|
||||
/opt/ai_qc/
|
||||
├── api_server.py
|
||||
├── llm_config.py
|
||||
├── profile_config.py
|
||||
├── jwt_validator.py
|
||||
├── auth_middleware.py
|
||||
├── visual_qc_apps/
|
||||
│ ├── utils.py
|
||||
│ ├── flask_app_template.py
|
||||
│ └── (all QC check modules)
|
||||
├── profiles/
|
||||
│ └── (all JSON profiles)
|
||||
├── brand_guidelines/
|
||||
│ ├── guidelines_db.json
|
||||
│ └── (reference assets)
|
||||
├── config/
|
||||
│ ├── production.env
|
||||
│ └── development.env
|
||||
├── uploads/
|
||||
├── uploads-dev/
|
||||
├── output/
|
||||
├── output-dev/
|
||||
├── scripts/
|
||||
│ ├── run-local.sh
|
||||
│ ├── deploy-to-prod.sh
|
||||
│ └── test-system.sh
|
||||
├── requirements.txt
|
||||
├── CLAUDE.md
|
||||
├── DEV_PROD_SETUP.md
|
||||
└── README.md
|
||||
```
|
||||
|
||||
## Required Code Changes
|
||||
|
||||
### 1. Frontend Changes (`web_ui.html`)
|
||||
|
||||
The frontend HTML needs to know where the backend API is located. Currently, it likely uses relative URLs like `/api/start_analysis`.
|
||||
|
||||
**Update API Base URL:**
|
||||
```javascript
|
||||
// Add at the top of the script section
|
||||
const API_BASE_URL = '/api'; // If using reverse proxy
|
||||
// OR
|
||||
const API_BASE_URL = 'http://your-domain.com/api'; // If using different port
|
||||
|
||||
// Update all fetch calls to use API_BASE_URL
|
||||
fetch(`${API_BASE_URL}/start_analysis`, {
|
||||
method: 'POST',
|
||||
// ... rest of the fetch call
|
||||
});
|
||||
```
|
||||
|
||||
### 2. Backend Changes (`api_server.py`)
|
||||
|
||||
**Update Static File Serving:**
|
||||
```python
|
||||
# Current: Flask serves web_ui.html from same directory
|
||||
# After split: Backend only serves API endpoints, no HTML
|
||||
|
||||
# Remove or comment out any static file serving for web_ui.html:
|
||||
# @app.route('/')
|
||||
# def index():
|
||||
# return send_file('web_ui.html')
|
||||
```
|
||||
|
||||
**Update CORS Settings (if needed):**
|
||||
```python
|
||||
# If frontend and backend on different domains/ports
|
||||
from flask_cors import CORS
|
||||
|
||||
app = Flask(__name__)
|
||||
CORS(app,
|
||||
origins=['https://your-frontend-domain.com'],
|
||||
supports_credentials=True)
|
||||
```
|
||||
|
||||
### 3. Path Configuration Updates
|
||||
|
||||
**Update file paths in `api_server.py`:**
|
||||
```python
|
||||
# Ensure all paths are absolute or relative to /opt/ai_qc/
|
||||
UPLOAD_FOLDER = '/opt/ai_qc/uploads'
|
||||
OUTPUT_FOLDER = '/opt/ai_qc/output'
|
||||
UPLOAD_FOLDER_DEV = '/opt/ai_qc/uploads-dev'
|
||||
OUTPUT_FOLDER_DEV = '/opt/ai_qc/output-dev'
|
||||
BRAND_GUIDELINES_FOLDER = '/opt/ai_qc/brand_guidelines'
|
||||
```
|
||||
|
||||
## Web Server Configuration Options
|
||||
|
||||
### Option A: Nginx Reverse Proxy (Recommended)
|
||||
|
||||
```nginx
|
||||
# /etc/nginx/sites-available/ai_qc
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name your-domain.com;
|
||||
|
||||
# Frontend - Serve static HTML from web root
|
||||
location / {
|
||||
root /var/www/html/ai_qc;
|
||||
index index.html;
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
|
||||
# Backend - Reverse proxy to Flask application
|
||||
location /api {
|
||||
proxy_pass http://127.0.0.1:7183;
|
||||
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;
|
||||
|
||||
# Increase timeout for long-running analysis
|
||||
proxy_read_timeout 300s;
|
||||
proxy_connect_timeout 300s;
|
||||
}
|
||||
|
||||
# Serve uploaded files and outputs
|
||||
location /uploads {
|
||||
alias /opt/ai_qc/uploads;
|
||||
}
|
||||
|
||||
location /output {
|
||||
alias /opt/ai_qc/output;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Option B: Apache Reverse Proxy
|
||||
|
||||
```apache
|
||||
# /etc/apache2/sites-available/ai_qc.conf
|
||||
|
||||
<VirtualHost *:80>
|
||||
ServerName your-domain.com
|
||||
|
||||
# Frontend - Serve static HTML
|
||||
DocumentRoot /var/www/html/ai_qc
|
||||
|
||||
<Directory /var/www/html/ai_qc>
|
||||
Options -Indexes +FollowSymLinks
|
||||
AllowOverride All
|
||||
Require all granted
|
||||
</Directory>
|
||||
|
||||
# Backend - Reverse proxy to Flask
|
||||
ProxyPreserveHost On
|
||||
ProxyPass /api http://127.0.0.1:7183/api
|
||||
ProxyPassReverse /api http://127.0.0.1:7183/api
|
||||
|
||||
# Static file aliases
|
||||
Alias /uploads /opt/ai_qc/uploads
|
||||
Alias /output /opt/ai_qc/output
|
||||
|
||||
<Directory /opt/ai_qc/uploads>
|
||||
Require all granted
|
||||
</Directory>
|
||||
|
||||
<Directory /opt/ai_qc/output>
|
||||
Require all granted
|
||||
</Directory>
|
||||
|
||||
# Enable required modules
|
||||
# a2enmod proxy proxy_http
|
||||
</VirtualHost>
|
||||
```
|
||||
|
||||
## Backend Service Configuration
|
||||
|
||||
### Systemd Service (Production Deployment)
|
||||
|
||||
Create `/etc/systemd/system/ai_qc.service`:
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=Visual AI QC Flask Application
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=www-data
|
||||
Group=www-data
|
||||
WorkingDirectory=/opt/ai_qc
|
||||
Environment="ENVIRONMENT=production"
|
||||
Environment="PATH=/opt/ai_qc/venv/bin"
|
||||
ExecStart=/opt/ai_qc/venv/bin/gunicorn \
|
||||
--bind 127.0.0.1:7183 \
|
||||
--workers 4 \
|
||||
--timeout 300 \
|
||||
--access-logfile /var/log/ai_qc/access.log \
|
||||
--error-logfile /var/log/ai_qc/error.log \
|
||||
api_server:app
|
||||
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
**Enable and start the service:**
|
||||
```bash
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable ai_qc
|
||||
sudo systemctl start ai_qc
|
||||
sudo systemctl status ai_qc
|
||||
```
|
||||
|
||||
## Migration Steps
|
||||
|
||||
### Step 1: Backup Current Deployment
|
||||
```bash
|
||||
# On web server
|
||||
cd /path/to/current/ai_qc
|
||||
tar -czf ai_qc_backup_$(date +%Y%m%d).tar.gz .
|
||||
```
|
||||
|
||||
### Step 2: Prepare Backend Location
|
||||
```bash
|
||||
# Create backend directory
|
||||
sudo mkdir -p /opt/ai_qc
|
||||
sudo chown $USER:$USER /opt/ai_qc # Or appropriate user
|
||||
|
||||
# Copy all files except web_ui.html
|
||||
rsync -av --exclude='web_ui.html' \
|
||||
--exclude='*.pyc' \
|
||||
--exclude='__pycache__' \
|
||||
/path/to/current/ai_qc/ /opt/ai_qc/
|
||||
|
||||
# Set up virtual environment
|
||||
cd /opt/ai_qc
|
||||
python3 -m venv venv
|
||||
source venv/bin/activate
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
### Step 3: Prepare Frontend Location
|
||||
```bash
|
||||
# Create frontend directory
|
||||
sudo mkdir -p /var/www/html/ai_qc
|
||||
sudo chown $USER:$USER /var/www/html/ai_qc
|
||||
|
||||
# Copy and rename web_ui.html
|
||||
cp /path/to/current/ai_qc/web_ui.html /var/www/html/ai_qc/index.html
|
||||
```
|
||||
|
||||
### Step 4: Update Configuration Files
|
||||
```bash
|
||||
# Update production environment config
|
||||
nano /opt/ai_qc/config/production.env
|
||||
|
||||
# Ensure paths are correct in api_server.py
|
||||
nano /opt/ai_qc/api_server.py
|
||||
|
||||
# Update API URLs in frontend
|
||||
nano /var/www/html/ai_qc/index.html
|
||||
```
|
||||
|
||||
### Step 5: Configure Web Server
|
||||
```bash
|
||||
# For Nginx
|
||||
sudo nano /etc/nginx/sites-available/ai_qc
|
||||
sudo ln -s /etc/nginx/sites-available/ai_qc /etc/nginx/sites-enabled/
|
||||
sudo nginx -t
|
||||
sudo systemctl reload nginx
|
||||
|
||||
# For Apache
|
||||
sudo nano /etc/apache2/sites-available/ai_qc.conf
|
||||
sudo a2ensite ai_qc
|
||||
sudo a2enmod proxy proxy_http
|
||||
sudo apache2ctl configtest
|
||||
sudo systemctl reload apache2
|
||||
```
|
||||
|
||||
### Step 6: Set Up Backend Service
|
||||
```bash
|
||||
# Create service file
|
||||
sudo nano /etc/systemd/system/ai_qc.service
|
||||
|
||||
# Create log directory
|
||||
sudo mkdir -p /var/log/ai_qc
|
||||
sudo chown www-data:www-data /var/log/ai_qc
|
||||
|
||||
# Enable and start service
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable ai_qc
|
||||
sudo systemctl start ai_qc
|
||||
sudo systemctl status ai_qc
|
||||
```
|
||||
|
||||
### Step 7: Test the Deployment
|
||||
```bash
|
||||
# Check backend is running
|
||||
curl http://localhost:7183/api/profiles
|
||||
|
||||
# Check frontend is accessible
|
||||
curl http://localhost/
|
||||
|
||||
# Check full flow through web server
|
||||
curl http://your-domain.com/api/profiles
|
||||
```
|
||||
|
||||
### Step 8: Verify Authentication
|
||||
```bash
|
||||
# Test MSAL authentication endpoints
|
||||
curl http://your-domain.com/api/auth/status
|
||||
|
||||
# Check JWT validation is working
|
||||
# (This requires authenticated requests from the browser)
|
||||
```
|
||||
|
||||
## Security Considerations
|
||||
|
||||
### File Permissions
|
||||
```bash
|
||||
# Backend files
|
||||
sudo chown -R www-data:www-data /opt/ai_qc
|
||||
sudo chmod -R 750 /opt/ai_qc
|
||||
sudo chmod 640 /opt/ai_qc/config/*.env
|
||||
|
||||
# Upload and output directories need write access
|
||||
sudo chmod 770 /opt/ai_qc/uploads /opt/ai_qc/output
|
||||
```
|
||||
|
||||
### Firewall Rules
|
||||
```bash
|
||||
# Only allow web server ports externally
|
||||
sudo ufw allow 80/tcp
|
||||
sudo ufw allow 443/tcp
|
||||
|
||||
# Flask port (7183) should NOT be exposed externally
|
||||
# It should only be accessible via reverse proxy
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
```bash
|
||||
# Ensure sensitive configs are not world-readable
|
||||
chmod 600 /opt/ai_qc/config/production.env
|
||||
|
||||
# Consider using environment variables instead of .env files
|
||||
# Add to systemd service file:
|
||||
# Environment="OPENAI_API_KEY=your-key"
|
||||
# Environment="GOOGLE_API_KEY=your-key"
|
||||
```
|
||||
|
||||
## Monitoring and Logs
|
||||
|
||||
### Log Locations
|
||||
- **Backend Application**: `/var/log/ai_qc/error.log` and `/var/log/ai_qc/access.log`
|
||||
- **Web Server (Nginx)**: `/var/log/nginx/access.log` and `/var/log/nginx/error.log`
|
||||
- **Web Server (Apache)**: `/var/log/apache2/access.log` and `/var/log/apache2/error.log`
|
||||
- **Systemd Service**: `journalctl -u ai_qc -f`
|
||||
|
||||
### Health Check Script
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# /opt/ai_qc/scripts/health_check.sh
|
||||
|
||||
# Check if service is running
|
||||
if ! systemctl is-active --quiet ai_qc; then
|
||||
echo "ERROR: AI QC service is not running"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if backend is responding
|
||||
if ! curl -sf http://localhost:7183/api/profiles > /dev/null; then
|
||||
echo "ERROR: Backend API is not responding"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "OK: AI QC application is healthy"
|
||||
exit 0
|
||||
```
|
||||
|
||||
## Rollback Plan
|
||||
|
||||
If issues occur during migration:
|
||||
|
||||
```bash
|
||||
# Stop new service
|
||||
sudo systemctl stop ai_qc
|
||||
|
||||
# Restore backup to original location
|
||||
cd /path/to/original/location
|
||||
tar -xzf ai_qc_backup_YYYYMMDD.tar.gz
|
||||
|
||||
# Restart original deployment method
|
||||
# (python api_server.py or previous service)
|
||||
|
||||
# Disable new web server config
|
||||
sudo a2dissite ai_qc # Apache
|
||||
sudo rm /etc/nginx/sites-enabled/ai_qc # Nginx
|
||||
sudo systemctl reload apache2 # or nginx
|
||||
```
|
||||
|
||||
## Benefits of This Structure
|
||||
|
||||
1. **Security**: Backend code not accessible from web root
|
||||
2. **Separation of Concerns**: Frontend and backend can be updated independently
|
||||
3. **Scalability**: Backend can be moved to separate server if needed
|
||||
4. **Standard Practice**: Follows industry best practices for web application deployment
|
||||
5. **Better Performance**: Web server serves static files directly, Flask only handles API requests
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. Identify current web server (Apache/Nginx)
|
||||
2. Determine current Flask running method
|
||||
3. Test restructure in development environment first
|
||||
4. Plan maintenance window for production migration
|
||||
5. Prepare rollback plan
|
||||
6. Execute migration during low-usage period
|
||||
7. Monitor logs and performance after migration
|
||||
428
MIGRATION_CHECKLIST.md
Normal file
428
MIGRATION_CHECKLIST.md
Normal file
|
|
@ -0,0 +1,428 @@
|
|||
# Migration Day Checklist ✅
|
||||
|
||||
Use this checklist during your migration to track progress and ensure nothing is missed.
|
||||
|
||||
---
|
||||
|
||||
## Pre-Migration (30 minutes before)
|
||||
|
||||
- [ ] **Read Complete Documentation**
|
||||
- [ ] Read `MIGRATION_GUIDE.md` completely
|
||||
- [ ] Review `MIGRATION_SUMMARY.md` for quick reference
|
||||
- [ ] Understand rollback procedure
|
||||
|
||||
- [ ] **Prepare Environment**
|
||||
- [ ] SSH access to server confirmed
|
||||
- [ ] Sudo privileges verified
|
||||
- [ ] Backup directory prepared (`~/backups/`)
|
||||
- [ ] Maintenance window scheduled and communicated
|
||||
|
||||
- [ ] **Verify Current State**
|
||||
```bash
|
||||
# Run these commands to document current state:
|
||||
sudo systemctl status ai_qc | tee ~/pre-migration-service-status.txt
|
||||
ps aux | grep run_api_server.py | tee ~/pre-migration-process.txt
|
||||
ls -la /var/www/html/ai_qc/ | tee ~/pre-migration-files.txt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Migration Steps (20-30 minutes)
|
||||
|
||||
### Step 1: Backup ✅
|
||||
- [ ] Create backup of current deployment
|
||||
```bash
|
||||
cd /var/www/html/ai_qc
|
||||
sudo tar -czf ~/ai_qc_backup_$(date +%Y%m%d_%H%M%S).tar.gz .
|
||||
ls -lh ~/ai_qc_backup_*.tar.gz # Verify backup created
|
||||
```
|
||||
- [ ] Backup created successfully
|
||||
- [ ] Backup size looks reasonable (should be several MB)
|
||||
- [ ] Backup location noted: `_______________`
|
||||
|
||||
### Step 2: Stop Current Service ✅
|
||||
- [ ] Find service name
|
||||
```bash
|
||||
sudo systemctl list-units --type=service | grep ai_qc
|
||||
```
|
||||
- [ ] Service name identified: `_______________`
|
||||
- [ ] Stop the service
|
||||
```bash
|
||||
sudo systemctl stop [SERVICE_NAME]
|
||||
```
|
||||
- [ ] Verify service stopped
|
||||
```bash
|
||||
sudo systemctl status ai_qc
|
||||
ps aux | grep run_api_server.py # Should return nothing
|
||||
```
|
||||
- [ ] Service fully stopped (no processes running)
|
||||
|
||||
### Step 3: Create Backend Directory ✅
|
||||
- [ ] Create `/opt/ai_qc/` directory
|
||||
```bash
|
||||
sudo mkdir -p /opt/ai_qc
|
||||
```
|
||||
- [ ] Copy files to backend location
|
||||
```bash
|
||||
cd /var/www/html/ai_qc
|
||||
sudo rsync -av \
|
||||
--exclude='web_ui.html' \
|
||||
--exclude='*.pyc' \
|
||||
--exclude='__pycache__' \
|
||||
--exclude='.git' \
|
||||
. /opt/ai_qc/
|
||||
```
|
||||
- [ ] Verify files copied
|
||||
```bash
|
||||
ls -la /opt/ai_qc/ # Should see all Python files
|
||||
```
|
||||
- [ ] Set ownership
|
||||
```bash
|
||||
sudo chown -R www-data:www-data /opt/ai_qc
|
||||
```
|
||||
- [ ] Set permissions
|
||||
```bash
|
||||
sudo chmod -R 750 /opt/ai_qc
|
||||
sudo chmod 770 /opt/ai_qc/uploads /opt/ai_qc/output
|
||||
sudo chmod 770 /opt/ai_qc/uploads-dev /opt/ai_qc/output-dev
|
||||
sudo chmod 640 /opt/ai_qc/config/*.env
|
||||
```
|
||||
|
||||
### Step 4: Prepare Frontend ✅
|
||||
- [ ] Create new frontend directory
|
||||
```bash
|
||||
sudo mkdir -p /var/www/html/ai_qc_new
|
||||
```
|
||||
- [ ] Copy and rename web_ui.html
|
||||
```bash
|
||||
sudo cp /var/www/html/ai_qc/web_ui.html /var/www/html/ai_qc_new/index.html
|
||||
```
|
||||
- [ ] Set ownership
|
||||
```bash
|
||||
sudo chown -R www-data:www-data /var/www/html/ai_qc_new
|
||||
```
|
||||
- [ ] Verify frontend file exists
|
||||
```bash
|
||||
ls -la /var/www/html/ai_qc_new/index.html
|
||||
```
|
||||
|
||||
### Step 5: Update Backend Paths ✅
|
||||
- [ ] Edit production.env
|
||||
```bash
|
||||
sudo nano /opt/ai_qc/config/production.env
|
||||
```
|
||||
- [ ] Verify paths are absolute (start with `/opt/ai_qc/`)
|
||||
- [ ] UPLOAD_FOLDER=/opt/ai_qc/uploads
|
||||
- [ ] OUTPUT_FOLDER=/opt/ai_qc/output
|
||||
- [ ] UPLOAD_FOLDER_DEV=/opt/ai_qc/uploads-dev
|
||||
- [ ] OUTPUT_FOLDER_DEV=/opt/ai_qc/output-dev
|
||||
- [ ] BRAND_GUIDELINES_FOLDER=/opt/ai_qc/brand_guidelines
|
||||
- [ ] Save and exit
|
||||
|
||||
### Step 6: Update Systemd Service ✅
|
||||
- [ ] Backup existing service file
|
||||
```bash
|
||||
sudo cp /etc/systemd/system/ai_qc.service /etc/systemd/system/ai_qc.service.backup
|
||||
```
|
||||
- [ ] Edit service file
|
||||
```bash
|
||||
sudo nano /etc/systemd/system/ai_qc.service
|
||||
```
|
||||
- [ ] Verify key settings:
|
||||
- [ ] WorkingDirectory=/opt/ai_qc
|
||||
- [ ] ExecStart=/opt/ai_qc/venv/bin/python /opt/ai_qc/run_api_server.py ...
|
||||
- [ ] User=www-data
|
||||
- [ ] Group=www-data
|
||||
- [ ] Save and exit
|
||||
- [ ] Reload systemd
|
||||
```bash
|
||||
sudo systemctl daemon-reload
|
||||
```
|
||||
|
||||
### Step 7: Install Dependencies ✅
|
||||
- [ ] Activate virtual environment
|
||||
```bash
|
||||
cd /opt/ai_qc
|
||||
source venv/bin/activate
|
||||
```
|
||||
- [ ] Install waitress
|
||||
```bash
|
||||
pip install waitress
|
||||
```
|
||||
- [ ] Verify requirements
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
- [ ] Deactivate venv
|
||||
```bash
|
||||
deactivate
|
||||
```
|
||||
|
||||
### Step 8: Test Backend Standalone ✅
|
||||
- [ ] Test backend starts
|
||||
```bash
|
||||
cd /opt/ai_qc
|
||||
sudo -u www-data /opt/ai_qc/venv/bin/python run_api_server.py --host localhost --port 7183 --workers 2
|
||||
```
|
||||
- [ ] Backend server started without errors
|
||||
- [ ] In another terminal, test API
|
||||
```bash
|
||||
curl http://localhost:7183/api/profiles
|
||||
```
|
||||
- [ ] API response received (should show profiles JSON)
|
||||
- [ ] Stop test server (Ctrl+C)
|
||||
|
||||
### Step 9: Update Apache Configuration ✅
|
||||
- [ ] Backup current Apache config
|
||||
```bash
|
||||
sudo cp /etc/apache2/sites-available/ai_qc.conf /etc/apache2/sites-available/ai_qc.conf.backup
|
||||
```
|
||||
- [ ] Edit Apache config
|
||||
```bash
|
||||
sudo nano /etc/apache2/sites-available/ai_qc.conf
|
||||
```
|
||||
- [ ] Update key sections:
|
||||
- [ ] DocumentRoot points to /var/www/html/ai_qc_new
|
||||
- [ ] ProxyPass /api and /ai_qc/api configured
|
||||
- [ ] Alias /uploads points to /opt/ai_qc/uploads
|
||||
- [ ] Alias /output points to /opt/ai_qc/output
|
||||
- [ ] Save and exit
|
||||
- [ ] Test Apache config
|
||||
```bash
|
||||
sudo apache2ctl configtest
|
||||
```
|
||||
- [ ] Apache config test result: Syntax OK
|
||||
|
||||
### Step 10: Start Services ✅
|
||||
- [ ] Start backend service
|
||||
```bash
|
||||
sudo systemctl start ai_qc
|
||||
```
|
||||
- [ ] Check service status
|
||||
```bash
|
||||
sudo systemctl status ai_qc
|
||||
```
|
||||
- [ ] Service running successfully (active/running)
|
||||
- [ ] Check logs for errors
|
||||
```bash
|
||||
sudo journalctl -u ai_qc -n 50 --no-pager
|
||||
```
|
||||
- [ ] No critical errors in logs
|
||||
- [ ] Verify backend responds
|
||||
```bash
|
||||
curl http://localhost:7183/api/profiles
|
||||
```
|
||||
- [ ] Backend API responding correctly
|
||||
|
||||
### Step 11: Reload Apache ✅
|
||||
- [ ] Reload Apache
|
||||
```bash
|
||||
sudo systemctl reload apache2
|
||||
```
|
||||
- [ ] Check Apache status
|
||||
```bash
|
||||
sudo systemctl status apache2
|
||||
```
|
||||
- [ ] Apache reloaded successfully
|
||||
- [ ] Check Apache errors
|
||||
```bash
|
||||
sudo tail -20 /var/log/apache2/ai_qc_error.log
|
||||
```
|
||||
- [ ] No critical Apache errors
|
||||
|
||||
---
|
||||
|
||||
## Testing (10 minutes)
|
||||
|
||||
### Browser Testing ✅
|
||||
- [ ] Open application URL: `_______________`
|
||||
- [ ] Frontend loads correctly
|
||||
- [ ] No console errors (F12 → Console tab)
|
||||
- [ ] "Sign In with Microsoft" button visible
|
||||
- [ ] Click sign in and authenticate
|
||||
- [ ] Authentication successful
|
||||
- [ ] User name displayed in UI
|
||||
|
||||
### Functionality Testing ✅
|
||||
- [ ] Upload test file successfully
|
||||
- [ ] Select profile from dropdown
|
||||
- [ ] Start analysis
|
||||
- [ ] Progress updates appear in real-time
|
||||
- [ ] Analysis completes successfully
|
||||
- [ ] Results display correctly
|
||||
- [ ] Overall score shown
|
||||
- [ ] Individual check results visible
|
||||
- [ ] Download report button works
|
||||
- [ ] Saved files list updates automatically
|
||||
- [ ] New file highlighted in saved files list
|
||||
|
||||
### Additional Testing ✅
|
||||
- [ ] Test different profile (e.g., General Check)
|
||||
- [ ] Test with reference asset selection
|
||||
- [ ] Test JSON output mode
|
||||
- [ ] Verify JSON download works
|
||||
- [ ] Test sign out functionality
|
||||
- [ ] Test sign in again
|
||||
|
||||
---
|
||||
|
||||
## Finalization (5 minutes)
|
||||
|
||||
### Directory Cleanup ✅
|
||||
- [ ] Rename old directory
|
||||
```bash
|
||||
sudo mv /var/www/html/ai_qc /var/www/html/ai_qc_old
|
||||
```
|
||||
- [ ] Rename new directory
|
||||
```bash
|
||||
sudo mv /var/www/html/ai_qc_new /var/www/html/ai_qc
|
||||
```
|
||||
- [ ] Update Apache config DocumentRoot (if needed)
|
||||
```bash
|
||||
sudo nano /etc/apache2/sites-available/ai_qc.conf
|
||||
# Change: DocumentRoot /var/www/html/ai_qc_new
|
||||
# To: DocumentRoot /var/www/html/ai_qc
|
||||
```
|
||||
- [ ] Reload Apache
|
||||
```bash
|
||||
sudo systemctl reload apache2
|
||||
```
|
||||
- [ ] Test application still works after rename
|
||||
|
||||
### Enable Service on Boot ✅
|
||||
- [ ] Enable service
|
||||
```bash
|
||||
sudo systemctl enable ai_qc
|
||||
```
|
||||
- [ ] Verify enabled
|
||||
```bash
|
||||
sudo systemctl is-enabled ai_qc
|
||||
```
|
||||
- [ ] Result shows "enabled"
|
||||
|
||||
### Documentation ✅
|
||||
- [ ] Document migration completion time: `_______________`
|
||||
- [ ] Note any issues encountered: `_______________`
|
||||
- [ ] Record backup location: `_______________`
|
||||
- [ ] Save this checklist for reference
|
||||
|
||||
---
|
||||
|
||||
## Post-Migration Monitoring (24 hours)
|
||||
|
||||
### Immediate Monitoring (First Hour) ✅
|
||||
- [ ] Monitor logs every 10 minutes
|
||||
```bash
|
||||
sudo journalctl -u ai_qc -f
|
||||
```
|
||||
- [ ] Check for errors or warnings
|
||||
- [ ] Test multiple analyses
|
||||
- [ ] Verify all features working
|
||||
|
||||
### Day 1 Monitoring ✅
|
||||
- [ ] Check service status multiple times
|
||||
```bash
|
||||
sudo systemctl status ai_qc
|
||||
```
|
||||
- [ ] Review logs for any anomalies
|
||||
```bash
|
||||
sudo journalctl -u ai_qc -n 200 --no-pager
|
||||
```
|
||||
- [ ] Check disk space
|
||||
```bash
|
||||
df -h /opt/ai_qc
|
||||
```
|
||||
- [ ] Verify uploads and outputs working
|
||||
|
||||
### After 48 Hours ✅
|
||||
- [ ] Confirm no issues reported by users
|
||||
- [ ] Review system logs one final time
|
||||
- [ ] Remove old directory (optional)
|
||||
```bash
|
||||
sudo rm -rf /var/www/html/ai_qc_old
|
||||
```
|
||||
- [ ] Keep backup for 30 days before deleting
|
||||
|
||||
---
|
||||
|
||||
## Rollback Procedure (If Needed) 🚨
|
||||
|
||||
### Quick Rollback Steps
|
||||
If issues occur and you need to rollback immediately:
|
||||
|
||||
1. **Stop New Service**
|
||||
```bash
|
||||
sudo systemctl stop ai_qc
|
||||
```
|
||||
|
||||
2. **Restore Old Directory**
|
||||
```bash
|
||||
sudo mv /var/www/html/ai_qc /var/www/html/ai_qc_failed
|
||||
sudo mv /var/www/html/ai_qc_old /var/www/html/ai_qc
|
||||
```
|
||||
|
||||
3. **Restore Old Apache Config**
|
||||
```bash
|
||||
sudo cp /etc/apache2/sites-available/ai_qc.conf.backup /etc/apache2/sites-available/ai_qc.conf
|
||||
sudo systemctl reload apache2
|
||||
```
|
||||
|
||||
4. **Restore Old Service File**
|
||||
```bash
|
||||
sudo cp /etc/systemd/system/ai_qc.service.backup /etc/systemd/system/ai_qc.service
|
||||
sudo systemctl daemon-reload
|
||||
```
|
||||
|
||||
5. **Start Old Service**
|
||||
```bash
|
||||
sudo systemctl start ai_qc
|
||||
```
|
||||
|
||||
6. **Verify Old Version Works**
|
||||
```bash
|
||||
curl http://your-domain.com/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Migration Summary
|
||||
|
||||
**Migration Date**: `_______________`
|
||||
**Started**: `_______________`
|
||||
**Completed**: `_______________`
|
||||
**Total Duration**: `_______________`
|
||||
|
||||
**Services Involved**:
|
||||
- Backend Service: `_______________`
|
||||
- Web Server: Apache2
|
||||
- Working: ✅ / ❌
|
||||
|
||||
**Issues Encountered**:
|
||||
```
|
||||
Write any issues or notes here:
|
||||
|
||||
|
||||
|
||||
|
||||
```
|
||||
|
||||
**Final Status**:
|
||||
- [ ] ✅ Migration Successful - All features working
|
||||
- [ ] ⚠️ Migration Partial - Some issues to resolve
|
||||
- [ ] ❌ Migration Failed - Rolled back to original
|
||||
|
||||
**Sign-off**: `_______________` (Name and Date)
|
||||
|
||||
---
|
||||
|
||||
## Notes and Reminders
|
||||
|
||||
- Keep backup for at least 30 days before deleting
|
||||
- Monitor logs for first week after migration
|
||||
- Update any deployment documentation with new paths
|
||||
- Inform team of new directory structure
|
||||
- Update any automation scripts pointing to old paths
|
||||
|
||||
---
|
||||
|
||||
**End of Migration Checklist** ✨
|
||||
515
MIGRATION_GUIDE.md
Normal file
515
MIGRATION_GUIDE.md
Normal file
|
|
@ -0,0 +1,515 @@
|
|||
# Visual AI QC Migration Guide
|
||||
## Moving from Web Root to /opt/ Structure
|
||||
|
||||
This guide provides step-by-step instructions for migrating the Visual AI QC application from `/var/www/html/ai_qc/` to a split frontend/backend structure.
|
||||
|
||||
---
|
||||
|
||||
## Current vs. New Structure
|
||||
|
||||
### Current Structure
|
||||
```
|
||||
/var/www/html/ai_qc/
|
||||
├── api_server.py # Backend
|
||||
├── run_api_server.py # Backend launcher
|
||||
├── web_ui.html # Frontend
|
||||
├── visual_qc_apps/ # Backend
|
||||
├── profiles/ # Backend
|
||||
├── brand_guidelines/ # Backend
|
||||
├── uploads/ # Backend data
|
||||
├── output/ # Backend data
|
||||
├── venv/ # Backend dependencies
|
||||
└── ... (all other files)
|
||||
```
|
||||
|
||||
### New Structure
|
||||
```
|
||||
Frontend: /var/www/html/ai_qc/
|
||||
└── index.html # Renamed from web_ui.html
|
||||
|
||||
Backend: /opt/ai_qc/
|
||||
├── api_server.py
|
||||
├── run_api_server.py
|
||||
├── llm_config.py
|
||||
├── profile_config.py
|
||||
├── jwt_validator.py
|
||||
├── auth_middleware.py
|
||||
├── visual_qc_apps/
|
||||
├── profiles/
|
||||
├── brand_guidelines/
|
||||
├── config/
|
||||
├── uploads/
|
||||
├── output/
|
||||
├── venv/
|
||||
└── ... (all Python/backend files)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before starting, ensure you have:
|
||||
1. SSH access to the server with sudo privileges
|
||||
2. Backup of current deployment
|
||||
3. Maintenance window scheduled (estimated 15-30 minutes downtime)
|
||||
4. Apache restart permissions
|
||||
|
||||
---
|
||||
|
||||
## Step-by-Step Migration
|
||||
|
||||
### Step 0: Preparation (On your server via SSH)
|
||||
|
||||
```bash
|
||||
# Check current service name
|
||||
sudo systemctl list-units --type=service | grep ai_qc
|
||||
|
||||
# Check current Apache configuration
|
||||
ls -la /etc/apache2/sites-enabled/ | grep ai_qc
|
||||
|
||||
# Backup current deployment
|
||||
cd /var/www/html/ai_qc
|
||||
sudo tar -czf ~/ai_qc_backup_$(date +%Y%m%d_%H%M%S).tar.gz .
|
||||
echo "Backup created at: ~/ai_qc_backup_$(date +%Y%m%d_%H%M%S).tar.gz"
|
||||
```
|
||||
|
||||
### Step 1: Stop Current Service
|
||||
|
||||
```bash
|
||||
# Find the service name (likely ai_qc or ai_qc.service)
|
||||
sudo systemctl list-units --type=service | grep ai_qc
|
||||
|
||||
# Stop the service (replace SERVICE_NAME with actual name)
|
||||
sudo systemctl stop SERVICE_NAME
|
||||
|
||||
# Verify it's stopped
|
||||
ps aux | grep run_api_server.py
|
||||
# Should return no results (except the grep command itself)
|
||||
```
|
||||
|
||||
### Step 2: Create Backend Directory Structure
|
||||
|
||||
```bash
|
||||
# Create backend directory
|
||||
sudo mkdir -p /opt/ai_qc
|
||||
|
||||
# Copy all files except web_ui.html to backend
|
||||
cd /var/www/html/ai_qc
|
||||
sudo rsync -av \
|
||||
--exclude='web_ui.html' \
|
||||
--exclude='*.pyc' \
|
||||
--exclude='__pycache__' \
|
||||
--exclude='.git' \
|
||||
. /opt/ai_qc/
|
||||
|
||||
# Set ownership
|
||||
sudo chown -R www-data:www-data /opt/ai_qc
|
||||
|
||||
# Set permissions
|
||||
sudo chmod -R 750 /opt/ai_qc
|
||||
sudo chmod 770 /opt/ai_qc/uploads /opt/ai_qc/output
|
||||
sudo chmod 770 /opt/ai_qc/uploads-dev /opt/ai_qc/output-dev
|
||||
sudo chmod 640 /opt/ai_qc/config/*.env
|
||||
```
|
||||
|
||||
### Step 3: Prepare Frontend Directory
|
||||
|
||||
```bash
|
||||
# Create clean frontend directory
|
||||
sudo mkdir -p /var/www/html/ai_qc_new
|
||||
|
||||
# Copy web_ui.html and rename to index.html
|
||||
sudo cp /var/www/html/ai_qc/web_ui.html /var/www/html/ai_qc_new/index.html
|
||||
|
||||
# Set ownership
|
||||
sudo chown -R www-data:www-data /var/www/html/ai_qc_new
|
||||
```
|
||||
|
||||
### Step 4: Update Backend Configuration
|
||||
|
||||
```bash
|
||||
# Update production environment config with absolute paths
|
||||
sudo nano /opt/ai_qc/config/production.env
|
||||
|
||||
# Ensure these paths are absolute:
|
||||
# UPLOAD_FOLDER=/opt/ai_qc/uploads
|
||||
# OUTPUT_FOLDER=/opt/ai_qc/output
|
||||
# UPLOAD_FOLDER_DEV=/opt/ai_qc/uploads-dev
|
||||
# OUTPUT_FOLDER_DEV=/opt/ai_qc/output-dev
|
||||
# BRAND_GUIDELINES_FOLDER=/opt/ai_qc/brand_guidelines
|
||||
```
|
||||
|
||||
### Step 5: Update Frontend API URLs
|
||||
|
||||
```bash
|
||||
# Edit the frontend to use absolute API paths
|
||||
sudo nano /var/www/html/ai_qc_new/index.html
|
||||
|
||||
# Find all fetch() calls and ensure they use /api/ prefix
|
||||
# Search for: fetch('
|
||||
# Replace relative URLs with /api/ prefix if needed
|
||||
# Example: fetch('/start_analysis') → fetch('/api/start_analysis')
|
||||
```
|
||||
|
||||
**Important**: Check if your current `web_ui.html` already uses `/api/` prefix. If it does, no changes needed!
|
||||
|
||||
### Step 6: Update Systemd Service
|
||||
|
||||
```bash
|
||||
# Find current service file
|
||||
sudo find /etc/systemd/system -name "*ai_qc*"
|
||||
|
||||
# Create new service file (or update existing)
|
||||
sudo nano /etc/systemd/system/ai_qc.service
|
||||
```
|
||||
|
||||
Paste this content:
|
||||
```ini
|
||||
[Unit]
|
||||
Description=Visual AI QC Flask Application
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=www-data
|
||||
Group=www-data
|
||||
WorkingDirectory=/opt/ai_qc
|
||||
Environment="ENVIRONMENT=production"
|
||||
Environment="PATH=/opt/ai_qc/venv/bin:/usr/local/bin:/usr/bin:/bin"
|
||||
ExecStart=/opt/ai_qc/venv/bin/python /opt/ai_qc/run_api_server.py --host localhost --port 7183 --workers 2
|
||||
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
|
||||
NoNewPrivileges=true
|
||||
PrivateTmp=true
|
||||
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
SyslogIdentifier=ai_qc
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
Save and exit (Ctrl+X, Y, Enter)
|
||||
|
||||
```bash
|
||||
# Reload systemd
|
||||
sudo systemctl daemon-reload
|
||||
```
|
||||
|
||||
### Step 7: Update Apache Configuration
|
||||
|
||||
```bash
|
||||
# Find current Apache config
|
||||
ls -la /etc/apache2/sites-available/ | grep ai_qc
|
||||
|
||||
# Backup current config
|
||||
sudo cp /etc/apache2/sites-available/ai_qc.conf /etc/apache2/sites-available/ai_qc.conf.backup
|
||||
|
||||
# Edit Apache config
|
||||
sudo nano /etc/apache2/sites-available/ai_qc.conf
|
||||
```
|
||||
|
||||
Update the configuration to:
|
||||
```apache
|
||||
<VirtualHost *:80>
|
||||
ServerName your-domain.com
|
||||
|
||||
# Frontend - serve from web root
|
||||
DocumentRoot /var/www/html/ai_qc_new
|
||||
|
||||
<Directory /var/www/html/ai_qc_new>
|
||||
Options -Indexes +FollowSymLinks
|
||||
AllowOverride None
|
||||
Require all granted
|
||||
DirectoryIndex index.html
|
||||
</Directory>
|
||||
|
||||
# Backend API - proxy to Flask
|
||||
ProxyPreserveHost On
|
||||
ProxyPass /api http://localhost:7183/api
|
||||
ProxyPassReverse /api http://localhost:7183/api
|
||||
ProxyTimeout 300
|
||||
|
||||
# Serve uploaded files from backend
|
||||
Alias /uploads /opt/ai_qc/uploads
|
||||
<Directory /opt/ai_qc/uploads>
|
||||
Options -Indexes
|
||||
Require all granted
|
||||
</Directory>
|
||||
|
||||
# Serve output files from backend
|
||||
Alias /output /opt/ai_qc/output
|
||||
<Directory /opt/ai_qc/output>
|
||||
Options -Indexes
|
||||
Require all granted
|
||||
</Directory>
|
||||
|
||||
# Development folders (optional)
|
||||
Alias /uploads-dev /opt/ai_qc/uploads-dev
|
||||
<Directory /opt/ai_qc/uploads-dev>
|
||||
Options -Indexes
|
||||
Require all granted
|
||||
</Directory>
|
||||
|
||||
Alias /output-dev /opt/ai_qc/output-dev
|
||||
<Directory /opt/ai_qc/output-dev>
|
||||
Options -Indexes
|
||||
Require all granted
|
||||
</Directory>
|
||||
|
||||
ErrorLog ${APACHE_LOG_DIR}/ai_qc_error.log
|
||||
CustomLog ${APACHE_LOG_DIR}/ai_qc_access.log combined
|
||||
</VirtualHost>
|
||||
```
|
||||
|
||||
Save and exit, then:
|
||||
```bash
|
||||
# Test Apache configuration
|
||||
sudo apache2ctl configtest
|
||||
|
||||
# Should return "Syntax OK"
|
||||
```
|
||||
|
||||
### Step 8: Install Dependencies (if needed)
|
||||
|
||||
```bash
|
||||
# Activate virtual environment
|
||||
cd /opt/ai_qc
|
||||
source venv/bin/activate
|
||||
|
||||
# Install waitress if not already installed (for run_api_server.py)
|
||||
pip install waitress
|
||||
|
||||
# Verify all dependencies
|
||||
pip install -r requirements.txt
|
||||
|
||||
deactivate
|
||||
```
|
||||
|
||||
### Step 9: Test Backend Standalone
|
||||
|
||||
```bash
|
||||
# Test if backend starts correctly
|
||||
cd /opt/ai_qc
|
||||
sudo -u www-data /opt/ai_qc/venv/bin/python run_api_server.py --host localhost --port 7183 --workers 2
|
||||
|
||||
# In another terminal, test the API
|
||||
curl http://localhost:7183/api/profiles
|
||||
|
||||
# Should return profile data
|
||||
# Press Ctrl+C to stop the test server
|
||||
```
|
||||
|
||||
### Step 10: Start Services
|
||||
|
||||
```bash
|
||||
# Start the backend service
|
||||
sudo systemctl start ai_qc
|
||||
|
||||
# Check status
|
||||
sudo systemctl status ai_qc
|
||||
|
||||
# Check logs
|
||||
sudo journalctl -u ai_qc -f
|
||||
|
||||
# Verify backend is responding
|
||||
curl http://localhost:7183/api/profiles
|
||||
```
|
||||
|
||||
### Step 11: Reload Apache
|
||||
|
||||
```bash
|
||||
# Reload Apache to apply new configuration
|
||||
sudo systemctl reload apache2
|
||||
|
||||
# Check Apache status
|
||||
sudo systemctl status apache2
|
||||
|
||||
# Check Apache error log
|
||||
sudo tail -f /var/log/apache2/ai_qc_error.log
|
||||
```
|
||||
|
||||
### Step 12: Test the Application
|
||||
|
||||
```bash
|
||||
# Test frontend is accessible
|
||||
curl http://your-domain.com/
|
||||
|
||||
# Test API through Apache proxy
|
||||
curl http://your-domain.com/api/profiles
|
||||
|
||||
# Test file serving
|
||||
curl -I http://your-domain.com/uploads/
|
||||
curl -I http://your-domain.com/output/
|
||||
```
|
||||
|
||||
**Then test in browser:**
|
||||
1. Open http://your-domain.com/ in browser
|
||||
2. Sign in with Microsoft authentication
|
||||
3. Upload a test file
|
||||
4. Run analysis
|
||||
5. Verify results display correctly
|
||||
6. Check saved files list updates
|
||||
|
||||
### Step 13: Finalize Migration
|
||||
|
||||
Once everything is working:
|
||||
|
||||
```bash
|
||||
# Rename directories
|
||||
sudo mv /var/www/html/ai_qc /var/www/html/ai_qc_old
|
||||
sudo mv /var/www/html/ai_qc_new /var/www/html/ai_qc
|
||||
|
||||
# Update Apache config DocumentRoot if needed
|
||||
sudo nano /etc/apache2/sites-available/ai_qc.conf
|
||||
# Change: DocumentRoot /var/www/html/ai_qc_new
|
||||
# To: DocumentRoot /var/www/html/ai_qc
|
||||
|
||||
# Reload Apache
|
||||
sudo systemctl reload apache2
|
||||
|
||||
# Test again to ensure everything still works
|
||||
```
|
||||
|
||||
### Step 14: Enable Service on Boot
|
||||
|
||||
```bash
|
||||
# Ensure service starts on boot
|
||||
sudo systemctl enable ai_qc
|
||||
|
||||
# Verify it's enabled
|
||||
sudo systemctl is-enabled ai_qc
|
||||
# Should return "enabled"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Verification Checklist
|
||||
|
||||
After migration, verify:
|
||||
|
||||
- [ ] Backend service is running: `sudo systemctl status ai_qc`
|
||||
- [ ] Backend responds: `curl http://localhost:7183/api/profiles`
|
||||
- [ ] Apache is running: `sudo systemctl status apache2`
|
||||
- [ ] Frontend loads: Visit http://your-domain.com/
|
||||
- [ ] API calls work: Check browser console for errors
|
||||
- [ ] Authentication works: Sign in with Microsoft
|
||||
- [ ] File upload works: Upload test file
|
||||
- [ ] Analysis works: Run QC analysis on test file
|
||||
- [ ] Results display: Verify results show correctly
|
||||
- [ ] Saved files work: Check saved files list updates
|
||||
- [ ] File downloads work: Download generated PDF reports
|
||||
- [ ] Logs are clean: `sudo journalctl -u ai_qc -n 50 --no-pager`
|
||||
|
||||
---
|
||||
|
||||
## Rollback Plan
|
||||
|
||||
If issues occur:
|
||||
|
||||
### Quick Rollback
|
||||
|
||||
```bash
|
||||
# Stop new service
|
||||
sudo systemctl stop ai_qc
|
||||
|
||||
# Restore old Apache config
|
||||
sudo cp /etc/apache2/sites-available/ai_qc.conf.backup /etc/apache2/sites-available/ai_qc.conf
|
||||
sudo systemctl reload apache2
|
||||
|
||||
# Rename directories back
|
||||
sudo mv /var/www/html/ai_qc /var/www/html/ai_qc_failed
|
||||
sudo mv /var/www/html/ai_qc_old /var/www/html/ai_qc
|
||||
|
||||
# Restore old service file (if you backed it up)
|
||||
sudo cp /etc/systemd/system/ai_qc.service.backup /etc/systemd/system/ai_qc.service
|
||||
sudo systemctl daemon-reload
|
||||
|
||||
# Start old service
|
||||
sudo systemctl start ai_qc
|
||||
|
||||
# Verify old version works
|
||||
curl http://your-domain.com/
|
||||
```
|
||||
|
||||
### Full Restore from Backup
|
||||
|
||||
```bash
|
||||
# Stop all services
|
||||
sudo systemctl stop ai_qc
|
||||
sudo systemctl stop apache2
|
||||
|
||||
# Remove new directories
|
||||
sudo rm -rf /opt/ai_qc
|
||||
sudo rm -rf /var/www/html/ai_qc_new
|
||||
|
||||
# Restore from backup
|
||||
cd /var/www/html/ai_qc
|
||||
sudo tar -xzf ~/ai_qc_backup_YYYYMMDD_HHMMSS.tar.gz
|
||||
|
||||
# Restore old config and restart
|
||||
sudo systemctl start ai_qc
|
||||
sudo systemctl start apache2
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Monitoring After Migration
|
||||
|
||||
### Check Logs Regularly
|
||||
|
||||
```bash
|
||||
# Backend logs
|
||||
sudo journalctl -u ai_qc -f
|
||||
|
||||
# Apache logs
|
||||
sudo tail -f /var/log/apache2/ai_qc_error.log
|
||||
sudo tail -f /var/log/apache2/ai_qc_access.log
|
||||
|
||||
# Check disk space
|
||||
df -h /opt/ai_qc
|
||||
```
|
||||
|
||||
### Performance Monitoring
|
||||
|
||||
```bash
|
||||
# Check backend process
|
||||
ps aux | grep run_api_server
|
||||
|
||||
# Check memory usage
|
||||
sudo systemctl status ai_qc
|
||||
|
||||
# Check port is listening
|
||||
sudo ss -tlnp | grep 7183
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Benefits of New Structure
|
||||
|
||||
✅ **Security**: Backend code not accessible from web root
|
||||
✅ **Separation**: Frontend and backend can be updated independently
|
||||
✅ **Scalability**: Backend can be moved to separate server if needed
|
||||
✅ **Standard Practice**: Matches other apps on your server (/opt/veo3, /opt/voice2text)
|
||||
✅ **Better Permissions**: More granular access control
|
||||
✅ **Cleaner Structure**: Clear separation of concerns
|
||||
|
||||
---
|
||||
|
||||
## Need Help?
|
||||
|
||||
If you encounter issues:
|
||||
1. Check logs: `sudo journalctl -u ai_qc -n 100 --no-pager`
|
||||
2. Check Apache logs: `sudo tail -100 /var/log/apache2/ai_qc_error.log`
|
||||
3. Test backend directly: `curl http://localhost:7183/api/profiles`
|
||||
4. Verify permissions: `ls -la /opt/ai_qc`
|
||||
5. Check service status: `sudo systemctl status ai_qc`
|
||||
|
||||
Common issues:
|
||||
- **Permission denied**: Check file ownership (`sudo chown -R www-data:www-data /opt/ai_qc`)
|
||||
- **Module not found**: Check virtual environment (`which python` should show venv path)
|
||||
- **Port already in use**: Check if old service is still running (`ps aux | grep 7183`)
|
||||
- **API not responding**: Check if service is running (`sudo systemctl status ai_qc`)
|
||||
202
MIGRATION_SUMMARY.md
Normal file
202
MIGRATION_SUMMARY.md
Normal file
|
|
@ -0,0 +1,202 @@
|
|||
# Visual AI QC Migration - Quick Summary
|
||||
|
||||
## What You Need to Know
|
||||
|
||||
### Why Split Frontend/Backend?
|
||||
|
||||
Your server already follows this pattern with other apps:
|
||||
- `/opt/veo3/backend/` - Backend in opt
|
||||
- `/opt/voice2text/` - Backend in opt
|
||||
- `/opt/justeight/` - Backend in opt
|
||||
|
||||
This structure provides:
|
||||
- ✅ **Better Security** - Backend code not in web root
|
||||
- ✅ **Cleaner Separation** - Frontend and backend updates independent
|
||||
- ✅ **Standard Practice** - Industry standard for web applications
|
||||
- ✅ **Better Permissions** - Granular access control
|
||||
|
||||
### Current vs. New Structure
|
||||
|
||||
**Current:**
|
||||
```
|
||||
/var/www/html/ai_qc/ ← Everything here
|
||||
├── web_ui.html (frontend)
|
||||
├── api_server.py (backend)
|
||||
├── visual_qc_apps/ (backend)
|
||||
└── ... (all files mixed together)
|
||||
```
|
||||
|
||||
**After Migration:**
|
||||
```
|
||||
/var/www/html/ai_qc/ ← Frontend only
|
||||
└── index.html (renamed from web_ui.html)
|
||||
|
||||
/opt/ai_qc/ ← Backend only
|
||||
├── api_server.py
|
||||
├── run_api_server.py
|
||||
├── visual_qc_apps/
|
||||
├── profiles/
|
||||
├── brand_guidelines/
|
||||
├── uploads/
|
||||
├── output/
|
||||
└── ... (all Python code and data)
|
||||
```
|
||||
|
||||
### Files Created for Migration
|
||||
|
||||
1. **`run_api_server.py`** - Production server wrapper (uses Waitress WSGI)
|
||||
2. **`ai_qc.service`** - Systemd service configuration
|
||||
3. **`apache_config.conf`** - Apache virtual host configuration
|
||||
4. **`MIGRATION_GUIDE.md`** - Complete step-by-step instructions
|
||||
5. **`requirements.txt`** - Updated with Waitress dependency
|
||||
|
||||
### Frontend Changes Required
|
||||
|
||||
**NONE!** Your `web_ui.html` already has smart base path detection:
|
||||
|
||||
```javascript
|
||||
function getBasePath() {
|
||||
const path = window.location.pathname;
|
||||
if (path.includes('/ai_qc/')) {
|
||||
return path.substring(0, path.indexOf('/ai_qc/') + 7);
|
||||
}
|
||||
return '/';
|
||||
}
|
||||
```
|
||||
|
||||
This automatically detects if running at root (`/`) or subdirectory (`/ai_qc/`) and adjusts API calls accordingly.
|
||||
|
||||
### Backend Changes Required
|
||||
|
||||
Minimal! Just update file paths in `api_server.py` to use absolute paths:
|
||||
|
||||
```python
|
||||
UPLOAD_FOLDER = '/opt/ai_qc/uploads'
|
||||
OUTPUT_FOLDER = '/opt/ai_qc/output'
|
||||
# etc.
|
||||
```
|
||||
|
||||
### Migration Timeline
|
||||
|
||||
- **Preparation**: 10 minutes (backup, read guide)
|
||||
- **Migration**: 15-20 minutes (follow MIGRATION_GUIDE.md)
|
||||
- **Testing**: 10 minutes (verify all features work)
|
||||
- **Total Downtime**: ~20-30 minutes
|
||||
|
||||
### Quick Migration Checklist
|
||||
|
||||
1. ✅ Read `MIGRATION_GUIDE.md` completely
|
||||
2. ✅ Schedule maintenance window
|
||||
3. ✅ Backup current deployment
|
||||
4. ✅ Stop current service
|
||||
5. ✅ Copy backend files to `/opt/ai_qc/`
|
||||
6. ✅ Copy frontend to `/var/www/html/ai_qc/` (rename to index.html)
|
||||
7. ✅ Update systemd service file
|
||||
8. ✅ Update Apache configuration
|
||||
9. ✅ Install waitress dependency
|
||||
10. ✅ Test backend standalone
|
||||
11. ✅ Start services
|
||||
12. ✅ Test in browser
|
||||
13. ✅ Enable service on boot
|
||||
|
||||
### Rollback Plan
|
||||
|
||||
If issues occur, rollback is simple:
|
||||
1. Stop new service
|
||||
2. Restore old Apache config
|
||||
3. Rename old directory back
|
||||
4. Start old service
|
||||
|
||||
Full instructions in `MIGRATION_GUIDE.md` → "Rollback Plan" section.
|
||||
|
||||
### What to Test After Migration
|
||||
|
||||
- [ ] Frontend loads (http://your-domain.com/)
|
||||
- [ ] Authentication works (Microsoft sign-in)
|
||||
- [ ] File upload works
|
||||
- [ ] Analysis runs successfully
|
||||
- [ ] Results display correctly
|
||||
- [ ] Saved files list updates
|
||||
- [ ] PDF downloads work
|
||||
- [ ] All profiles load
|
||||
- [ ] Brand guidelines work
|
||||
|
||||
### Need Help During Migration?
|
||||
|
||||
**Before Migration:**
|
||||
- Read `MIGRATION_GUIDE.md` completely
|
||||
- Test commands in Step 0 to understand current setup
|
||||
- Verify backup is created successfully
|
||||
|
||||
**During Migration:**
|
||||
- Follow steps sequentially - don't skip
|
||||
- Test each step before moving to next
|
||||
- Check logs if something fails:
|
||||
```bash
|
||||
sudo journalctl -u ai_qc -n 50 --no-pager
|
||||
sudo tail -100 /var/log/apache2/ai_qc_error.log
|
||||
```
|
||||
|
||||
**After Migration:**
|
||||
- Monitor logs for first hour
|
||||
- Test all major features
|
||||
- Keep backup for 48 hours before deleting
|
||||
|
||||
### Common Issues and Solutions
|
||||
|
||||
| Issue | Cause | Solution |
|
||||
|-------|-------|----------|
|
||||
| Backend won't start | Permission denied | `sudo chown -R www-data:www-data /opt/ai_qc` |
|
||||
| Module not found | Wrong Python environment | Check service file uses `/opt/ai_qc/venv/bin/python` |
|
||||
| API not responding | Service not running | `sudo systemctl status ai_qc` |
|
||||
| Frontend shows 404 | Apache config wrong | Check DocumentRoot path in Apache config |
|
||||
| Uploads fail | Directory permissions | `sudo chmod 770 /opt/ai_qc/uploads` |
|
||||
|
||||
### Key Commands
|
||||
|
||||
```bash
|
||||
# Check service status
|
||||
sudo systemctl status ai_qc
|
||||
|
||||
# View logs (live)
|
||||
sudo journalctl -u ai_qc -f
|
||||
|
||||
# Check Apache logs
|
||||
sudo tail -f /var/log/apache2/ai_qc_error.log
|
||||
|
||||
# Test backend directly
|
||||
curl http://localhost:7183/api/profiles
|
||||
|
||||
# Test through Apache
|
||||
curl http://your-domain.com/api/profiles
|
||||
|
||||
# Restart service
|
||||
sudo systemctl restart ai_qc
|
||||
|
||||
# Reload Apache
|
||||
sudo systemctl reload apache2
|
||||
```
|
||||
|
||||
### Files to Review Before Migration
|
||||
|
||||
1. **Read completely**: `MIGRATION_GUIDE.md`
|
||||
2. **Understand**: `apache_config.conf` (your Apache setup)
|
||||
3. **Review**: `ai_qc.service` (systemd service)
|
||||
4. **Check**: `run_api_server.py` (server wrapper)
|
||||
|
||||
### Next Steps
|
||||
|
||||
1. **Read `MIGRATION_GUIDE.md`** - Complete step-by-step instructions
|
||||
2. **Schedule maintenance window** - 30 minutes recommended
|
||||
3. **Test in development** - If you have a dev server, test there first
|
||||
4. **Execute migration** - Follow guide exactly
|
||||
5. **Monitor and verify** - Test all features thoroughly
|
||||
|
||||
---
|
||||
|
||||
## Questions?
|
||||
|
||||
- **Where's the detailed guide?** → `MIGRATION_GUIDE.md`
|
||||
- **What Apache config do I use?** → `apache_config.conf`
|
||||
- **How do I start the service?** → See `ai_qc.service`
|
||||
- **Need to rollback?** → `MIGRATION_GUIDE.md` → "Rollback Plan"
|
||||
|
|
@ -713,13 +713,19 @@ DEBUG_MODE=false
|
|||
|
||||
## 📚 Additional Documentation
|
||||
|
||||
### Core Documentation
|
||||
- **[Development/Production Setup](DEV_PROD_SETUP.md)**: Complete guide for development and production environments (**NEW** ⭐)
|
||||
- **[API Reference](API_README.md)**: Detailed API endpoint documentation
|
||||
- **[Environment Setup](ENVIRONMENT_SETUP_GUIDE.md)**: Comprehensive setup instructions
|
||||
- **[Environment Setup](ENVIRONMENT_SETUP_GUIDE.md)**: Comprehensive setup instructions
|
||||
- **[Testing Guide](TESTING_GUIDE.md)**: Testing procedures and examples
|
||||
- **[Triage System](TRIAGE_SYSTEM_README.md)**: Automatic content type detection
|
||||
- **[Profiles Guide](profiles/README.md)**: Profile configuration and customization
|
||||
|
||||
### Deployment Documentation
|
||||
- **[Migration Guide](MIGRATION_GUIDE.md)**: Complete step-by-step migration to split frontend/backend structure (**NEW** 🚀)
|
||||
- **[Migration Summary](MIGRATION_SUMMARY.md)**: Quick reference for deployment restructure (**NEW** 📋)
|
||||
- **[Deployment Restructure](DEPLOYMENT_RESTRUCTURE.md)**: Detailed architecture and benefits explanation (**NEW** 🏗️)
|
||||
|
||||
## 🤝 Contributing
|
||||
|
||||
1. Fork the repository
|
||||
|
|
|
|||
28
ai_qc.service
Normal file
28
ai_qc.service
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
[Unit]
|
||||
Description=Visual AI QC Flask Application
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=www-data
|
||||
Group=www-data
|
||||
WorkingDirectory=/opt/ai_qc
|
||||
Environment="ENVIRONMENT=production"
|
||||
Environment="PATH=/opt/ai_qc/venv/bin:/usr/local/bin:/usr/bin:/bin"
|
||||
ExecStart=/opt/ai_qc/venv/bin/python /opt/ai_qc/run_api_server.py --host localhost --port 7183 --workers 2
|
||||
|
||||
# Restart policy
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
|
||||
# Security settings
|
||||
NoNewPrivileges=true
|
||||
PrivateTmp=true
|
||||
|
||||
# Logging
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
SyslogIdentifier=ai_qc
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
70
apache_config.conf
Normal file
70
apache_config.conf
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
# Apache Configuration for Visual AI QC
|
||||
# Save to: /etc/apache2/sites-available/ai_qc.conf
|
||||
# Enable with: sudo a2ensite ai_qc.conf
|
||||
|
||||
<VirtualHost *:80>
|
||||
ServerName your-domain.com
|
||||
ServerAlias www.your-domain.com
|
||||
|
||||
# Document root for frontend
|
||||
DocumentRoot /var/www/html/ai_qc
|
||||
|
||||
<Directory /var/www/html/ai_qc>
|
||||
Options -Indexes +FollowSymLinks
|
||||
AllowOverride None
|
||||
Require all granted
|
||||
|
||||
# Serve index.html as default
|
||||
DirectoryIndex index.html
|
||||
</Directory>
|
||||
|
||||
# Proxy API requests to Flask backend
|
||||
# Handle both /api and /ai_qc/api patterns (frontend auto-detects)
|
||||
ProxyPreserveHost On
|
||||
|
||||
# If serving from subdirectory /ai_qc/
|
||||
ProxyPass /ai_qc/api http://localhost:7183/api
|
||||
ProxyPassReverse /ai_qc/api http://localhost:7183/api
|
||||
|
||||
# If serving from root /
|
||||
ProxyPass /api http://localhost:7183/api
|
||||
ProxyPassReverse /api http://localhost:7183/api
|
||||
|
||||
# Increase timeout for long-running analysis
|
||||
ProxyTimeout 300
|
||||
|
||||
# Serve uploaded files from backend location
|
||||
Alias /uploads /opt/ai_qc/uploads
|
||||
<Directory /opt/ai_qc/uploads>
|
||||
Options -Indexes
|
||||
Require all granted
|
||||
</Directory>
|
||||
|
||||
# Serve output files from backend location
|
||||
Alias /output /opt/ai_qc/output
|
||||
<Directory /opt/ai_qc/output>
|
||||
Options -Indexes
|
||||
Require all granted
|
||||
</Directory>
|
||||
|
||||
# Development folders (optional, comment out in production)
|
||||
Alias /uploads-dev /opt/ai_qc/uploads-dev
|
||||
<Directory /opt/ai_qc/uploads-dev>
|
||||
Options -Indexes
|
||||
Require all granted
|
||||
</Directory>
|
||||
|
||||
Alias /output-dev /opt/ai_qc/output-dev
|
||||
<Directory /opt/ai_qc/output-dev>
|
||||
Options -Indexes
|
||||
Require all granted
|
||||
</Directory>
|
||||
|
||||
# Logging
|
||||
ErrorLog ${APACHE_LOG_DIR}/ai_qc_error.log
|
||||
CustomLog ${APACHE_LOG_DIR}/ai_qc_access.log combined
|
||||
|
||||
</VirtualHost>
|
||||
|
||||
# Enable required Apache modules with:
|
||||
# sudo a2enmod proxy proxy_http alias
|
||||
|
|
@ -6,6 +6,7 @@ opencv-python>=4.0.0
|
|||
python-dotenv>=1.0.0
|
||||
flask>=2.2.3
|
||||
hypercorn>=0.14.3
|
||||
waitress>=2.1.2
|
||||
requests>=2.28.2
|
||||
python-multipart>=0.0.5
|
||||
colorama>=0.4.4
|
||||
|
|
|
|||
39
run_api_server.py
Executable file
39
run_api_server.py
Executable file
|
|
@ -0,0 +1,39 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
Production server wrapper for Visual AI QC
|
||||
Runs the Flask application using Waitress WSGI server
|
||||
"""
|
||||
import argparse
|
||||
import sys
|
||||
import os
|
||||
from waitress import serve
|
||||
|
||||
# Add current directory to Python path
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
# Import the Flask app
|
||||
from api_server import app
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description='Run Visual AI QC API Server')
|
||||
parser.add_argument('--host', default='localhost', help='Host to bind to')
|
||||
parser.add_argument('--port', type=int, default=7183, help='Port to bind to')
|
||||
parser.add_argument('--workers', type=int, default=2, help='Number of worker threads')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
print(f"Starting Visual AI QC server on {args.host}:{args.port}")
|
||||
print(f"Worker threads: {args.workers}")
|
||||
print(f"Working directory: {os.getcwd()}")
|
||||
|
||||
# Use Waitress WSGI server (production-ready)
|
||||
serve(
|
||||
app,
|
||||
host=args.host,
|
||||
port=args.port,
|
||||
threads=args.workers,
|
||||
url_scheme='http'
|
||||
)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Loading…
Add table
Reference in a new issue