Creating Courses
Lessons
Lessons are video-based content items with a transcript, key points, and optional resources. Each lesson lives in its own directory with a lesson.yml file.
lesson.yml Example
A complete lesson file using the fields loaded by the course CLI:
type: lesson
id: "what-is-kubernetes"
title: "What is Kubernetes?"
description: "Learn the fundamentals of Kubernetes and container orchestration."
estimatedTime: 15
estimatedReadTime: 10
# Video content
youtubeID: "fqMOX6JJhGo"
# Supporting content
transcript: |
# What is Kubernetes?
Kubernetes is an open-source container orchestration platform that
automates deploying, scaling, and managing containerized applications.
## Key Benefits
- Portability: Run anywhere — dev, test, production
- Scalability: Easy horizontal scaling
- Self-healing: Automatic restarts and replacements
summary: "Kubernetes orchestrates containerized applications at scale."
keyPoints:
- "Kubernetes automates deployment and scaling of containers"
- "Pods are the smallest deployable units in Kubernetes"
- "Services provide stable network access to pods"
narration:
audioUrl: "https://storage.googleapis.com/example-course/narration/audio.mp3"
slidesUrl: "https://storage.googleapis.com/example-course/narration/slides.json"
captionsUrl: "https://storage.googleapis.com/example-course/narration/captions.vtt"
interactionsUrl: "https://storage.googleapis.com/example-course/narration/interactions.json"
durationSec: 600
resources:
- title: "Official Kubernetes Documentation"
url: "https://kubernetes.io/docs/"
type: "documentation"
- title: "Kubernetes Interactive Tutorial"
url: "https://kubernetes.io/docs/tutorials/"
type: "tutorial"| Field | Required | Description |
|---|---|---|
description | Yes | Non-empty description; this is the lesson field enforced by course validation. |
id, title, youtubeID, transcript | Accepted | Loaded into the lesson. The course validator does not require these values or validate youtubeID. |
estimatedReadTime | Accepted | Loaded as a minute value; no maximum is enforced by the course validator. |
summary, keyPoints, resources | Accepted | Optional supporting content loaded into the lesson. |
narration | Optional | When present, audioUrl, slidesUrl, and captionsUrl must be public GCS URLs, and durationSec must be greater than zero. interactionsUrl is accepted but not validator-required. |
estimatedTime, type | Ignored | Accepted while reading lesson.yml but not copied into the loaded lesson. |
Validation
Keep lessons focused
The course validator requires a non-empty description. Keeping lessons short and focused is a teaching recommendation, not an enforced estimatedReadTime limit.
If a topic needs more depth, break it into multiple shorter lessons at natural conceptual break points. Each lesson should cover a focused subtopic that stands on its own.
Avoid
One 25-minute lesson on Complete Kubernetes Setup
Correct
Three 8-minute lessons: Clusters, Pods, Services
Flat Structure
Put the loaded fields at the top level of lesson.yml. A nested block is not read as lesson data, so required fields such as description would be empty.
Incorrect — nested structure
type: lesson
title: "Pods"
lesson:
id: "pods"
estimatedTime: 10
transcript: |
...Correct — flat structure
type: lesson
id: "pods"
title: "Pods"
description: "Learn how Kubernetes Pods group containers."
estimatedTime: 10
transcript: |
...Downloadable Resources
To attach a downloadable file to a lesson, place a file named lesson.zip in the same directory as the lesson.yml. No configuration needed — pov push-course detects and uploads it.
sections/01-intro/01-getting-started/
├── lesson.yml
└── lesson.zip ← just add this file- Must be a valid ZIP archive
- Maximum size: 50 MB
- The CLI looks only for lesson.zip beside lesson.yml
- pov push-course records and uploads the archive as the lesson's downloadable resource
- pov push-course-batch does not currently attach or upload lesson ZIP resources
