os.getenv() fallback and the .env / tfvars template that ships
alongside it.
For the detailed treatment of a surface — startup validation order, footguns, and
the exact code path that reads each value — follow the per-service links:
Gateway env vars ·
Dashboard build & config ·
Drone OS services ·
AWS environments & Terraform.
This page is the flat, copy-pasteable index across all of them.
The four config surfaces
Default mismatches you must reconcile
The single most common source of “works in dev, breaks in prod” is a Python fallback insettings.py that disagrees with the value shipped in the env template or baked into the
production task definition. These are the known divergences:
Gateway Service (skyhub_gateway_service)
Every constant below is defined in src/application/settings.py unless noted. Defaults
shown are the Python os.getenv() fallback. Secrets are redacted — supply real values
via .env (local) or SSM (prod).
Deployment & environment
Deployment & environment
IS_LOCAL_ENVIRONMENT is derived (DEPLOYMENT_ENVIRONMENT == "local"), not a raw
env var. Note DEPLOYMENT_ENVIRONMENT (local/server) and APP_ENVIRONMENT (dev/production)
are two different switches — see Startup & validation.Database (PostgreSQL)
Database (PostgreSQL)
Assembled into
postgresql://… in src/connector/db_connection.py. See
Migrations & DB connection and the
Database schema reference.Authentication & JWT
Authentication & JWT
AWS & cloud identity
AWS & cloud identity
VPN & network CIDRs
VPN & network CIDRs
The
10.71.* trust and jumphost routing are covered in
VPN middleware & jumphost and
Network topology.Jumphost & rosbridge connection
Jumphost & rosbridge connection
See Rosbridge connection.
Socket.IO
Socket.IO
Docker & SITL orchestration
Docker & SITL orchestration
Full container lifecycle: SITL lifecycle and
Gateway build & runtime.
SITL default ArduPilot parameters
SITL default ArduPilot parameters
Applied to every newly created SITL drone (fence + battery + logging defaults).
Video (Janus / WHIP)
Video (Janus / WHIP)
See Janus video rooms.
Observability (OpenTelemetry / SigNoz)
Observability (OpenTelemetry / SigNoz)
Billing (Stripe)
Billing (Stripe)
Email (SMTP)
Email (SMTP)
MAIL_* and APP_ENVIRONMENT bypass settings.py (read via os.getenv directly) — easy
to miss when auditing configuration.Container / entrypoint-only (build & deploy)
Container / entrypoint-only (build & deploy)
These are consumed by
containers/docker-entrypoint.sh or docker-compose.yml — not
by settings.py. See Gateway build & runtime.Dashboard (skyhub_dashboard)
The Angular SPA has no runtime env vars — configuration is a TypeScript object in
src/environments/environment*.ts, and angular.json swaps one file in at build time via
fileReplacements. Change a value → rebuild and redeploy. The five files and the build
configuration that selects each:
Keys and per-environment values
environment.ts is the dev default (production: false) yet it already carries the
live Stripe key and the prod Janus / ws_proxy / assets URLs — only its url
points at localhost. environment.e2e.ts deliberately targets the real production API
(https://prod.skyhub.ai:5000), so Playwright smoke runs hit prod. Full build/deploy
detail: Dashboard build & config ·
App state & video.SkyCore Drone OS (skyhub_core)
The on-drone stack is a docker-compose microservice bundle configured through a single
.env (template .env.example). Every value uses the ${VAR:-default} pattern, so unset
vars fall back to the compose default. COMPOSE_PROFILES decides which containers even
start. Below are the load-bearing groups; see Drone OS services for
the exhaustive per-module treatment.
- Profiles & identity
- Camera & video
- RTK NTRIP
- Agent half & guided control
- ArUco landing
core and gamepad are no longer profiles — they are the two halves of the single skyhub
service, selected by SKYHUB_ROLE. The camera and slam profiles went with the
camera-proxy and isaac-slam containers.IP_OVERRIDE is central to the Redis message bus — see
Redis message bus and
Redis channels & MAVLink port map.AWS infrastructure (skyhub_terraform)
Terraform inputs live in environments/<env>/inputs.tf (declarations) and are set per
environment in environments/prod/settings.tfvars (prod) — dev supplies values on the CLI.
Applied with terraform apply -var-file=settings.tfvars.
The provisioned topology (ECS Fargate on
172.31.0.0/16, the single t4g.nano WireGuard
jumphost at public <prod-ingress-ip>, self-hosted Postgres/Redis) is described in
AWS environments & state and
Production config. Prod ingress is nginx running on that
t4g.nano WireGuard EC2, acting as a TLS-terminating reverse proxy in front of the ECS
services — there is no Cloudflare tunnel or ALB/ELB in prod. GATEWAY_CLOUDFLARE_PORT
/ 2053 is only a local/optional dev-compose artifact and is not used in production.
Secrets hygiene
Related references
Gateway env vars (detailed)
Startup validation order, footguns, and the code path reading each gateway value.
Dashboard build & config
The five Angular environment files, build configurations, and CI/deploy flow.
Drone OS services
On-drone container profiles and how
COMPOSE_PROFILES selects them.Environments & Terraform state
tfvars, remote state, and the prod/dev environment split.
HTTP & Socket.IO API reference
Full endpoint and event reference for the gateway.
Redis channels & MAVLink ports
Where
IP_OVERRIDE, ports, and channel naming come together.
