Replace all ~1,086 occurrences of Wizamart/wizamart/WIZAMART/WizaMart with Orion/orion/ORION across 184 files. This includes database identifiers, email addresses, domain references, R2 bucket names, DNS prefixes, encryption salt, Celery app name, config defaults, Docker configs, CI configs, documentation, seed data, and templates. Renames homepage-wizamart.html template to homepage-orion.html. Fixes duplicate file_pattern key in api.yaml architecture rule. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
8.2 KiB
8.2 KiB
GitLab CI/CD Deployment Guide
This document describes how to deploy the Orion platform to a DigitalOcean Droplet using bare-metal systemd + Nginx, with automated deployments from GitLab CI/CD.
Prerequisites
- DigitalOcean Droplet (Ubuntu 22.04+ recommended)
- Domain name pointing to your server
- GitLab repository with CI/CD enabled
- SSH key pair for deployment
1. Server Folder Structure
The application will be deployed to:
/var/www/orion/
├── app/ # FastAPI application
├── static/
│ ├── admin/
│ ├── store/
│ ├── shop/
│ └── shared/
├── templates/
├── alembic/ # Database migrations
├── .venv/ # Python virtual environment
├── .env # Environment variables (created manually)
└── pyproject.toml
2. Server Setup
Create Deploy User (Recommended)
sudo adduser deploy --disabled-password
sudo usermod -aG sudo deploy
sudo mkdir -p /var/www/orion
sudo chown -R deploy:deploy /var/www/orion
Install System Dependencies
sudo apt update
sudo apt install -y python3.11 python3.11-venv python3-pip \
build-essential libpq-dev nginx postgresql postgresql-contrib \
nodejs npm certbot python3-certbot-nginx
Install uv (Python Package Manager)
curl -LsSf https://astral.sh/uv/install.sh | sh
source ~/.bashrc
3. Database Setup (PostgreSQL)
# Create database and user
sudo -u postgres psql << EOF
CREATE USER orion WITH PASSWORD 'your_secure_password';
CREATE DATABASE orion OWNER orion;
GRANT ALL PRIVILEGES ON DATABASE orion TO orion;
EOF
4. systemd Service
Create /etc/systemd/system/orion.service:
[Unit]
Description=Orion FastAPI Application
After=network.target postgresql.service
[Service]
User=deploy
Group=deploy
WorkingDirectory=/var/www/orion
Environment="PATH=/var/www/orion/.venv/bin"
EnvironmentFile=/var/www/orion/.env
ExecStart=/var/www/orion/.venv/bin/uvicorn app.main:app --host 127.0.0.1 --port 8000 --workers 4
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
Enable the service:
sudo systemctl daemon-reload
sudo systemctl enable orion
5. Nginx Configuration
Create /etc/nginx/sites-available/orion:
server {
listen 80;
server_name yourdomain.com www.yourdomain.com;
# Static files
location /static/ {
alias /var/www/orion/static/;
expires 30d;
add_header Cache-Control "public, immutable";
}
# Media/uploads
location /uploads/ {
alias /var/www/orion/uploads/;
expires 7d;
}
# Proxy to FastAPI
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;
proxy_read_timeout 300;
proxy_connect_timeout 300;
}
}
Enable the site:
sudo ln -s /etc/nginx/sites-available/orion /etc/nginx/sites-enabled/
sudo rm /etc/nginx/sites-enabled/default # Remove default site
sudo nginx -t
sudo systemctl restart nginx
6. HTTPS with Let's Encrypt
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com
Certbot will automatically configure HTTPS and set up auto-renewal.
7. Firewall Configuration
sudo ufw allow OpenSSH
sudo ufw allow 'Nginx Full'
sudo ufw enable
8. GitLab CI/CD Pipeline
Create .gitlab-ci.yml in your project root:
stages:
- test
- build
- deploy
variables:
PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"
UV_CACHE_DIR: "$CI_PROJECT_DIR/.cache/uv"
# Test stage
test:
stage: test
image: python:3.11
before_script:
- pip install uv
- uv venv
- source .venv/bin/activate
- uv pip install -r requirements.txt
script:
- python -m pytest tests/ -v --tb=short
only:
- merge_requests
- main
# Build Tailwind CSS
build:
stage: build
image: node:20
script:
- npm install
- npx tailwindcss -i ./static/src/input.css -o ./static/dist/output.css --minify
artifacts:
paths:
- static/dist/
expire_in: 1 week
only:
- main
# Deploy to production
deploy:
stage: deploy
image: alpine:latest
before_script:
- apk add --no-cache openssh-client rsync
- mkdir -p ~/.ssh
- echo "$SSH_PRIVATE_KEY" | tr -d '\r' > ~/.ssh/id_ed25519
- chmod 600 ~/.ssh/id_ed25519
- ssh-keyscan -H $SERVER_HOST >> ~/.ssh/known_hosts
script:
# Sync files to server (excluding sensitive files)
- rsync -avz --delete
--exclude='.git'
--exclude='.env'
--exclude='*.pyc'
--exclude='__pycache__'
--exclude='.pytest_cache'
--exclude='htmlcov'
--exclude='*.db'
./ $SERVER_USER@$SERVER_HOST:$SERVER_PATH/
# Install dependencies and run migrations
- ssh $SERVER_USER@$SERVER_HOST "
cd $SERVER_PATH &&
~/.cargo/bin/uv venv --python 3.11 &&
source .venv/bin/activate &&
~/.cargo/bin/uv pip install -r requirements.txt &&
python -m alembic upgrade head
"
# Restart the service
- ssh $SERVER_USER@$SERVER_HOST "sudo systemctl restart orion"
# Verify deployment
- ssh $SERVER_USER@$SERVER_HOST "sudo systemctl status orion --no-pager"
only:
- main
environment:
name: production
url: https://yourdomain.com
9. GitLab CI/CD Variables
Configure these in Settings > CI/CD > Variables:
| Variable | Description | Example |
|---|---|---|
SSH_PRIVATE_KEY |
Private key for server access | -----BEGIN OPENSSH PRIVATE KEY-----... |
SERVER_USER |
SSH user on server | deploy |
SERVER_HOST |
Server IP or hostname | 203.0.113.50 |
SERVER_PATH |
Application directory | /var/www/orion |
Mark SSH_PRIVATE_KEY as Protected and Masked.
10. Environment Variables
Create /var/www/orion/.env on the server:
# Application
APP_ENV=production
DEBUG=false
SECRET_KEY=your-super-secret-key-change-this
# Database
DATABASE_URL=postgresql://orion:password@localhost:5432/orion
# Stripe (if using billing)
STRIPE_SECRET_KEY=sk_live_...
STRIPE_WEBHOOK_SECRET=whsec_...
# Email
SMTP_HOST=smtp.your-provider.com
SMTP_PORT=587
SMTP_USER=your-email@domain.com
SMTP_PASSWORD=your-smtp-password
EMAILS_FROM=noreply@yourdomain.com
# Letzshop Integration (if applicable)
LETZSHOP_API_URL=https://api.letzshop.lu
Secure the file:
chmod 600 /var/www/orion/.env
11. Deployment Flow
- Developer pushes to
mainbranch - GitLab runs tests
- GitLab builds Tailwind CSS
- GitLab syncs files to server via rsync
- Server installs/updates Python dependencies
- Alembic runs database migrations
- systemd restarts the FastAPI service
- Nginx serves the application over HTTPS
12. Maintenance Commands
# View application logs
sudo journalctl -u orion -f
# Restart application
sudo systemctl restart orion
# Check application status
sudo systemctl status orion
# Run migrations manually
cd /var/www/orion
source .venv/bin/activate
python -m alembic upgrade head
# Rollback migration
python -m alembic downgrade -1
13. Security Recommendations
- Use a non-root deploy user (as shown above)
- Enable fail2ban for SSH protection
- Configure PostgreSQL to only allow local connections
- Set up automated backups for the database
- Enable log rotation
- Consider using Docker for isolation
- Set up monitoring (e.g., Prometheus + Grafana)
- Configure rate limiting in Nginx
14. Troubleshooting
Application won't start
# Check logs
sudo journalctl -u orion -n 100
# Verify environment file
cat /var/www/orion/.env
# Test manually
cd /var/www/orion
source .venv/bin/activate
uvicorn app.main:app --host 127.0.0.1 --port 8000
Database connection issues
# Test PostgreSQL connection
psql -U orion -h localhost -d orion
# Check PostgreSQL status
sudo systemctl status postgresql
Nginx errors
# Test configuration
sudo nginx -t
# Check error logs
sudo tail -f /var/log/nginx/error.log