2
Deployment-Guide
kitos edited this page 2026-05-22 12:33:09 +00:00

Deployment Guide

This guide covers deploying Aegis in both development and production environments.


Prerequisites

Requirement Version Notes
Docker 24+ Required
Docker Compose v2 (plugin) docker compose (not docker-compose)
Git Any For pulling updates
4GB RAM Minimum 8GB recommended for production
20GB disk Minimum For database + evidence files

Development Setup

1. Clone and configure

git clone https://git.undiamagico.es/kitos/Aegis
cd Aegis
cp .env.example .env
# Edit .env with your settings

2. Start services

docker compose up -d

This starts all services:

3. Verify

curl http://localhost:8000/health
# {"status": "ok"}

4. First login

Default admin credentials are set via ADMIN_USERNAME and ADMIN_PASSWORD in .env.

curl -X POST http://localhost:8000/api/v1/auth/login \
  -d "username=admin&password=yourpassword" \
  -c cookies.txt

Production Deployment

1. Prepare server

# On the server
mkdir -p /opt/aegis
cd /opt/aegis
git clone https://git.undiamagico.es/kitos/Aegis .
cp .env.example .env
# Edit .env — see Required Environment Variables section

2. Deploy

docker compose -f docker-compose.prod.yml up -d --build

3. Verify

docker compose -f docker-compose.prod.yml ps
# All services should show "healthy" or "running"

curl http://localhost:8000/health
# {"status": "ok"}

4. Update

git pull
docker compose -f docker-compose.prod.yml up -d --build

Required Environment Variables

Create a .env file at the project root:

# ─── Database ─────────────────────────────────────────────
DATABASE_URL=postgresql+asyncpg://aegis:strongpassword@aegis-postgres:5432/aegis

# ─── Security ─────────────────────────────────────────────
SECRET_KEY=your-256-bit-random-secret-key-here
ACCESS_TOKEN_EXPIRE_MINUTES=480

# ─── Application ─────────────────────────────────────────
AEGIS_ENV=production          # or "development"
SECURE_COOKIES=auto           # auto | true | false

# ─── First-run Admin ──────────────────────────────────────
ADMIN_USERNAME=admin
ADMIN_PASSWORD=ChangeMe123!   # Must meet password policy

# ─── MinIO (Object Storage) ───────────────────────────────
MINIO_ENDPOINT=aegis-minio:9000
MINIO_ACCESS_KEY=minioadmin
MINIO_SECRET_KEY=minio-secret-key
MINIO_BUCKET=aegis-evidence
MINIO_USE_SSL=false           # true if MinIO behind HTTPS

# ─── Redis ────────────────────────────────────────────────
REDIS_URL=redis://aegis-redis:6379/0

# ─── Optional: Jira Integration ───────────────────────────
# JIRA_URL=https://yourorg.atlassian.net
# JIRA_USERNAME=service-account@yourorg.com
# JIRA_API_TOKEN=your-jira-api-token
# JIRA_PROJECT_KEY=SEC

# ─── Optional: CORS ───────────────────────────────────────
# CORS_ORIGINS=https://aegis.yourcompany.com

Generating SECRET_KEY

python3 -c "import secrets; print(secrets.token_hex(32))"

Database Migrations

Migrations are managed with Alembic and run automatically on container start in production via entrypoint.prod.sh:

#!/bin/bash
# entrypoint.prod.sh
alembic upgrade head
uvicorn app.main:app --host 0.0.0.0 --port 8000 --workers 4

Manual migration (if needed):

docker compose exec aegis-backend alembic upgrade head

Create a new migration (development):

docker compose exec aegis-backend alembic revision --autogenerate -m "add_new_field"

Port Reference

Service Development port Production notes
Backend API 8000 Typically proxied via nginx/Traefik
Frontend 5173 Served as static files via nginx in prod
PostgreSQL 5433 (host) Not exposed in production
MinIO API 9000 Not exposed in production
MinIO Console 9001 Optional admin access
Redis 6379 Not exposed in production

HTTPS / Reverse Proxy

In production, place a reverse proxy (nginx, Traefik, Caddy) in front of Aegis:

nginx example:

server {
    listen 443 ssl;
    server_name aegis.yourcompany.com;

    ssl_certificate /etc/ssl/certs/aegis.crt;
    ssl_certificate_key /etc/ssl/private/aegis.key;

    location /api/ {
        proxy_pass http://localhost:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Proto https;
    }

    location / {
        proxy_pass http://localhost:5173;
        proxy_set_header Host $host;
    }
}

Running Tests

# Full test suite
cd backend && pytest tests/ -v

# Specific module
pytest tests/test_auth.py -v

# With coverage report
pytest tests/ --cov=app --cov-report=html

# Fast (no DB — unit tests only)
pytest tests/ -v -m "not integration"

The test suite has 367+ tests covering all major modules.


Linting

# Check
ruff check .

# Fix auto-fixable issues
ruff check . --fix

# Format
ruff format .

Logs

# Follow backend logs
docker compose logs -f aegis-backend

# All services
docker compose logs -f

# Last 100 lines
docker compose logs --tail=100 aegis-backend

Backup

Database

# Dump
docker compose exec aegis-postgres pg_dump -U aegis aegis > backup_$(date +%Y%m%d).sql

# Restore
docker compose exec -T aegis-postgres psql -U aegis aegis < backup_20240315.sql

Evidence files (MinIO)

# Using mc (MinIO client)
mc mirror myminio/aegis-evidence ./evidence-backup/

Troubleshooting

Issue Solution
Backend fails to start Check SECRET_KEY is set in production
401 on all requests Check SECURE_COOKIES — may be forcing HTTPS on HTTP connection
MinIO errors Verify MINIO_BUCKET exists; check credentials
Migration fails Check DATABASE_URL is correct and DB is reachable
Redis connection refused Verify REDIS_URL and that redis container is running
Swagger not loading Expected in production (AEGIS_ENV=production disables it)