Tower Services¶
Tower Services is the group of small Docker apps that run compute: Drone, Bioacoustic (CEM), DIY LULC, and others. Each service does one job (tree crowns, audio, land cover). They share Airflow and STACD when a job needs orchestration.
The currently deployed nginx paths and GitHub repos are on Deployed Architecture.
Architecture¶
Every Tower Service is interactive in the browser. The operator uses a frontend Docker. From there the app sends compute and polls status. When the run is success, it writes the relevant output into data/. That directory is exposed by FileBrowser, so people can browse and download results in the FileBrowser UI.
Where compute runs is one env var:
AIRFLOW_API_BASE |
Compute |
|---|---|
| Set | Frontend/backend sends the job to the Airflow–STACD Docker, then polls until success or failed. |
| Empty | Compute runs on the local system (in the service container). No Airflow. |
The browser never talks to Airflow. The frontend Docker talks to Airflow–STACD only when AIRFLOW_API_BASE is set.
flowchart LR
Browser[Browser] --> FE[Frontend Docker]
FE -->|AIRFLOW_API_BASE set<br/>trigger + poll| AF[Airflow–STACD Docker]
FE -->|AIRFLOW_API_BASE empty<br/>local compute| Local[Local system]
AF -->|success| Data["data/"]
Local -->|success| Data
Data --> FB[FileBrowser UI]
Browser -.->|view / download output| FB
sequenceDiagram
participant Browser
participant Frontend as Frontend Docker
participant Compute as Airflow–STACD Docker or local system
participant Data as data/
participant FB as FileBrowser UI
Browser->>Frontend: interactive UI
Frontend->>Compute: send compute
loop poll until success or failed
Frontend->>Compute: status
end
Compute-->>Frontend: success
Frontend->>Data: write relevant output
Browser->>FB: browse and download from data/
Supporting pieces on the host: bind-mounts code/ → /app, models/ → /app/models, data/ → /app/data. Logs under data/logs/<application_name>/. Optional central Postgres. Image pulls through the campus proxy.
Shared terminology¶
Use these names in READMEs, .env.example, the runbook, and the checklist. Do not invent aliases.
| Term | Meaning |
|---|---|
| Tower Services | This host and the small compute apps on it (Drone, Bioacoustic, DIY LULC). |
| Service | One Tower app (browser + frontend Docker) that sends compute and writes output to data/. |
| Frontend Docker | The container the browser talks to. Sends compute, polls status, writes data/ on success. |
| Airflow–STACD Docker | Shared orchestrator. Used only when AIRFLOW_API_BASE is set. |
AIRFLOW_API_BASE |
Airflow 2.x REST root, e.g. http://airflow:8080/api/v1. Set → compute in Airflow–STACD Docker. Empty → local compute on this system. |
AIRFLOW_DAG_ID |
DAG this service triggers when AIRFLOW_API_BASE is set. |
CORESTACK_API_BASE |
URL the Airflow worker uses to reach this service (LAN or Docker DNS, not localhost from the worker). |
| Same-origin proxy | Browser talks to the frontend Docker only. That container calls Airflow–STACD. |
| FileBrowser | UI over data/. After a successful run, people view and download outputs here. |
code/ |
Host git checkout. Bind-mount to /app. Update with git pull + restart. |
models/ |
Host model weights. Bind-mount to /app/models. |
data/ |
Host inputs, caches, all compute output. Bind-mount to /app/data. Exposed by FileBrowser. |
| STACD | YAML → Airflow DAG generator. Three files: DAG YAML, Algorithm Repo YAML, Dataset Repo YAML. |
| STAC Item | Required compute output: a STAC 1.x Feature (see runbook §9). |
| Deps-only image | Image has OS/Python deps and an entrypoint only. No application source, models, or outputs. |
| GHCR or Docker Hub | Where you push the deps-only image. Either registry is fine. |
LOG_LEVEL |
debug | info | error. Logs on disk: data/logs/<application_name>/. |
| Central Postgres | Shared cluster database. Connect with DATABASE_URL. No per-service Postgres/SQLite on cluster. |
outputs.yaml |
Declares each tree under data/. Modes: public, private_persistent, delete. |
| Host data service | Cluster process that reads outputs.yaml and publishes, keeps, or deletes. |
Do not use AIRFLOW_BASE_API_URL, AIRFLOW_BASE_URL (unless you only mean the web UI host), COMPUTE_MODE, /data as the data mount, or /models as the models mount. Those names showed up in older notes and are not the contract.
How to prepare docker service to deploy in Tower services cluster¶
Cluster Docker Services is the standards and how-to: why deps-only images, how to write STACD YAML, how to trigger/poll Airflow, STAC Item shape, Custom LULC copy-this example. It is not a tick-box for deploy sign-off.
The runbook is long. You can follow it if you already know:
- Deps-only + three mounts — rebuild the image only when requirements change;
git pullupdatescode/. AIRFLOW_API_BASEis the compute switch — set = Airflow–STACD Docker (trigger + poll); empty = local system.- STACD writes the DAG — you do not hand-write Airflow Python for cluster services. Algorithm YAML is API mode (HTTP work endpoint) or Docker mode (
image+module.function). - The browser never talks to Airflow — browser → frontend Docker → Airflow–STACD (or local compute). On success, output goes to
data/, which FileBrowser exposes. - Deliverable is a STAC Item — not a bare file path or GeoServer layer name.
- Campus
docker pulluses the daemon proxy — see IIT Delhi proxy below.
Then open the runbook in this order: §1–§2 (env + mounts) → §7–§9 (STACD, Airflow, STAC) → Custom LULC example → §3–§6 and §10 as needed.
How to prepare the checklist to deploy in Tower services cluster¶
Cluster Service Checklist is the acceptance list you copy into the GitHub issue. Tick a row only when the Acceptance line is true. It is not a second copy of the how-to. Each item points back to the runbook when you need the procedure.
The checklist is ten acceptance items. It does not re-teach STACD or STAC. Complete it after you understand the architecture on this page and the matching runbook sections.
| Checklist item | Same term as the runbook |
|---|---|
| 1. Mounts | code/, models/, data/ → /app, /app/models, /app/data — runbook §2 |
| 2. Airflow vs local | AIRFLOW_API_BASE set / empty — runbook §8 |
| 3. Registry | GHCR or Docker Hub, deps-only image — runbook §5 |
| 4–10 | SSO, LOG_LEVEL, one container, frontend API base, per-service diagram, central Postgres, outputs.yaml — checklist is the source; runbook §1 / §6 covers env and logging |
Open Cluster Service Checklist
Shared cluster pieces¶
| Piece | Role |
|---|---|
| Airflow + STACD | Orchestration — STACD Framework (dev) |
Install commands stay in each service repository.
Docker pull behind the IIT Delhi proxy¶
Campus hosts often cannot reach GHCR or Docker Hub directly. Configure the Docker daemon proxy. Do not put registry-1.docker.io or auth.docker.io in NO_PROXY.
sudo mkdir -p /etc/systemd/system/docker.service.d
sudo tee /etc/systemd/system/docker.service.d/http-proxy.conf <<'EOF'
[Service]
Environment="HTTP_PROXY=http://proxy21.iitd.ac.in:3128"
Environment="HTTPS_PROXY=http://proxy21.iitd.ac.in:3128"
Environment="NO_PROXY=localhost,127.0.0.1,::1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16"
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
Replace the proxy host with the one for your IITD account category. Same steps: Cluster Docker Services — IIT Delhi proxy.
Adding a service¶
- Read this page (architecture + terms).
- Follow Cluster Docker Services for how to package, wire Airflow/STACD, and return a STAC Item.
- Tick Cluster Service Checklist in the service issue or README.
- Keep install steps, image name, and pinned tag in the service
READMEandVERSION.