| 1 | # Deployment (AI Agent View) |
| 2 | |
| 3 | Source of truth: `docker-compose.yml`. |
| 4 | |
| 5 | ## Runtime Services |
| 6 | |
| 7 | | Service | Compose Name | Purpose | Exposed Ports | Persistent Storage | |
| 8 | |---|---|---|---|---| |
| 9 | | Backend API | `copilot-backend` | FastAPI app (`/api/*`) | `5000:5000` | `./data/copilot-backend-data/logs:/opt/logs`, `./data/data:/opt/copilot/backend/data` | |
| 10 | | Frontend (Nginx) | `copilot-frontend` | UI + TLS termination + reverse proxy to backend | `80:80`, `443:443` | none by default | |
| 11 | | MySQL | `copilot-mysql` | Primary relational DB | `3306:3306` | named volume `mysql-data:/var/lib/mysql` | |
| 12 | | MinIO | `copilot-minio` | Object storage for case/artifact files | `9000:9000` (S3 API), container also uses `9001` console | `./data/data/minio-data:/data` | |
| 13 | | Nuclei module | `copilot-nuclei-module` | External module container | none | none | |
| 14 | | MCP service | `copilot-mcp` | MCP/OpenAI-adjacent service + optional subservers | none exposed by compose | `./data/copilot-mcp/api.config.yaml:/app/velociraptor-config.yaml:ro` | |
| 15 | | Customer portal (optional) | `copilot-customer-portal` | Separate customer-facing UI | example `8443:443` (commented) | none by default | |
| 16 | |
| 17 | ## Networking and Request Path |
| 18 | |
| 19 | - Browser -> `copilot-frontend` :443 |
| 20 | - `copilot-frontend` proxies `/api` to `http://copilot-backend:5000` (see `frontend/build/etc/nginx/sites-enabled/default.conf`) |
| 21 | - Backend connects internally to: |
| 22 | - MySQL via env (`MYSQL_URL`, defaults to `copilot-mysql`) |
| 23 | - MinIO via env (`MINIO_URL`, defaults to `copilot-minio`) |
| 24 | |
| 25 | ## Environment Variable Overview |
| 26 | |
| 27 | Primary env file: `.env` (template: `.env.example`). |
| 28 | |
| 29 | - Core runtime: |
| 30 | - `SERVER_IP`, `SERVER_HOST` |
| 31 | - MySQL: |
| 32 | - `MYSQL_URL`, `MYSQL_ROOT_PASSWORD`, `MYSQL_USER`, `MYSQL_PASSWORD`, `MYSQL_DATABASE` |
| 33 | - MinIO: |
| 34 | - `MINIO_URL`, `MINIO_ROOT_USER`, `MINIO_ROOT_PASSWORD`, `MINIO_SECURE` |
| 35 | - Connector bootstrap values: |
| 36 | - e.g. `WAZUH_INDEXER_URL`, `GRAYLOG_URL`, `GRAFANA_URL`, etc. (loaded in `backend/app/db/db_populate.py`) |
| 37 | - Header/shared-secret style values: |
| 38 | - `GRAYLOG_API_HEADER_VALUE`, `VELOCIRAPTOR_API_HEADER_VALUE` |
| 39 | - MCP/OpenAI values: |
| 40 | - `OPENAI_API_KEY`, `OPENAI_MODEL`, `MCP_*`, `OPENSEARCH_*`, `WAZUH_PROD_*`, `VELOCIRAPTOR_*` |
| 41 | |
| 42 | ## TLS |
| 43 | |
| 44 | Frontend TLS behavior is implemented in: |
| 45 | - `frontend/build/docker-entrypoint.d/90-copilot-ssl.sh` |
| 46 | - `frontend/build/etc/nginx/sites-enabled/default.conf` |
| 47 | |
| 48 | Behavior: |
| 49 | - If `TLS_CERT_PATH`/`TLS_KEY_PATH` files exist, Nginx uses them. |
| 50 | - If missing, startup script auto-generates self-signed certs (365 days). |
| 51 | - Port 80 redirects to HTTPS (443). |
| 52 | |
| 53 | ## Persistence Model |
| 54 | |
| 55 | - MySQL durable data: |
| 56 | - Docker named volume `mysql-data`. |
| 57 | - MinIO durable objects: |
| 58 | - Host path `./data/data/minio-data`. |
| 59 | - Backend local files/logs: |
| 60 | - Host paths under `./data/...` bind-mounted into backend. |
| 61 | - Buckets auto-created at startup: |
| 62 | - See `backend/app/data_store/data_store_setup.py` (`copilot-cases`, `copilot-case-report-templates`, `sysmon-configs`, `velociraptor-artifacts`). |
| 63 | |
| 64 | ## Startup Initialization Hooks (Deployment-Relevant) |
| 65 | |
| 66 | `backend/copilot.py` startup event performs: |
| 67 | - DB creation/user bootstrap in production |
| 68 | - Alembic migrations (`backend/app/db/db_setup.py`) |
| 69 | - MinIO bucket creation |
| 70 | - connector + integration seed data |
| 71 | - admin/scheduler user ensure |
| 72 | - scheduler init/start |
| 73 | |
| 74 | If deployment seems healthy but features fail, validate this startup chain first. |