<!-- markdownlint-disable MD041 -->
# TiDB Hands-on Labs: Creating and Contributing Labs

This repository hosts [Hands-On Labs](https://labs.tidb.io), which may be publicly available or restricted to employees, designed to:

- Support Live demonstrations, competitor comparison, workshops
- Help users learn TiDB concepts and features through clear, practical, step-by-step exercises

**[Hands-On Labs](https://labs.tidb.io) can cover any topic except performance-related proof of concepts (PoC).**

---

## How to Create a New Lab

Before starting, please review the [hands-on lab roadmap](https://pingcap.feishu.cn/wiki/PzflwDU6JiWfd5kQ9Mfczu7un1g?table=tblGm4w7kRBQBkyI&view=vewIC72IzU) to ensure your work or proposal will NOT duplicate an existing lab.

There are **three ways** to create a new lab, choose the one that best fits your needs:

  1. (A) Submit a new hands-on lab proposal to the TiDB Labs team
  2. (B) Use your preferred AI Coding Agent to create a new lab (TiDB lab creation agent skill is integrated in the repo)
  3. (C) Manually create a new lab

After you submit your proposal or new lab PR, the TiDB Labs team will reach out to assist you with the final manual reviews and help publish your lab on labs.tidb.io.

## (A) Submit a New Lab Proposal to the TiDB Labs Team

Simply complete and submit [this form](https://pingcap.feishu.cn/share/base/form/shrcn4HOj6pVHESVSdbG9tKV2Af?from=navigation). The TiDB Labs team will review your proposal and follow up with you.

## (B) Use Your Preferred AI Coding Agent to Help You Create a New Lab

This repository supports Agent Skills, making it easy to skip the prompt engineering works. Just type `/lab-creator` in your AI agent's chat window and let the AI guide you step by step through designing, creating, and submitting a new lab.

## (C) Manually Create a New Lab

To create a new lab manually, you should have hands-on experience with TiDB, SQL, AWS (including Networking, IAM, CloudFormation, and EC2, etc), and Linux (Amazon Linux or Ubuntu), as well as any other relevant skills needed for your lab's specific requirements, such as Jupyter Notebook, Python, etc.

Each hands-on lab lives in its own top-level folder (e.g., `demo_001`, `demo_005`, `demo_408`). To create a new lab:

1. **Choose a Naming Convention**

   - For demo labs (feature demos): use `demo_XXX`, e.g., `demo_001`.
   - For administration course labs: use `dba_XXX`, e.g., `dba_101`.
   - Numbers should be unique and sequential, you can talk to TiDB Labs team to get the unique code for your lab.

2. **Copy the Standard Folder Structure**

   ```shell
   demo_xxx/
   ├── manifest.yaml            # Lab metadata (see below)
   ├── cloudformation.json      # AWS infrastructure as code template (required)
   ├── guides/
   │   ├── en/                  # English content (required)
   │   │   ├── catalog.yaml
   │   │   ├── module_0.md
   │   │   ├── module_1.md
   │   │   └── quiz_1.yaml
   │   ├── ja/                  # Japanese content (optional, recommended)
   │   └── zh/                  # Chinese content (optional, recommended)
   └── scripts/
        └── [utility scripts, e.g., prepare-monitor.sh]
   ```

3. **Fill Out the Manifest**

   There are two kinds of manifest files:

   - Lab that uses TiDB Cloud Starter.
   - Lab that uses TiDB Self-Managed.

   The following is an example of **TiDB Cloud Starter** environment `manifest.yaml` based on `demo_203/manifest.yaml` with explanations for each key:

   ```yaml
   lab_code: demo_203                      # [Required] Unique lab identifier; use the standard naming convention.
   title_en: Introduction to TiDB Cloud Starter   # [Required] Lab title in English.
   title_ja: TiDB Cloud Starter 紹介              # [Optional] Lab title in Japanese.
   title_zh: TiDB Cloud Starter 简介               # [Optional] Lab title in Chinese.
   description_en: |                        # [Required] Lab description in English. Use '|' for multiline.
     In this lab, you will learn the basic operations and features of TiDB Cloud...
   description_ja: |                        # [Optional] Japanese version of the description.
     この演習では、TiDB Cloud の基本的な操作方法...
   description_zh: |                        # [Optional] Chinese version of the description.
     在这个实验中，你将学习 TiDB Cloud Starter 的基本操作...
   splash_image_en: https://...             # [Required] Splash/header image for English interface.
   splash_image_ja: https://...             # [Optional] Splash/header image for Japanese interface.
   splash_image_zh: https://...             # [Optional] Splash/header image for Chinese interface.

   external_materials_en:                   # [Optional] List of external references in English. 'employee_only' restricts internal materials.
     - name: "TiDB Cloud Intro Reference Deck"
       url: https://docs.google.com/presentation/...
       employee_only: true
   external_materials_ja:                   # [Optional] Japanese reference materials.
   external_materials_zh:                   # [Optional] Chinese reference materials.

   lab_level: Beginner                      # [Required] Lab difficulty: Beginner, Intermediate, Advanced.
   category_en:                             # [Required] List of technology or topic categories in English.
     - TiDB Cloud
     - Non-Sandbox
   category_ja:                             # [Optional] Japanese categories.
   category_zh:                             # [Optional] Chinese categories.

   authors:                                 # [Required] Creator(s) or contributor(s).
     - Todd Bao (CEG)
   delivery_type: Self-Paced                # [Required] Type: Self-Paced, Instructor-Led.

   tidb_environments:                       # [Required] TiDB Cloud Starter. For TiDB Cloud Starter labs, it must be TiDB Cloud Starter.
     - TiDB Cloud Starter

   target_audience:                         # [Required] Who should take this lab? (List of user personas)
     - GenAI Developer
     - Developer
     - DBA
     - Architect

   regions:                                 # [Required] Supported AWS regions, by provider.
     aws:
       - oregon
       - singapore
       - frankfurt

   credits: 1                               # [Required] Lab credits “cost” for running this lab.
   credit_redeemable: true                  # [Required] Whether credits can be exchanged to take this lab.
   employee_only: false                     # [Required] Set to true if lab is internal only. For internal or working-in-progress labs, set to true.
   estimated_duration_minutes: 150          # [Required] Estimated time to complete in minutes.

   keywords_en:                             # [Optional] Tags/keywords in English to help with search/discovery.
     - "TiDB X"
     - "Vector Search"
     - "Auto Embedding"
     # ... more keywords

   topology:                                # [Required] Infrastructure/VM roles required. Keep those values.
     - role: monitor
       node_count: 1
       web_ssh: true
       web_ssh_name: "Client Machine"
       ssh_user: ubuntu

   requirements:                            # [Required] Special prerequisites. Keep those values.
     - type: "CloudStack"
     - type: "TiDBServerlessCluster"
     - type: "AWSAuroraServerlessCluster"

   bootstrap:                               # [Required] Steps/scripts to prepare environment.
     - name: "prepare monitor"
       type: "ShellScript"
       target:
         - monitor1
       script: ./scripts/prepare-monitor.sh # [Required] Preparation steps you need the lab machine to run.

   features:                                # [Required] Feature/toggle flags for lab behavior.
     enable_content_explain: true           # [Required] true for all labs.
     disable_serverless_sandbox: true       # [Required] If you want users run the labs in their own TiDB Cloud account, use true.
     enable_environment_variables_fallback: true # [Required] Keep it as true.
   ```

   The following is an example of **TiDB Self-Managed** environment `manifest.yaml` based on `demo_010/manifest.yaml` with explanations for each key:

   ```yaml
   lab_code: demo_010                    # [Required] Unique identifier for the lab. Use lowercase letters/numbers/underscores.
   title_en: Deploying a TiDB Cluster Using TiUP  # [Required] Lab title in English. Repeat for other languages as title_zh, title_ja, title_ko if multilingual.
   description_en: |                    # [Required] Short English description of lab purpose/goals. Provide similarly for other languages if desired.
     This hands-on lab demonstrates how to deploy a TiDB cluster using TiUP, a powerful cluster management tool for TiDB...
   splash_image_en: https://...png       # [Optional] Splash/feature image for lab in English UI. Use language codes (en/zh/ja/ko) for localization.
   lab_level: Beginner                   # [Required] Difficulty/star-level: Beginner, Intermediate, or Advanced.
   category_en:                         # [Required] Category tags in English. Repeat in other languages for i18n.
     - Short Demo
     - Deployment
   authors:                             # [Required] List of author(s) and their team/role.
     - Todd Bao (CEG)
   delivery_type: Self-Paced            # [Required] Type: Self-Paced, Instructor-Led.

   tidb_environments:                   # [Required] Target deployment environments for TiDB. For TiDB Self-Managed labs, it must be TiDB Self-Managed.
     - TiDB Self-Managed

   tidb_versions:                       # [Required] List of recommended/validated TiDB versions for lab. Optional but encouraged. Please confirm with TiDB Labs team first for the TiDB versions availability on the lab platform.
     - 6.5.9
     - 7.5.4
     - 8.1.1
     - 8.5.1

   target_audience:                     # [Required] List of user personas this lab is intended for.
     - Architect
     - DBA
     - DevOps

   regions:                             # [Required] Supported regions per cloud provider. Nested per provider.
     aws:
       - oregon
       - tokyo
       - singapore
       - frankfurt

   credits: 3                           # [Required] Lab credit cost.
   credit_redeemable: true              # [Required] Whether users can redeem credits for this lab.
   employee_only: false                 # [Required] true if only internal/employees can access.
   estimated_duration_minutes: 45       # [Required] Estimated time for completion.

   topology:                            # [Required] Defines cluster/machine architecture. Each entry specifies role, count, and special configs. It should be aligned with the `cloudformation.json` file.
     - role: monitor                    # The machine can be logged in by user.
       node_count: 1
       web_ssh: true                 # Can user SSH onto this machine?
       web_ssh_name: "TiUP Control Machine"
       ssh_user: ec2-user               # The SSH username.
     - role: pd
       node_count: 3
     - role: kv
       node_count: 3
     - role: db
       node_count: 2
     - role: tiflash
       node_count: 1

   requirements:                        # [Required] Keep it unchanged.
     - type: "CloudStack"

   bootstrap:                           # [Required] Preparation steps/scripts run after infra is ready (per node or group).
     - name: "prepare monitor"
       type: "ShellScript"
       target:
         - monitor1
       script: ./scripts/prepare-monitor.sh

   features:                            # [Required] Feature flags to enable/disable lab options. Boolean flags.
     enable_content_explain: true       # Keep this setting unchanged.
   ```

   **Key Explanations:**
   - All top-level keys have been annotated above. Non-required fields are optional but encouraged for localization and flexibility.
   - For additional details or complex scenarios, check other `manifest.yaml` files in this repository.

   **Key points:**
   - `lab_code`, `title_en`, `description_en`, `lab_level`, `category_en`, `authors`, `delivery_type`, `credits`, and `estimated_duration_minutes` are required for every lab.
   - Localized fields (titles, descriptions, categories, splash images) are recommended for multilingual support.
   - Additional fields allow specifying prerequisites, infrastructure topology, and region support.
   - Look at other example labs for further conventions.

4. **Write Step-by-Step Modules**

   - Place markdown files as `module_0.md`, `module_1.md`, ... for each step.
   - Use clear language, commands, and expected results.
   - If applicable, include quizzes as `quiz_*.yaml`.
   - We highly recommend reviewing and using the existing lab guides in other labs as your starting point.

5. **Ensure Multilingual Support**

   - All labs must include at least English (`guides/en/`).
   - Japanese (`ja/`) and Chinese (`zh/`) translations are recommended for core labs.

6. **Design the Content Catalog**

   The `catalog.yaml` in each language guides navigation:

   ```yaml
   - file: module_0.md
     public: true
     title: Overview
     type: markdown
   - file: module_1.md
     public: true
     title: "Module 1: Title"
     type: markdown
   - file: quiz_1.yaml
     public: true
     title: "Quiz 1"
     type: quiz
   ```

7. **Infrastructure Templates**

   Infrastructure templates are required:
   - For AWS, use `cloudformation.json` (CloudFormation).
   - For Alicloud, use `alicloud_ros.json` (ROS).
   - Use descriptive resource names and add `Owner` tags for cost tracking.
   - Test infrastructure in each listed region per cloud provider.

8. **Provide Utility Scripts**

   - Store in the `scripts/` subdirectory.
   - Use bash with inline comments and error-handling.

---

### Contributing: Branching & Pull Requests

We welcome your contributions! Please follow this workflow:

0. **Add your Github account to PingCAP owned Github organizations**

   - In Lark Workplace, open "Approval", search for "Request to join the Github organization", submit the form, and wait for approval.

   ![join-pingcap-inc-org](https://lab-static.pingcap.com/images/2026/1/15/054cb5c68c68499233842cb368f8395132da6c39.jpg)

1. **Clone the Repo**

   ```shell
   git clone https://github.com/pingcap-inc/tidb-labs.git
   cd tidb-labs
   ```

2. **Set the Upstream**

   ```shell
   git remote add upstream https://github.com/pingcap-inc/tidb-labs.git
   ```

3. **Create a Feature Branch**

   ```shell
   git checkout -b feature/my-new-lab
   ```

4. **Develop Your Lab**

   - Follow the structure guidelines above.
   - Use clear, atomic commits for each significant change:

     ```shell
     git add .
     git commit -m "lab(demo_123): Adding new lab - TiDB Migration Basics"
     ```

5. **Push Your Branch**

   ```shell
   git push origin feature/my-new-lab
   ```

6. **Submit a Pull Request (PR)**

   - Go to tidb-labs GitHub page.
   - Click "New Pull Request", targeting `pingcap-inc/tidb-labs:main`.
   - In your PR message:
     - Clearly describe your lab and changes.
     - Tag relevant reviewers if needed.
     - Reference any related discussions/issues.

7. **Code Review and Merging**

   - Automated checks (YAML validation, markdown lint, template checks) must pass.
   - Maintainers will review for accuracy, structure, and translation (if included).
   - Address any reviewer feedback.
   - Once approved, your lab will be merged!

---

### Best Practices & Tips

- **File Naming**: Use lowercase and hyphens, e.g., `module_01.md`, `prepare-env.sh`
- **Commit Messages**: Be descriptive! E.g., "Add demo_007: TiCDC Data Replication Lab"
- **Consistency**: Match navigation and file naming across languages.
- **Version Updates**: Reflect recent TiDB versions in `manifest.yaml`.
- **Testing**: Run all code/infra — labs must work in a clean, new environment.
- **Localization**: Sync translation updates across `en/`, `zh/`, `ja/`.

---

### Examples

- `demo_001`: Database Zero Downtime Under Availability Zone Failure
- `demo_408`: Build Vector Search Apps Using Jupyter Notebook
- `demo_203`: Introduction to TiDB Cloud Starter

Browse these folders for practical examples of structure and content.

---

## Need Help?

- [Open an Issue](https://github.com/pingcap-inc/tidb-labs/issues)
- Contact TiDB Labs team by searching "TiDB Labs" in Lark, we can give you more guidance.
