chore: PostgreSQL migration compatibility and infrastructure improvements
Database & Migrations: - Update all Alembic migrations for PostgreSQL compatibility - Remove SQLite-specific syntax (AUTOINCREMENT, etc.) - Add database utility helpers for PostgreSQL operations - Fix services to use PostgreSQL-compatible queries Documentation: - Add comprehensive Docker deployment guide - Add production deployment documentation - Add infrastructure architecture documentation - Update database setup guide for PostgreSQL-only - Expand troubleshooting guide Architecture & Validation: - Add migration.yaml rules for SQL compatibility checking - Enhance validate_architecture.py with migration validation - Update architecture rules to validate Alembic migrations Development: - Fix duplicate install-all target in Makefile - Add Celery/Redis validation to install.py script - Add docker-compose.test.yml for CI testing - Add squash_migrations.py utility script - Update tests for PostgreSQL compatibility - Improve test fixtures in conftest.py Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,399 @@
|
||||
# Traditional VPS Deployment
|
||||
|
||||
This guide covers deploying Wizamart to a traditional VPS (Ubuntu 22.04+) without containers.
|
||||
|
||||
**Best for:** Teams who want direct server access and familiar Linux administration.
|
||||
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Ubuntu 22.04 LTS or newer
|
||||
- 4GB+ RAM recommended
|
||||
- Root or sudo access
|
||||
- Domain name with DNS configured
|
||||
|
||||
---
|
||||
|
||||
## Quick Start
|
||||
|
||||
```bash
|
||||
# 1. Install system packages
|
||||
sudo apt update && sudo apt upgrade -y
|
||||
sudo apt install -y nginx postgresql-15 redis-server python3.11 python3.11-venv git curl
|
||||
|
||||
# 2. Create application user
|
||||
sudo useradd -m -s /bin/bash wizamart
|
||||
|
||||
# 3. Setup PostgreSQL
|
||||
sudo -u postgres createuser wizamart_user
|
||||
sudo -u postgres createdb wizamart_db -O wizamart_user
|
||||
sudo -u postgres psql -c "ALTER USER wizamart_user WITH PASSWORD 'your-secure-password';"
|
||||
|
||||
# 4. Clone and setup application
|
||||
sudo su - wizamart
|
||||
git clone <repository-url> ~/app
|
||||
cd ~/app
|
||||
python3.11 -m venv .venv
|
||||
source .venv/bin/activate
|
||||
pip install -r requirements.txt
|
||||
|
||||
# 5. Configure environment
|
||||
cp .env.example .env
|
||||
nano .env # Edit with production values
|
||||
|
||||
# 6. Initialize database
|
||||
alembic upgrade head
|
||||
python scripts/init_production.py
|
||||
|
||||
# 7. Exit wizamart user
|
||||
exit
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Systemd Services
|
||||
|
||||
### Main Application
|
||||
|
||||
```bash
|
||||
sudo nano /etc/systemd/system/wizamart.service
|
||||
```
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=Wizamart API Server
|
||||
After=network.target postgresql.service redis.service
|
||||
|
||||
[Service]
|
||||
User=wizamart
|
||||
Group=wizamart
|
||||
WorkingDirectory=/home/wizamart/app
|
||||
Environment="PATH=/home/wizamart/app/.venv/bin"
|
||||
EnvironmentFile=/home/wizamart/app/.env
|
||||
ExecStart=/home/wizamart/app/.venv/bin/uvicorn main:app --host 127.0.0.1 --port 8000 --workers 4
|
||||
Restart=always
|
||||
RestartSec=3
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
### Celery Worker (when implemented)
|
||||
|
||||
```bash
|
||||
sudo nano /etc/systemd/system/wizamart-celery.service
|
||||
```
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=Wizamart Celery Worker
|
||||
After=network.target redis.service postgresql.service
|
||||
|
||||
[Service]
|
||||
User=wizamart
|
||||
Group=wizamart
|
||||
WorkingDirectory=/home/wizamart/app
|
||||
Environment="PATH=/home/wizamart/app/.venv/bin"
|
||||
EnvironmentFile=/home/wizamart/app/.env
|
||||
ExecStart=/home/wizamart/app/.venv/bin/celery -A app.celery worker --loglevel=info --concurrency=4
|
||||
Restart=always
|
||||
RestartSec=3
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
### Celery Beat (Scheduler)
|
||||
|
||||
```bash
|
||||
sudo nano /etc/systemd/system/wizamart-celery-beat.service
|
||||
```
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=Wizamart Celery Beat Scheduler
|
||||
After=network.target redis.service
|
||||
|
||||
[Service]
|
||||
User=wizamart
|
||||
Group=wizamart
|
||||
WorkingDirectory=/home/wizamart/app
|
||||
Environment="PATH=/home/wizamart/app/.venv/bin"
|
||||
EnvironmentFile=/home/wizamart/app/.env
|
||||
ExecStart=/home/wizamart/app/.venv/bin/celery -A app.celery beat --loglevel=info
|
||||
Restart=always
|
||||
RestartSec=3
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
### Enable Services
|
||||
|
||||
```bash
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable wizamart wizamart-celery wizamart-celery-beat
|
||||
sudo systemctl start wizamart wizamart-celery wizamart-celery-beat
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Nginx Configuration
|
||||
|
||||
```bash
|
||||
sudo nano /etc/nginx/sites-available/wizamart
|
||||
```
|
||||
|
||||
```nginx
|
||||
# Redirect HTTP to HTTPS
|
||||
server {
|
||||
listen 80;
|
||||
server_name yourdomain.com www.yourdomain.com;
|
||||
return 301 https://$server_name$request_uri;
|
||||
}
|
||||
|
||||
# Main HTTPS server
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
server_name yourdomain.com www.yourdomain.com;
|
||||
|
||||
# SSL (managed by Certbot)
|
||||
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
|
||||
include /etc/letsencrypt/options-ssl-nginx.conf;
|
||||
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
|
||||
|
||||
# Security headers
|
||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header X-XSS-Protection "1; mode=block" always;
|
||||
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
||||
|
||||
# Logging
|
||||
access_log /var/log/nginx/wizamart.access.log;
|
||||
error_log /var/log/nginx/wizamart.error.log;
|
||||
|
||||
# Static files (served directly)
|
||||
location /static {
|
||||
alias /home/wizamart/app/static;
|
||||
expires 30d;
|
||||
add_header Cache-Control "public, immutable";
|
||||
access_log off;
|
||||
}
|
||||
|
||||
# Uploaded files
|
||||
location /uploads {
|
||||
alias /home/wizamart/app/uploads;
|
||||
expires 7d;
|
||||
add_header Cache-Control "public";
|
||||
}
|
||||
|
||||
# Application
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:8000;
|
||||
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;
|
||||
|
||||
# WebSocket support
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
|
||||
# Timeouts
|
||||
proxy_connect_timeout 60s;
|
||||
proxy_send_timeout 60s;
|
||||
proxy_read_timeout 60s;
|
||||
}
|
||||
|
||||
# Block sensitive files
|
||||
location ~ /\. {
|
||||
deny all;
|
||||
}
|
||||
location ~ \.env$ {
|
||||
deny all;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Enable Site
|
||||
|
||||
```bash
|
||||
sudo ln -s /etc/nginx/sites-available/wizamart /etc/nginx/sites-enabled/
|
||||
sudo nginx -t
|
||||
sudo systemctl reload nginx
|
||||
```
|
||||
|
||||
### SSL with Certbot
|
||||
|
||||
```bash
|
||||
sudo apt install certbot python3-certbot-nginx
|
||||
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Firewall
|
||||
|
||||
```bash
|
||||
sudo ufw allow OpenSSH
|
||||
sudo ufw allow 'Nginx Full'
|
||||
sudo ufw enable
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Daily Operations
|
||||
|
||||
### View Logs
|
||||
|
||||
```bash
|
||||
# Application logs
|
||||
sudo journalctl -u wizamart -f
|
||||
|
||||
# Celery logs
|
||||
sudo journalctl -u wizamart-celery -f
|
||||
|
||||
# Nginx logs
|
||||
sudo tail -f /var/log/nginx/wizamart.access.log
|
||||
sudo tail -f /var/log/nginx/wizamart.error.log
|
||||
|
||||
# PostgreSQL logs
|
||||
sudo tail -f /var/log/postgresql/postgresql-15-main.log
|
||||
```
|
||||
|
||||
### Restart Services
|
||||
|
||||
```bash
|
||||
sudo systemctl restart wizamart
|
||||
sudo systemctl restart wizamart-celery
|
||||
sudo systemctl restart nginx
|
||||
```
|
||||
|
||||
### Database Access
|
||||
|
||||
```bash
|
||||
# Connect as wizamart user
|
||||
sudo -u postgres psql wizamart_db
|
||||
|
||||
# Or with password
|
||||
psql -h localhost -U wizamart_user -d wizamart_db
|
||||
```
|
||||
|
||||
### Deploy Updates
|
||||
|
||||
```bash
|
||||
sudo su - wizamart
|
||||
cd ~/app
|
||||
git pull origin main
|
||||
source .venv/bin/activate
|
||||
pip install -r requirements.txt
|
||||
alembic upgrade head
|
||||
exit
|
||||
sudo systemctl restart wizamart wizamart-celery
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Backups
|
||||
|
||||
### Database Backup Script
|
||||
|
||||
```bash
|
||||
sudo nano /home/wizamart/backup.sh
|
||||
```
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
BACKUP_DIR=/home/wizamart/backups
|
||||
DATE=$(date +%Y%m%d_%H%M%S)
|
||||
|
||||
# Create backup directory
|
||||
mkdir -p $BACKUP_DIR
|
||||
|
||||
# Backup database
|
||||
pg_dump -U wizamart_user wizamart_db | gzip > $BACKUP_DIR/db_$DATE.sql.gz
|
||||
|
||||
# Backup uploads
|
||||
tar -czf $BACKUP_DIR/uploads_$DATE.tar.gz -C /home/wizamart/app uploads/
|
||||
|
||||
# Keep last 7 days
|
||||
find $BACKUP_DIR -name "*.gz" -mtime +7 -delete
|
||||
|
||||
echo "Backup completed: $DATE"
|
||||
```
|
||||
|
||||
```bash
|
||||
chmod +x /home/wizamart/backup.sh
|
||||
```
|
||||
|
||||
### Cron Job
|
||||
|
||||
```bash
|
||||
sudo -u wizamart crontab -e
|
||||
```
|
||||
|
||||
```cron
|
||||
# Daily backup at 2 AM
|
||||
0 2 * * * /home/wizamart/backup.sh >> /home/wizamart/backup.log 2>&1
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Monitoring
|
||||
|
||||
### Basic Health Check
|
||||
|
||||
```bash
|
||||
curl -s http://localhost:8000/health | jq
|
||||
```
|
||||
|
||||
### Process Monitoring
|
||||
|
||||
```bash
|
||||
# Check all services
|
||||
systemctl status wizamart wizamart-celery postgresql redis nginx
|
||||
|
||||
# Resource usage
|
||||
htop
|
||||
df -h
|
||||
free -h
|
||||
```
|
||||
|
||||
### Set Up Sentry (Error Tracking)
|
||||
|
||||
Add to `.env`:
|
||||
```env
|
||||
SENTRY_DSN=https://your-sentry-dsn
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
See [Infrastructure Guide - Troubleshooting](infrastructure.md#troubleshooting-guide) for detailed diagnostics.
|
||||
|
||||
### Quick Checks
|
||||
|
||||
```bash
|
||||
# Is the app running?
|
||||
systemctl status wizamart
|
||||
|
||||
# Can we connect to the database?
|
||||
pg_isready -h localhost -U wizamart_user
|
||||
|
||||
# Is Redis running?
|
||||
redis-cli ping
|
||||
|
||||
# Check open ports
|
||||
ss -tlnp | grep -E '(8000|5432|6379|80|443)'
|
||||
|
||||
# View recent errors
|
||||
journalctl -u wizamart --since "1 hour ago" | grep -i error
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user