Raven Zero Logo RAVEN ZERO

Deployment

🐳 Docker Deployment

docker-compose.yml

services:
  app:
    build: .
    expose:
      - 8000
    environment:
      - REDIS_URL=redis://valkey:6379/0
    volumes:
      - ./logs:/app/logs
      - ./storage:/app/storage  # Persist encrypted files
    depends_on:
      - valkey
    restart: on-failure
    networks:
      - raven-net

  valkey:
    image: valkey/valkey:9-alpine
    expose:
      - 6379
    networks:
      - raven-net

networks:
  raven-net:
    driver: bridge

Dockerfile

FROM ghcr.io/astral-sh/uv:python3.13-bookworm-slim

WORKDIR /app

COPY pyproject.toml uv.lock ./
RUN uv sync --frozen --no-dev

COPY . .
RUN apt-get update && apt-get install -y libmagic1 && rm -rf /var/lib/apt/lists/*

EXPOSE 8000
CMD ["uv", "run", "fastapi", "run", "app/main.py"]

🔧 Configuration

Environment Variables

VariableDefaultDescription
REDIS_URLredis://localhost:6379/0Redis connection URL
STORAGE_PATH./storage/uploadsFile storage directory
TEMP_PATH./storage/tempTemporary files directory
MAX_FILE_SIZE10485760 (10MB)Maximum upload size
ALLOWED_MIME_TYPES[] (all allowed)Whitelist of MIME types
UPLOAD_RATE_LIMIT30/hourRate limit for uploads
HEALTH_RATE_LIMIT1/secondRate limit for health checks
DOWNLOAD_FAIL_LIMIT10Failures before IP block
DOWNLOAD_BLOCK_WINDOW1800Block duration (seconds)
CLEANUP_INTERVAL_MINUTES10Orphan cleanup interval
ORPHAN_AGE_MINUTES15Age before orphan deletion
SECURE_SHRED_PASSES1Byte overwrite passes
DICEWARE_WORDLIST_PATHdata/diceware_words.txtPath to wordlist

📊 Observability

Structured Logging

All logs are JSON formatted via structlog:

{
  "event": "file_upload_started",
  "request_id": "abc123-...",
  "method": "POST",
  "path": "/upload/",
  "timestamp": "2024-12-10T15:30:00Z",
  "level": "info"
}

Fields included:

  • timestamp (ISO8601)
  • level (INFO, WARNING, ERROR)
  • request_id (UUID per request)
  • method, path, status_code, duration

Log Files

  • Location: ./logs/raven_zero.log
  • Rotation: 10MB max, 5 backups
  • Format: JSON lines

Health Check

GET /health/ returns:

{
  "status": "healthy",
  "version": "0.1.0",
  "timestamp": "2024-12-10T15:50:00Z",
  "services": {
    "redis": "online",
    "storage": "online",
    "scheduler": "online",
    "diceware": "online"
  },
  "uptime_seconds": 3600,
  "started_at": "2024-12-10T14:50:00Z"
}

🔄 Restart & Failure Modes

ScenarioData LossRecoveryUser Impact
Graceful restartAll active uploads2-5 secIn-flight complete, uploads lost
Crash (hard kill)All active uploads5-10 secOrphans cleaned on startup
Redis crashAll metadata1-2 secBrief outage, service recovers
Disk fullNone (fails safely)ImmediateUploads fail with clear error

Key principle: Ephemeral by design means restarts clearing data is expected, not a bug.


📊 Performance Expectations

MetricTargetHardware
Upload latency (p95)< 500ms4-core, 8GB RAM
Download latency< 100msSame
Redis operations< 10msSame
Concurrent uploads50+Same

Scale Capacity

  • 100 uploads/day: Easy
  • 1,000 uploads/day: Comfortable
  • 10,000 uploads/day: With tuning

When to scale: Measure first (logs/metrics), identify bottleneck, optimize.