Developer overview
This section is for people working on GantryCD. It’s a map and a set of principles, not a line-by-line reference — for that, each page links into the Reference section, which tracks the implementation in detail.
Tip — start with
CLAUDE.md. The repository’sCLAUDE.mdis the canonical entry point for contributors working in the code. This page is the gentler narrative version.
The four surfaces
GantryCD is one repository producing a few binaries plus a web app:
Web (React SPA)
│ /api/v1/...
▼
┌──────────────────┐ PostgreSQL (source of truth)
│ Backend │ ─────▶ S3 (state/logs/artifacts), Redis, AWS STS, GitHub
│ API + jobs │
└──────────────────┘
▲
│ poll / accept / done
┌──────────────────┐
│ Runner group │ long-lived; launches…
│ + ephemeral │ …ephemeral runners (one per run)
│ runners │
└──────────────────┘
- Backend (
cmd/backend) — the HTTP API, orchestration, and background jobs. - Runner group (
cmd/runner/group/*) — a long-lived coordinator with four launcher variants (local, docker, kubernetes, github). - Ephemeral runner (
cmd/runner/ephemeral) — the real per-run worker. - Web (
web/) — a React SPA, embedded into the backend binary at build time. - Plus the CLI (
cmd/cli,gantrycli) — mostly an HTTP client like Web, plus a small direct-DBoperator/break-glass subtree.
Communication boundaries (non-negotiable)
These are architectural constraints, enforced and assumed everywhere:
- Web → Backend only.
- CLI resource commands (
deployments,stacks,orgs, …) → Backend only, viapkg/sdk— same boundary as Web. - CLI
operator/subtree → PostgreSQL directly (documented break-glass exception; bypasses HTTP authz, only safe with database credentials). - Runner group / ephemeral runner → Backend only.
- Backend → PostgreSQL, Redis, S3, AWS STS, GitHub.
Runners never talk to the web app, to each other, or directly to the database. If you find yourself wanting a new edge in that graph, you’re solving the problem in the wrong place.
Package layout
| Path | What lives there |
|---|---|
cmd/ | Entry points and wiring (backend, runner group launchers, ephemeral runner, CLI). |
internal/backend/ | The backend’s guts: handlers, services, repositories, db, middleware, scm, sso, jobs. |
internal/authz/ | Hot-path authorization — three SQL queries, no service layer. |
internal/runner/ | Shared runner-group and ephemeral-runner logic. |
internal/clients/ | Outbound client wrappers (aws, gcp, github). |
pkg/domain/ | Entities, validation, typed errors — the vocabulary. |
pkg/contracts/ | Backend↔runner wire types, notably RunContext. |
pkg/extensions/ | The pluggable extension points (e.g. runner-group types). |
pkg/sdk/ | The Go API client, shared by the CLI and the Terraform provider. |
schema/ | Declarative database schema (Atlas). |
migrations/ | Data-only migrations (seeds, backfills) — never schema DDL. |
How to navigate by question
| You’re asking… | Read |
|---|---|
| How is a request handled? | Backend internals |
| How does a deployment progress / a run get executed? | Execution model |
| How do I add an SCM / cloud / runner / SSO integration? | Extending GantryCD |
| How do I build, test, and change the schema? | Contributing |
For depth on any topic, the Reference section has the detailed implementation doc.