开始制作
基础要求
要编写交互式实验和挑战,你必须具备以下基本技能:
- 使用 Linux 的命令行界面,LabEx 的实验和挑战都是基于 Linux 系统。
- Git 和 GitHub 用于内容的提交和版本控制。
- Markdown 基本语法用于文档的编写。
- JSON 文件格式用于管理配置文件。
- 基本的英文读写能力。
- 如果你在中国大陆地区,需要一个稳定的本地代理,以便于顺利访问 GitHub 和 LabEx 网站。请不要询问我们使用什么代理,我们不会回答这个问题。
当然,也同时需要你具备期望制作实验和挑战相关的专业技能知识。
认领任务
接下来,介绍作者如何在 LabEx 平台上认领任务。
认领 Issue
在开始编写实验和挑战之前,你需要先认领一个 Issue:https://github.com/labex-labs/scenarios/issues
一般情况下,Issue 会有 3 个基本 Labels:
- 难度:例如
Beginner
,Intermediate
,Advanced
; - 类型:例如
Lab
,Challenge
; - 方向:例如
linux
,python
,docker
;
请充分利用好 GitHub Issue 提供的筛选功能。
如上图所示:
- 新手可以通过 ❶ 标记的筛选项进行筛选。例如你选中 Assignees 中的 Assigned to nobody,就可以看到所有未被别人分配认领的 Issue,再通过 Label 进一步筛选方向和难度等;还可以通过 Sort 进行 Issue 的排序,例如按照最新更新时间排序;
- 如果你对 GitHub 足够熟悉,也可以通过 ❷ 处的筛选条件进行筛选;
每个 Issue 对应一个实验或挑战。一般情况下,我们会在 Issue 中提供:
- 相应 Lab 的制作素材和基本信息;
- 补充的要求和注意事项;
请仔细阅读 Issue 的内容,然后按要求将 Issue 分配给自己(右上角点击 assign yourself),避免被其他作者重复认领。
认领后,你就可以开始编写实验和挑战了。
组织结构
我们的实验和挑战都是基于 GitHub 仓库进行组织的,每个仓库包含一个或多个实验和挑战。了解文件的组织结构对你正确提交内容非常重要。
我们会提前创建好一个 GitHub 仓库,其中包含多个文件夹,每个实验和挑战都在一个独立的文件夹内。
文档存放结构如下:
repo-name
└── linux
├── lab-name-1
├── lab-name-2
├── challenge-name-3
├── ……
其中:
linux
:是一个 Skill Tree 文件夹;lab-name-1
:是一个示例 Lab 文件夹;challenge-name-3
:是一个示例 Challenge 文件夹;
- 格式:只能出现小写字母和短横线,空格以短横线代替,不能出现空格、下划线、大写字母、特殊字符;
- 名称:Lab 以
lab-
开头,Challenge 以challenge-
开头,后续和 Lab Title 一致,不能单独定义;
我们会提前创建好一个 GitHub 仓库,其中包含多个文件夹,每个实验和挑战都在一个独立的文件夹内。
文档存放结构如下:
repo-name
└── linux
├── lab-name-1
├── lab-name-2
├── challenge-name-3
├── ……
其中:
linux
:是一个 Skill Tree 文件夹;lab-name-1
:是一个示例 Lab 文件夹;challenge-name-3
:是一个示例 Challenge 文件夹;
- 格式:只能出现小写字母和短横线,空格以短横线代替,不能出现空格、下划线、大写字母、特殊字符;
- 名称:Lab 以
lab-
开头,Challenge 以challenge-
开头,后续和 Lab Title 一致,不能单独定义;
每个 Lab 文件夹包一个实验/挑战的完整内容和素材。可以查看模板仓库:https://github.com/labex-labs/labs-template
示例如下:
└── basic-template
├── assets
└── example-asset.md
├── finish.md
├── index.json
├── intro.md
├── setup.sh
├── solutions
└── step1-solution.md
└── step2-solution.md
├── step1.md
├── step2.md
├── verify1-1.sh
├── verify1-2.sh
└── verify2.sh
其中:
index.json
:Lab 完整配置文件;intro.md
:开始步骤 Markdown 文件;finish.md
:结束步骤 Markdown 文件;step*.md
:中间步骤的 Markdown 文件;setup.sh
:启动脚本;verify*.sh
:验证脚本;solutions
:解决方案文件夹;assets
:附件文件夹;
- 格式:只能出现小写字母和短横线,空格以短横线代替,不能出现空格、下划线、大写字母、特殊字符;
- 名称:需严格按照上述示例命名,不能单独定义;
内容规范
以下是单个实验/挑战的完整内容规范。请仔细阅读,然后按照要求提交内容,我们会对内容进行 Review。
{
"type": "lab",
"title": "Basic Template",
"description": "The description of basic template",
"difficulty": "Beginner",
"time": 5,
"hidden": false,
"fee_type": "pro",
"contributors": []
}
index.json
中存在 5 个基础配置项:
type
: 必须为lab
或者challenge
. 关于实验和挑战title
: 实验/挑战的标题,采用 Title Case 格式。通常情况下,标题与文件夹名称完全一致。description
: 简介,通常为 1 ~ 2 句话,10 ~ 100 个单词,为intro.md
更精简的版本。time
: 预估完成时间,单位为分钟,通常为 5 的倍数,可以按每个步骤 5 分钟计算。difficulty
: 难度,必须为Beginner
,Intermediate
或者Advanced
。hidden
: 是否隐藏,默认为 False,管理员配置项,作者无需处理。fee_type
: 收费类型,默认为 Pro,管理员配置项,作者无需处理。contributors
: 贡献者列表,系统通过 GitHub 提交记录自动补充,作者无需处理。
Lab 的难度根据包含 Skills 的范围来定义,以下是:
Beginner
:实验/挑战只包含同一技能组(Skill Group)中的单个或多个技能,技能很简单。Intermediate
:实验/挑战包含同一技能树(Skill Tree)中的不同技能组的多种技能,技能难度不大。Advanced
:实验/挑战包含来自不同技能树(Skill Tree)的多种技能,而且技能难度较大。
其中,Skill Tree 层级为三级结构: Skill
→ Skill Group
→ Project
。例如:cd
→ Directory Operations
→ Linux
。
下面是一个完整的配置文件示例:
{
"type": "lab",
"title": "Basic Template",
"description": "The description of basic template",
"difficulty": "Beginner",
"time": 5,
"hidden": false,
"fee_type": "pro",
"details": {
"steps": [
{
"title": "Bananas",
"text": "step1.md",
"verify": [
{
"name": "Verify if bananas.txt exists",
"file": "verify1-1.sh",
"hint": "Please create file bananas.txt in /home/labex",
"timeout": 0,
"showstderr": true
},
{
"name": "Verify if apples.txt exists",
"file": "verify1-2.sh",
"hint": "Please create apples.txt in /home/labex",
"timeout": 10,
"showstderr": true
}
],
"skills": ["linux/ls", "linux/cd"],
"solutions": ["step1-solution.md", "solution2.py"]
},
{
"title": "Oranges",
"text": "step2.md",
"verify": [
{
"name": "Verify if oranges.txt exists",
"file": "verify2.sh",
"hint": "Please create file test.txt in /home/labex",
"timeout": 0,
"showstderr": true
}
],
"skills": ["linux/ls", "linux/cd"],
"solutions": ["step2-solution.md"]
}
],
"intro": {
"text": "intro.md",
"background": "setup.sh"
},
"finish": {
"text": "finish.md"
},
"assets": {
"host01": [
{
"file": "*.txt",
"target": "~/"
}
]
}
},
"backend": {
"imageid": "webide-ubuntu:2004"
},
"contributors": []
}
{
"type": "lab",
"title": "Basic Template",
"description": "The description of basic template",
"difficulty": "Beginner",
"time": 5,
"hidden": false,
"fee_type": "pro",
"contributors": []
}
index.json
中存在 5 个基础配置项:
type
: 必须为lab
或者challenge
. 关于实验和挑战title
: 实验/挑战的标题,采用 Title Case 格式。通常情况下,标题与文件夹名称完全一致。description
: 简介,通常为 1 ~ 2 句话,10 ~ 100 个单词,为intro.md
更精简的版本。time
: 预估完成时间,单位为分钟,通常为 5 的倍数,可以按每个步骤 5 分钟计算。difficulty
: 难度,必须为Beginner
,Intermediate
或者Advanced
。hidden
: 是否隐藏,默认为 False,管理员配置项,作者无需处理。fee_type
: 收费类型,默认为 Pro,管理员配置项,作者无需处理。contributors
: 贡献者列表,系统通过 GitHub 提交记录自动补充,作者无需处理。
Lab 的难度根据包含 Skills 的范围来定义,以下是:
Beginner
:实验/挑战只包含同一技能组(Skill Group)中的单个或多个技能,技能很简单。Intermediate
:实验/挑战包含同一技能树(Skill Tree)中的不同技能组的多种技能,技能难度不大。Advanced
:实验/挑战包含来自不同技能树(Skill Tree)的多种技能,而且技能难度较大。
其中,Skill Tree 层级为三级结构: Skill
→ Skill Group
→ Project
。例如:cd
→ Directory Operations
→ Linux
。
下面是一个完整的配置文件示例:
{
"type": "lab",
"title": "Basic Template",
"description": "The description of basic template",
"difficulty": "Beginner",
"time": 5,
"hidden": false,
"fee_type": "pro",
"details": {
"steps": [
{
"title": "Bananas",
"text": "step1.md",
"verify": [
{
"name": "Verify if bananas.txt exists",
"file": "verify1-1.sh",
"hint": "Please create file bananas.txt in /home/labex",
"timeout": 0,
"showstderr": true
},
{
"name": "Verify if apples.txt exists",
"file": "verify1-2.sh",
"hint": "Please create apples.txt in /home/labex",
"timeout": 10,
"showstderr": true
}
],
"skills": ["linux/ls", "linux/cd"],
"solutions": ["step1-solution.md", "solution2.py"]
},
{
"title": "Oranges",
"text": "step2.md",
"verify": [
{
"name": "Verify if oranges.txt exists",
"file": "verify2.sh",
"hint": "Please create file test.txt in /home/labex",
"timeout": 0,
"showstderr": true
}
],
"skills": ["linux/ls", "linux/cd"],
"solutions": ["step2-solution.md"]
}
],
"intro": {
"text": "intro.md",
"background": "setup.sh"
},
"finish": {
"text": "finish.md"
},
"assets": {
"host01": [
{
"file": "*.txt",
"target": "~/"
}
]
}
},
"backend": {
"imageid": "webide-ubuntu:2004"
},
"contributors": []
}
一个 Lab 由若干 Steps 有序组成,包含 2 个固定步骤和若干中间步骤。
intro
和 finish
项是固定步骤,无需修改。用于展示实验/挑战的开始 intro.md
和结束 finish.md
文档。配置如下:
"intro": {
"text": "intro.md",
"background": "setup.sh"
},
"finish": {
"text": "finish.md"
}
请注意,intro
和 finish
固定步骤在 index.json
中的 details
层级下,而非 steps
层级下。
此外,intro
中还包含 setup.sh
启动脚本,后续详解。
intro.md
要求:
- 标题:固定为
# Introduction
,不出现其他任何标题,采用 Title Case 格式; - 格式:正常的英文文本段落书写格式;首字母大写,句号结尾;
- 开头:一般以 “In this lab/challenge, you will learn how to …” 开头;
- 长度:2 到 3 句话为宜;
finish.md
要求:
- 标题:固定为
# Summary
,不出现其他任何标题,采用 Title Case 格式; - 格式:正常的英文文本段落书写格式;首字母大写,句号结尾;
- 开头:一般以 “Congratulations! You have successfully …” 开头;
- 长度:2 到 3 句话为宜;
step*.md
文件中包含每个步骤的内容。步骤的内容是以 Markdown 格式编写的,可以分为两部分:文本部分和代码部分。
一些注意事项:
- 一个步骤应该只包含 一个主要 Skill 的内容。
- 长的内容应该被分解成小的步骤。
- 步骤应该都需要包括代码练习,理论解释应该被整合到代码练习的过程中。
- 一般情况下,步骤的操作都是在
~/project
目录(/home/labex/project
)下完成,也是用户完成 lab 的默认工作目录。
steps
配置中包含若干中间步骤:
"steps": [
{
"title": "Bananas",
"text": "step1.md",
"verify": [
{
"name": "Verify if bananas.txt exists",
"file": "verify1-1.sh",
"hint": "Please create file bananas.txt in /home/labex",
"timeout": 0,
"showstderr": true
},
{
"name": "Verify if apples.txt exists",
"file": "verify1-2.sh",
"hint": "Please create apples.txt in /home/labex",
"timeout": 10,
"showstderr": true
}
],
"skills": ["linux/ls", "linux/cd"]
}
]
详细说明如下:
title
: 该步骤的标题。它将显示给学习者,所以它应该是清晰和简明的。text
: 该步骤的 markdown 文件名称。verify
: 该步骤的验证脚本,多个脚本会按顺序执行。后续详解。Verify Name 一般默认以 “Verify ……” 开头。skills
: 该步骤关联的 Skill ,需要从 Skill Tree 中复制相关的 Skill IDs。关于 Skill Treesolutions
: (challenge 必选,lab 缺省) challenge 的每个步骤均需要配置相应步骤的解决方案(答案),通过 list 列表绑定本地solutions
文件夹中的 md 文件、代码文件,每个步骤均支持绑定多个文件。所有文件请务必放在solutions
文件夹中。
stepx.md
要求:
- 标题:第一个标题为
# Step Title
,从 1 级别标题开始,按顺序递增,不能跳级,采用 Title Case 格式; - 格式:正常的英文文本段落书写格式;首字母大写,句号结尾;
- 开头:一般以 “In this step,” 开头;
- 长度:按需
- 请保持标题和描述的简洁性,正文同样避免冗长和赘述。
- 所有专有名词都应使用官方正式用法,不清楚时可以 Google 一下。
- 例如,GitHub 而不是 Github。
- 例如,Python 而不是 python。
- 内容中不应该出现任何英文以外的语言,包括中文。并尽量符合英文理解习惯。应使用 DeepL Write 或者 Grammarly 来检查拼写和语法错误。
- 所有的
.md
文件都应该用 Prettier 进行格式化。可以参考官方文档安装好命令行工具,然后cd
到提交 lab/challenge 目录下,运行prettier --write **/*.md
。
在大多数情况下,我们不推荐在 lab/challenge 中插入图片或截图。原因是:
- 图片无法很方便地被大语言模型分析,我们的文档内容会全部传输给大语言模型,以便学习助手 Labby 能更好地为用户提供帮助。
- 图片不易维护,一旦图片内容发生变化,就需要重新截图。且无法被编辑器搜索到关键字,需要人工逐一确认。
- 图片可能会导致文档的大小增加,从而增加了下载时间。
我们推荐你:
- 尽量将图片表达的内容转为使用文本。例如,终端的输入和输出信息,运行结果等,都使用 markdown 代码块来展示。
- 如果有图片存在的情况下,请通过文本段落对图片进行描述,从而让大语言模型能够更好地理解文档中的图片。
但是,如果你认为截图图片对于理解实验或挑战很重要,那么你仍然可以按以下要求插入图片:
- 所有图片不应侵犯任何版权或商标法,尤其是不要出现国外产品的 LOGO 等。
- 所有图片在添加到代码仓库之前应使用 TinyPNG 进行压缩。
- 所有图片应使用以下格式命名:
lab-<lab-name>-<step-number>-<image-number>.png
。 - 所有的图像都需要放置在
assets
目录下,但不需要在index.json
中添加assets
配置。 - 所有图片应使用以下相对链接格式进行引用:

。
你可以使用 Markdown 代码块来插入代码,例如:
print("Hello World")
- 在你的代码示例中,不要使用非正式的关键词,如
demo
,test
等。 - 单反引号只能用于内联代码,请不要用它来突出一个单词或短语。
- 正确用法:
print("Hello World")
。 - 错误用法:
这句话很重要
。
- 正确用法:
- 双反引号只能用于代码块,它必须有一个指定的语言。
- ```python
setup.sh
启动脚本包含在 intro
的第一个固定步骤配置中,用于在实验环境启动时自动运行。
启动脚本具有以下特性:
- Bash 脚本文件,用于执行一些初始化操作,例如安装软件包,配置环境变量等。
- 会在实验环境启动时自动在后台执行。执行过程和结果用户不可见。
- 启动脚本执行完成后,才会给用户展示环境界面。所以,为了避免用户长时间等待,请不要编写执行时间较长的命令,一般脚本执行时间最长不应该超过 5s。
- 太长的脚本会导致用户长时间等待,用户可能会误以为实验环境启动失败,从而关闭实验界面,重新打开实验界面,导致实验环境重复启动,浪费资源。
- 如果需要比较长的启动脚本,可以考虑将启动脚本作为准备步骤,放在 Steps 内容中,让用户手动操作完成 Lab 的准备过程。
Verify 步骤检测脚本是 LabEx 的重要特性之一,用户的每一步操作,系统都可以自动检测并反馈,也是交互式实验和挑战的核心。
一个步骤可以按需包含多个 Verify 脚本,单个脚本包含以下配置项:
{
"name": "Check if bananas.txt exists",
"file": "verify1-1.sh",
"hint": "Please create file bananas.txt in /home/labex",
"timeout": 0,
"showstderr": true
}
name
: 脚本的检测目标。它将显示给学习者,所以它应该是清晰和简明的,让用户知道检测了什么。file
: Shell 脚本文件名称。hint
: 如果脚本执行失败,将显示给学习者的提示信息。方便学习者解决问题。timeout
: 超时,默认为0
秒, 即不设置超时。可以指定检测超时时间。showstderr
: 默认为true
,即同时显示自定义的hint
提示信息和终端标准错误信息。
你可以简单理解 Verify 检测脚本为用户代码的单元测试。用户每完成一个步骤,系统就会自动运行相应的单元测试,检测用户代码是否正确。
你需要充分测试验证脚本,包括以下场景:
- 在步骤未操作或者操作错误时,验证脚本能正常报错;
- 验证脚本报错时,报错信息简洁、清晰、规范;
- 在步骤操作正确时,验证脚本能正常通过;
- ⽤户点击下一步,自动触发后台检测脚本依次执⾏;
- 脚本执⾏过程是系统通过 SSH 连接到⽤户环境,以默认⽤户权限在用户当前使用的环境中执⾏。检测脚本为 Bash 命令。
- 执行通过的脚本,只展示
name
配置项; - 执行失败的脚本,展示
name
和hint
配置项,也可以通过配showstderr
展示终端标准错误信息; - 依次执行,直到脚本执行失败(退出码 1)或者全部通过(退出码 0),如果中间脚本执行失败,后续脚本不再执行;
- 执行过程用户不可见。
Verify 脚本的基础是 Shell 命令,因为要通过 SSH 连接到用户环境中执行,但执行的内容可以自定义,灵活性非常高:
- 以 Python 为例,我们可以用 unittest 编写用户代码完整的单元测试,然后在 Verify 脚本脚本中执行单元测试。这意味着,用户的代码检测是由 Python 单元测试代码完成的,而 Shell 脚本只是触发了单元测试的执行。
- 类似 Python 的还有,Java 单元测试推荐使⽤ Junit,前端也可以使用第三方工具完成⾃动化测试。
- 数据库:可以使⽤擅⻓的编程语⾔连接到数据库访问数据判断。还可以利⽤数据库⽇志进⾏检测。
- API/HTTP 请求:利⽤ curl 或者擅⻓编程语⾔构建 HTTP 请求。
使⽤混淆矩阵来表示⽤户答案的正确性和检测判定的正确性。
编写 Verify 脚本时,要努⼒降低 FP 和 FN。 宁可 FP,也不要 FN。
- 在使用
grep
这类匹配关键词,用作verify
检测时,一定要特别谨慎小心。因为这种匹配字符串的方法,尤其是匹配用户的代码很死板。代码的写法很多,还比如说用户多一个空格,少一个空格之类的,都很容易导致匹配出现问题,检测不通过。这就是「假阴性」问题。 - 不是说不可以用
grep
,而是你一定要站在用户角度去提前帮用户规避这种问题。 - 一旦当用户觉得自己的代码是对的(的确也是对的),而检测不通过时,这种是最让用户烦躁的状态。你可以想一下如果你是用户,这个时候可能就会开骂「什么垃圾平台」。😂
assets
配置可以在环境启动时自动运行,将 assets
文件夹中的指定文件复制到用户环境中。实验环境的默认名称是 host01
。你可以充分利用好此特性,尤其是在需要给用户提供基础代码文件的实验/挑战设计中非常方便。
例如,下方配置表示把 assets
文件夹中所有文件复制到默认登录用户的主文件夹。
"assets": {
"host01": [
{ "file": "*.py", "target": "~/" }
]
}
在这个例子中,~/
映射到 /home/labex
,因为 labex
是默认用户,而 /home/labex
是该用户的主目录。
下面的例子复制了三个特定的文件。没有使用 *.py
通配符来选择所有 .py
结尾的文件,而是将两个文件复制到主目录,而第三个文件被复制到 /usr/local/bin
,并将其权限设置为可执行。
"assets": {
"host01": [
{"file": "sample_code.py", "target": "~/" },
{"file": "sample_data.csv", "target": "~/" },
{"file": "sneaky_script.sh", "target": "/usr/local/bin/", "chmod": "+x"}
]
}
assets
中的文件,无特殊情况外,请使用全小写字母 + 下划线替代空格,避免出现文件名大小写不一致的问题。- 保证你的附件足够小,每个文件限制在 9MB 以内。对附件的数量没有限制,但使用更多的附件会增加实验的加载时间。
- 尽可能不要使用
{ "file": "*", "target": "~/" }
复制所有文件,尤其是当assets
目录下存在文档需要的图片时,会导致图片被复制到用户环境中,从而无法在文档中正确显示。
内容中的 插图 虽然会放置到 assets
目录,但是无需添加 assets
配置。
backend
是实验环境配置项,包含以下内容:
"backend": {
"imageid": "webide-ubuntu:2204"
}
实验环境可以简单理解由两部分组成,虚拟机(VM)和界面(Interface)。界面运行在对应的虚拟机中,用户通过不同的界面与虚拟机进行交互。
目前,我们提供 2 种类型的虚拟机:
- 容器(Container):Docker 容器,启动速度快,成本低,适合绝大多数的实验/挑战使用。
- 云主机(Instance):云主机,启动速度慢,成本高,适合少数无法在 Docker 中完成的实验/挑战。例如学习 Docker 本身的实验,无法在 Docker 虚拟机中完成,需要在云主机中完成。
目前,我们提供 3 种类型的界面:
- VNC:图形界面,适合需要 GUI 界面的实验/挑战。启动速度快。
- WebIDE:类 VS Code 代码编辑器界面,适合需要编写大量代码的实验/挑战。启动速度较慢。
- TTYD:命令行界面,适合仅需要终端操作的实验/挑战。启动速度最快。
最终,我们通过 VM 和 Interface 的组合 <interface>-<vm>-<os>:<version>
,提供了 6 个 imageid
名称:
vnc-ubuntu:2204
: Ubuntu 22.04 容器环境webide-ubuntu:2204
: 和vnc-ubuntu:2204
一样,但默认展示给用户的 Interface 是 WebIDEvnc-instance-ubuntu:2204
: Ubuntu 22.04 云主机环境,预装了 Docker,Kuberneteswebide-instance-ubuntu:2204
: 和vnc-instance-ubuntu:2204
一样,但默认展示给用户的 Interface 是 WebIDEvnc-instance-ubuntu-bigdata:2204
: 基于vnc-instance-ubuntu:2204
基础上,预装 Hadoop,Hivevnc-instance-ubuntu-kali:2204
: Ubuntu 22.04 云主机环境,预装了 Metasploit 和 Docker 版本的 Kali Linux
解释如下:
- 第一个部分
<interface>
:一般情况下,所有的 Interface 都会展示给用户,用户可以自由切换,但是默认展示给用户的 Interface 由imageid
的第一个部分决定。例如vnc
和webide
, - 第二个部分
<vm>
:instance
指启动一个新的虚拟机实例(云主机),不包含instance
指启动后是一个新的容器实例(Docker)。 - 第三个部分
<os>:<version>
:ubuntu:2204
指启动后的操作系统是 Ubuntu 22.04,目前仅支持 Ubuntu 22.04。
在大多数情况下,你只需要配置好 imageid
即可,但我们提供了更多的灵活性允许对实验界面进行定制。
当你仅配置 imageid
时,这个 imageid
会包含对实验环境界面的默认配置,例如启动后你可以看到如下界面,包含 2 个 Tabs,分别是 Desktop
和 SSH
。
这个默认配置你无法修改,但是可以通过配置 Backend Services 按需新增更多类型的 Tabs。
目前,我们支持的 Services 类型有:
"backend": {
"imageid": "webide-ubuntu:2204",
"services": [
{ "type": "kasm_vnc"},
{ "type": "ttyd"},
{ "type": "iframe"},
{ "type": "iframe", "name": "HTTP 8081", "port": 8081 },
{ "type": "iframe", "src": "https://labex.io/courses"}
]
}
kasm_vnc
:即 VNC 界面,如果你的实验/挑战需要 GUI 界面,那么你需要配置这个类型的 Service。前端默认显示为Desktop
Tab。ttyd
:即 SSH 界面,如果你的实验/挑战需要 SSH 界面,那么你需要配置这个类型的 Service。前端默认显示为SSH
Tab。iframe
:即内嵌网页- 没有配置 port 和 src 的 iframe 代表 console.iframe,也就是 webide;前端默认显示为
WebIDE
Tab; - 配置容器端口的 iframe,例如上面的例子中的
HTTP 8080
;前端显示为HTTP 8080
Tab,当 Web 服务启动到相应端口后,你可以通过此 Tab 访问到 Web 服务; - 配置固定 url 的 iframe,例如上面的例子中的
https://labex.io/courses
。在 Tab 中内嵌一个固定的网页,例如你可以在这里内嵌一个文档,或者内嵌一个在线的 IDE。
- 没有配置 port 和 src 的 iframe 代表 console.iframe,也就是 webide;前端默认显示为
请注意,为了简化配置,我们会在 imageid
中配置固定的 Services,也是从上述的 Services 类型中选择。你在 index.json
中添加的 Services 只是在默认 imageid
的基础上新增的 Services,而不是覆盖。你也没有权限修改 imageid
中默认配置的 Services。
例如,当你的配置如下时:
"backend": {
"imageid": "webide-ubuntu:2204",
"services": [
{ "type": "iframe", "name": "HTTP 8081", "port": 8081 },
]
}
此时,你选择的 "imageid": "webide-ubuntu:2204"
包含默认的 Services 有 2 个,分别是 kasm_vnc
和 ttyd
,也就是上方你看到截图里的 Desktop
和 SSH
Tab。
在此基础上,你新增了一个 iframe
类型的 Service,也就是 HTTP 8081
Tab。
最终,当这个 Lab 启动后,你会看到 3 个 Tabs,分别是 Desktop
、SSH
和 HTTP 8081
。
Was this page helpful?