Quick Start¶
The one page to get a development instance of Cortex running, reachable from your LAN, with an admin user and a first API key. Production is a separate, shorter procedure: Production deployment.
1. Prerequisites¶
- Linux host (Ubuntu 22.04/24.04 or RHEL 9 family), Docker Engine 24+ with the compose plugin,
GNU make,
curl,jq. - For GPU models: NVIDIA driver (>= 580 for the default vLLM image, >= 550 for llama.cpp and
the
-cu129vLLM build) and the NVIDIA Container Toolkit. Verify withdocker run --rm --gpus all nvidia/cuda:12.8.0-base-ubuntu22.04 nvidia-smi. - Directories for model files, the HF cache and exports (defaults shown; change them in
.env):
sudo mkdir -p /var/cortex/models /var/cortex/hf-cache /var/cortex/exports
sudo chown -R 1000:1000 /var/cortex # the gateway runs as uid 1000 inside its container
sudo apt-get install -y make docker.io docker-compose-plugin curl jq # Debian/Ubuntu
sudo usermod -aG docker $USER && newgrp docker
2. Start¶
git clone <repo> Cortex && cd Cortex
cp .env.example .env # optional: paths and ports
make quick-start # = make build + make up; asks for the admin username/password once
make up exports versions.env (pinned images), detects the host IP for CORS, and enables
the linux/gpu monitoring profiles automatically. The output ends with the URLs:
Admin UI: http://192.168.1.50:3001/login
Gateway: http://192.168.1.50:8084
Prometheus: http://192.168.1.50:19090
Use the host IP, not localhost, from other devices. make ip prints it again.
Without make (standalone compose):
set -a; . ./versions.env; set +a
HOST_IP=$(bash scripts/detect-ip.sh) docker compose -f docker.compose.dev.yaml up -d --build
3. First login and API key¶
- Open
http://<HOST_IP>:3001/loginand sign in with the username and password you typed duringmake quick-start(stored in.envasADMIN_BOOTSTRAP_*, mode 600; the account is created on an empty database).make setup-adminchanges them at any time, also on a running system;LOGOUT_ALL=1 make setup-adminadditionally signs out every session. - Non-interactive installs: put
ADMIN_BOOTSTRAP_USERNAME/ADMIN_BOOTSTRAP_PASSWORDin.env(or exportSETUP_ADMIN_USERNAME/SETUP_ADMIN_PASSWORD) beforemake up. - API Keys → Create key (scopes
chat,completions,embeddings). Copy it; it is shown once.
Or from a shell: make login && make create-key.
curl -H "Authorization: Bearer $KEY" http://<HOST_IP>:8084/v1/models
The dev stack sets GATEWAY_DEV_ALLOW_ALL_KEYS=true, so any bearer token is accepted on
/v1 for local experiments. Production turns this off.
4. Add a model¶
Put the weights under /var/cortex/models/<folder> (see
HuggingFace download), then Models → Add model:
- GGUF file → engine
llamacpp(guide); - safetensors / HF checkpoint → engine
vllm(guide); - pick the GPUs, keep the defaults, Dry-run, Start.
The row shows loading until the engine answers /health, then running; a failure shows
failed with a state_reason. Model containers keep running across gateway restarts and
reboots are covered in the runbooks.
Test in Chat → Playground, or:
curl -H "Authorization: Bearer $KEY" -H 'Content-Type: application/json' \
http://<HOST_IP>:8084/v1/chat/completions \
-d '{"model":"<served name>","messages":[{"role":"user","content":"Hello!"}]}'
5. Verify¶
make validate # IP detection, CORS, listeners, firewall
make health # gateway /health, containers, Prometheus and exporters
make test-backend # unit tests inside the gateway container
6. Network access, CORS and firewall¶
The gateway uses host networking (0.0.0.0:8084); the UI is published on 3001. Browser
origins allowed to call the API with cookies come from CORS_ALLOW_ORIGINS; make up builds
it from the detected host IP, and the entrypoint adds the IP it detects when the list is
localhost-only. If your IP changes, make restart. To force an IP: HOST_IP=10.0.0.5 make up
or HOST_IP=... in .env.
Ports to allow on the host firewall for LAN access:
sudo ufw allow from 192.168.0.0/16 to any port 3001 proto tcp comment 'Cortex UI'
sudo ufw allow from 192.168.0.0/16 to any port 8084 proto tcp comment 'Cortex API'
sudo ufw reload
Containers on the same host reach the API at http://host.docker.internal:8084 (add
extra_hosts: ["host.docker.internal:host-gateway"]); with UFW active run
make setup-firewall once so Docker bridge subnets may reach the host. Diagnose with
make test-external-access. Model engines listen on 127.0.0.1 only and are never reachable
from the LAN. Details: Network access.
7. Monitoring¶
Prometheus scrapes the gateway, node-exporter, cAdvisor, DCGM and every running model
container (discovered by Docker label). make monitoring-status lists the targets; the
System Monitor page shows host, GPU and per-model metrics. Prometheus defaults to port
19090 on the host (avoids Cockpit on 9090). See Observability.
8. Everyday commands¶
make help # everything
make logs SERVICE=gateway # follow one service
make logs-models # tail every model container
make down / make up # stop / start the stack (model containers survive)
make clean-models # remove all model containers
make db-backup # pg_dump to backups/
make versions # pinned images from every source
Next: Configuration, Model management, Production deployment, Offline deployment.