Skip to content

Deployment Guide

This guide documents the actual current production path in the repo. For the step-by-step operator procedure, see Deploy Runbook.

Current Production Topology

                   ┌─────────────────────────────────┐
                   │ Cloudflare Pages                │
                   │ qgtmai.com                      │
                   │ project: qgtm-trading          │
                   └──────────────┬──────────────────┘
                                  │ HTTPS
                   ┌─────────────────────────────────┐
                   │ DigitalOcean Droplet            │
                   │ 142.93.1.195                    │
                   │ /opt/trading                    │
                   │ systemd + Docker Compose        │
                   ├─────────────────────────────────┤
                   │ qgtm-api.service                │
                   │ qgtm-daemon.service             │
                   │ qgtm-redis.service              │
                   └─────────────────────────────────┘

                   Docs deploy separately to Cloudflare Pages
                   project: qgtm-docs

What Deploys Where

Surface Current path Source of truth
Terminal web app Cloudflare Pages project qgtm-trading .github/workflows/deploy.yml
API DigitalOcean droplet via SSH deploy .github/workflows/deploy.yml
Daemon Restarted on the droplet during API deploy .github/workflows/deploy.yml + infra/systemd/qgtm-daemon.service
Redis Docker/systemd on the droplet infra/systemd/qgtm-redis.service
Docs Cloudflare Pages project qgtm-docs .github/workflows/deploy-docs.yml
Release artifacts GitHub Releases with SBOM + signing .github/workflows/release.yml

CI / CD Behavior

CI

ci.yml handles linting, tests, coverage, and SBOM/security scan on pushes and pull requests to main.

Production deploy

deploy.yml is the production deploy workflow:

  1. detect whether web and/or API-relevant files changed
  2. build qgtm_web and deploy out/ to Cloudflare Pages project qgtm-trading
  3. SSH to the DigitalOcean droplet
  4. git fetch + git reset --hard origin/main inside /opt/trading
  5. refresh selected .env values from GitHub secrets when present
  6. reinstall the package into the droplet virtualenv
  7. restart qgtm-api and then qgtm-daemon
  8. verify /health; rollback to the previous commit if the health check fails

Release engineering

release.yml is not the production deploy path. It builds artifacts, runs tests, generates SBOMs, signs outputs, and publishes a GitHub Release on tags.

Runtime Services

The droplet uses systemd units that wrap Docker Compose:

  • infra/systemd/qgtm-api.service
  • infra/systemd/qgtm-daemon.service
  • infra/systemd/qgtm-redis.service

The compose file referenced by those units lives on the server at /opt/trading/docker-compose.prod.yml.

Verification Targets

After a production deploy, the minimum checks are:

  • https://qgtmai.com
  • https://api.qgtmai.com/health
  • https://api.qgtmai.com/api/v1/market-data/bars/GLD?limit=5
  • https://api.qgtmai.com/api/v1/forecast/gold

If the API health check fails during deploy, the workflow already performs a commit-level rollback on the droplet.

Legacy / Non-Canonical Surfaces

The repo still contains references to older or alternate infrastructure such as Fly.io, Neon, Upstash, Doppler, Terraform, and k8s manifests. Treat those as historical, experimental, or future-state assets unless they are explicitly reintroduced into the active deploy workflows.