Skip to main content

Production Deployment

Infrastructure

ComponentDetails
App Server77.42.82.4 (Ubuntu 22.04)
LXD Server65.109.236.163
Frontendhttps://mvp.zafarsaidov.uz
APIhttps://mvp-api.zafarsaidov.uz
DNS/SSLCloudflare (proxy + flexible SSL)

Quick Deploy (Existing Server)

make deploy
# Equivalent to: git pull → docker-compose build → migrate → smoke test

Or manually:

ssh -i private_key [email protected]
cd /opt/platform-v2
./scripts/deploy.sh

First-Time Server Setup

1. Install Dependencies

ssh [email protected]

apt update && apt upgrade -y

# Docker
curl -fsSL https://get.docker.com | sh
apt install -y docker-compose git

# Firewall
ufw allow 22/tcp
ufw allow 80/tcp
ufw allow 443/tcp
ufw enable

2. Clone the Repository

cd /opt
git clone [email protected]:zsaidov1988/educenter-platform.git platform-v2
cd platform-v2

3. Configure Environment

cp backend/.env.example backend/.env
nano backend/.env

Critical values to set:

SECRET_KEY=$(python3 -c "import secrets; print(secrets.token_urlsafe(32))")
ADMIN_PASSWORD=<strong-password>
DATABASE_URL=postgresql+asyncpg://platform:<db-password>@postgres:5432/platform
CORS_ORIGINS=https://mvp.zafarsaidov.uz
LXD_ENDPOINT=https://10.0.0.3:8443
LXD_SSH_JUMP_HOST=65.109.236.163
LESSONS_REPO_URL=[email protected]:zsaidov1988/lessons-content.git

4. Place Secrets

# LXD TLS certificates
mkdir -p backend/.lxd
# Copy client.crt and client.key from LXD server setup

# SSH key for LXD server access and lessons repo
cp private_key backend/private_key
chmod 600 backend/private_key

5. Deploy

docker-compose -f docker-compose.prod.yml up -d --build
docker-compose -f docker-compose.prod.yml exec backend alembic upgrade head
docker-compose -f docker-compose.prod.yml exec backend python -m app.db.init_db

6. Verify

# Check containers
docker-compose -f docker-compose.prod.yml ps

# Health check
curl https://mvp-api.zafarsaidov.uz/health

# Run smoke tests
make smoke-test

Updating the Application

# From your local machine:
make deploy

# Or on the server directly:
cd /opt/platform-v2
git pull
docker-compose -f docker-compose.prod.yml up -d --build
docker-compose -f docker-compose.prod.yml exec backend alembic upgrade head

Monitoring

Logs

make prod-logs          # Tail all production logs
make prod-logs-backend # Backend only

# On the server:
docker-compose -f docker-compose.prod.yml logs -f backend
docker-compose -f docker-compose.prod.yml logs -f nginx

Container Status

docker-compose -f docker-compose.prod.yml ps   # Docker containers
make lxd-list # LXD containers

Restart Services

docker-compose -f docker-compose.prod.yml restart backend
docker-compose -f docker-compose.prod.yml restart nginx

Troubleshooting

Backend not connecting to LXD

make lxd-check
ls -la backend/.lxd/ # Certificates present?

WebSocket terminal not connecting

  1. Verify container is running: make lxd-list
  2. Check token is in WebSocket URL: /ws/terminal/{id}?token={jwt}
  3. Review backend logs for SSH errors

SSL/HTTPS issues

  1. Verify DNS records point to 77.42.82.4
  2. Check Cloudflare SSL/TLS setting is "Flexible" or "Full"
  3. Ensure Cloudflare proxy is enabled (orange cloud icon)

Container creation failing

ssh -i private_key [email protected] "lxc list"
# Check available resources:
df -h && free -h

Security Checklist

  • Changed default ADMIN_PASSWORD
  • Generated strong SECRET_KEY
  • Firewall configured (UFW: 22, 80, 443 only)
  • SSH key authentication only (no password auth)
  • LXD certificates in place and not committed to git
  • private_key not committed to git (in .gitignore)
  • HTTPS enabled via Cloudflare
  • Regular apt update && apt upgrade scheduled