Add wiki page: Deployment-Guide
@@ -0,0 +1,295 @@
|
|||||||
|
# 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
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://git.undiamagico.es/kitos/Aegis
|
||||||
|
cd Aegis
|
||||||
|
cp .env.example .env
|
||||||
|
# Edit .env with your settings
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Start services
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
This starts all services:
|
||||||
|
- Backend API: http://localhost:8000
|
||||||
|
- Frontend: http://localhost:5173
|
||||||
|
- Swagger UI: http://localhost:8000/docs
|
||||||
|
- ReDoc: http://localhost:8000/redoc
|
||||||
|
- MinIO Console: http://localhost:9001
|
||||||
|
- PostgreSQL: localhost:5433
|
||||||
|
|
||||||
|
### 3. Verify
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl http://localhost:8000/health
|
||||||
|
# {"status": "ok"}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. First login
|
||||||
|
|
||||||
|
Default admin credentials are set via `ADMIN_USERNAME` and `ADMIN_PASSWORD` in `.env`.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST http://localhost:8000/api/v1/auth/login \
|
||||||
|
-d "username=admin&password=yourpassword" \
|
||||||
|
-c cookies.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Production Deployment
|
||||||
|
|
||||||
|
### 1. Prepare server
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 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
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose -f docker-compose.prod.yml up -d --build
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Verify
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose -f docker-compose.prod.yml ps
|
||||||
|
# All services should show "healthy" or "running"
|
||||||
|
|
||||||
|
curl http://localhost:8000/health
|
||||||
|
# {"status": "ok"}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Update
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git pull
|
||||||
|
docker compose -f docker-compose.prod.yml up -d --build
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Required Environment Variables
|
||||||
|
|
||||||
|
Create a `.env` file at the project root:
|
||||||
|
|
||||||
|
```env
|
||||||
|
# ─── 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
|
||||||
|
|
||||||
|
```bash
|
||||||
|
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`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
#!/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):
|
||||||
|
```bash
|
||||||
|
docker compose exec aegis-backend alembic upgrade head
|
||||||
|
```
|
||||||
|
|
||||||
|
**Create a new migration** (development):
|
||||||
|
```bash
|
||||||
|
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:**
|
||||||
|
```nginx
|
||||||
|
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
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 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
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check
|
||||||
|
ruff check .
|
||||||
|
|
||||||
|
# Fix auto-fixable issues
|
||||||
|
ruff check . --fix
|
||||||
|
|
||||||
|
# Format
|
||||||
|
ruff format .
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Logs
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 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
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 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)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 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) |
|
||||||
|
|||||||
Reference in New Issue
Block a user