# TiDB Labs Architecture

TiDB Labs provides hands-on labs for learning TiDB and distributed SQL. The
platform combines a public frontend, a Django API, async provisioning workers,
and a browser-based SSH proxy so users can move from browsing a lab to using a
live environment.

## System Context

- `frontend/`: user-facing Next.js app for labs, exams, certificates, and
  billing flows.
- `backend/`: Django + DRF API under `/api/`, the staff admin under `/admin/`,
  plus Celery workers for lab creation and teardown.
- `ssh-proxy/`: Go service that upgrades browser WebSocket sessions into SSH
  sessions on lab VMs.
- `deployment/`: Ansible-managed production runtime and Docker Compose
  templates.

![Architecture diagram](./misc/images/labs-architecture.png)

## Production Topology

```text
                         +-----------------------------------------+
                         |             labs service VM              |
Browser                  |  deployment/roles/labs_service/files    |
  |                      |                                         |
  | https://labs.tidb.io |   +----------+         +-------------+  |
  +--------------------->|-->|  nginx   |-- / --->| global FE   |  |
  |                      |   |          |         | Next.js     |  |
  | https://labs.pingcap.com |          |-- / --->| china FE    |  |
  +--------------------->|   |          |         | Next.js     |  |
  | /api (shared)        |   |          |-- /api->| backend     |  |
  +--------------------->|   |          |         | Django/DRF  |  |
  | /admin/ (global)     |   |          |-/admin->|             |  |
  +--------------------->|   |          |         |             |  |
  |                      |   +----------+         +-------------+  |
  |                      |                     +-----------------+ |
  |                      |                     | celery worker   | |
  |                      |                     | celery beat     | |
  |                      |                     +-----------------+ |
                         +-----------------------------------------+
                                      |
                                      v
                        TiDB + Redis + cloud provider APIs
```

## Critical Runtime Paths

### Browser to core app

- Browser traffic lands on nginx and routes to the appropriate frontend, the
  shared Django API, or the Django staff admin.
- The public site is split between the global and China frontends, while the
  API is shared.
- `/admin/` is exposed only on `labs.tidb.io`; unauthenticated staff are sent
  through the frontend login page before Django applies staff and OTP checks.

### Start a lab

```text
POST /api/v2/lab-instances
  -> create LabInstance + LabJob + LabTask records
  -> schedule Celery task graph
  -> provision cloud resources and TiDB Cloud assets
  -> upload bootstrap scripts and optional Caddy config
  -> mark LabInstance running and expose access resources
```

Key implementation anchors:

- Backend routing: `backend/labs/urls.py`, `backend/labs/api/urls.py`
- Lab spec loading: `backend/labs/lab_manager_v2/lab_spec.py`
- Lab lifecycle: `backend/labs/lab_manager_v2/lab_instance.py`
- Task execution: `backend/labs/tasks/lab_v2.py`

### Browser Web SSH

```text
Browser (xterm.js) -> wss://<ssh-proxy>/ssh-server/web?auth=<JWT>
                   -> ssh-proxy -> SSH -> lab VM
```

Key implementation anchors:

- URL generation and JWT signing:
  `backend/labs/lab_manager_v2/lab_instance.py`
- Proxy bridge entrypoint: `ssh-proxy/cmd/web-console-ssh/main.go`
- Proxy control plane registration:
  `ssh-proxy/internal/controlplane/client.go`

### HTTPS reverse proxy into the lab VM

```text
Browser -> https://<ip-as-host>.<xip-domain>/set-token?user_session=<JWT>&redirect=/
        -> Caddy on lab VM -> localhost:<service-port>
```

Key implementation anchors:

- Backend URL generation:
  `backend/labs/lab_manager_v2/lab_instance.py`
- Caddy install template:
  `backend/labs/templates/labs/install_caddy.sh`
- Setup task:
  `backend/labs/lab_manager_v2/tasks/create.py`

## Shared Operational Dependencies

- TiDB on MySQL protocol, typically port `4000`
- Redis, typically port `6379`
- `pingcap-inc/tidb-labs` checked out or mounted at `backend/labs/labs`
- Cloud provider credentials for AWS, Alicloud, and TiDB Cloud flows

## Where To Read Next

- [`docs/FRONTEND.md`](./docs/FRONTEND.md) for the user-facing app
- [`docs/RELIABILITY.md`](./docs/RELIABILITY.md) for runtime dependencies and
  deployment
- [`docs/SECURITY.md`](./docs/SECURITY.md) for auth, tokens, and secrets
- [`docs/product-specs/index.md`](./docs/product-specs/index.md) for
  user-facing product behavior
