此页面由 AI 自动翻译。查看英文原版

本页目录

  • 配置字段
  • 应用元数据
  • 应用构建和运行时配置
  • 应用层
  • 挂载点
  • 静态前端
  • DepthAI 模型缓存
  • 环境变量和构建参数

配置 (oakapp.toml)

在每个应用的目录中,必须有一个 oakapp.toml 文件,其中包含应用的静态元数据和构建步骤。 元数据包括应用的标识符和版本。构建步骤是在容器中执行以构建或运行应用的命令。 oakapp.toml 文件示例:
Toml
1# (Required) App Identifier
2identifier = "com.luxonis.python_demo"
3# (Required) App Entrypoint
4entrypoint = ["bash", "-c", "python3 /app/main.py"]
5
6# (Optional) Prepare container commands
7# Here is the place where you can install all the dependencies that are needed at run-time
8prepare_container = [
9    { type = "COPY", source = "requirements.txt", target = "requirements.txt" },
10    { type = "RUN", command = "apt-get update" },
11    { type = "RUN", command = "apt-get install -y python3-pip" },
12    { type = "RUN", command = "pip3 install -r /app/requirements.txt --break-system-packages" },
13]
14
15# (Optional) Prepare build dependencies
16# Here is the place where you can install all the dependencies that are needed at build-time
17prepare_build_container = [
18    # Example: npm, gcc, ...
19]
20
21# (Optional) Additional commands after all the app files are copied to the container
22build_steps = []

配置字段

应用元数据

  • identifier - 应用的名称,采用类似 Java 的格式(使用点作为分隔符;例如,com.my_company.my_app
    • com.luxonis 命名空间保留给官方应用
    • com.example 命名空间不推荐用于生产应用
  • app_version - 应用的版本,格式为 major.minor.patch(例如,1.0.0

应用构建和运行时配置

  • entrypoint - 字符串数组(argv 格式的命令)
  • cwd - (可选,默认为 / )容器的当前工作目录
  • shell - (可选,默认为 ["/bin/bash", "-c"] )用于在 prepare_containerprepare_build_container 部分执行 build_stepsentrypointRUN 命令的 shell
  • app_dir_name (可选/高级;默认为 app ) - 应用文件复制到容器内的目录;仅当您已将此目录名称用于其他用途时才使用

应用层

类似于 Docker,应用是分层构建的:
  1. 基础镜像层(在 base_image 部分指定)
  2. 运行时层(在 prepare_container 部分构建)
  3. 构建层(在 prepare_build_container 部分构建;此层在构建后与运行时层断开连接)
  4. 应用层(应用目录中的所有文件以及在此处执行的 build_steps
除了应用层之外,还有两个额外的并行层:
  • 静态前端层(如果在 static_frontend 部分指定)
  • DepthAI 模型缓存层(如果在 depthai_models 部分指定)
如果这些层中的任何一层发生更改,所有后续层都将重新构建。并行层会独立于彼此重新构建,因为它们没有相互依赖关系。

基础镜像

默认基础镜像是 debian/bookworm-slim,从 registry-1.docker.io 拉取。 完整的 base_image 配置如下所示:
Toml
1[base_image]
2api_url = "https://registry-1.docker.io" # 可选:服务 https 地址
3service = "registry.docker.io" # 可选:镜像注册表服务名称
4image_name = "library/debian"
5image_tag = "bookworm-slim"
6
7oauth_url = "https://auth.docker.io/token" # 可选:此服务的 oauth 2.0 令牌地址
8auth_type = "repository" # 可选:范围类型
9auth_name = "library/debian" # 可选:资源名称

使用自定义基础镜像

如果您已经在使用 Docker 进行开发,可以通过将 base_image 指向您自己的镜像来重用该工作。当您想先在熟悉的 Docker 工作流中迭代操作系统包、运行时或共享依赖项,然后使用 oakapp.toml 打包最终应用时,这非常有用。当您开发可重用的基础环境并希望在多个应用之间共享它时,这也可能是一个不错的选择。使用自定义基础镜像进行稳定的共享环境设置,并使用 prepare_containerprepare_build_container 进行特定于应用的运行时和构建步骤。要使用不同的镜像作为基础层,请在 oakapp.toml 中定义它,如下所示:
Toml
1[base_image]
2image_name = "myorg/my-base"
3image_tag = "latest"
默认情况下,镜像从 Docker Hub 拉取,但您也可以使用 api_url 字段将 base_image 指向不同的注册表。

自托管容器注册表

为了避免 Docker Hub 的速率限制,您可以自托管一个容器注册表,并在开发过程中将 base_image.api_url 指向它。运行一个设备可访问的注册表:
Command Line
1docker run --rm -d -p 5000:5000 --name registry registry:2
构建一个镜像并推送到本地注册表
Sh
1echo "FROM ubuntu:26.04" > ./Dockerfile
2docker buildx build --platform linux/arm64 -t myapp-base:latest --load .
3docker tag myapp-base:latest localhost:5000/myapp-base:latest
4docker push localhost:5000/myapp-base:latest
在 oakapp 中使用基础镜像。在 oakapp.toml 中添加 [base_image] 部分,如下所示:
Toml
1[base_image]
2api_url = "http://<self-hosted-registry-ip>:5000" # 服务 http 地址,设备可见
3image_name = "myapp-base"
4image_tag = "latest"
请记住,应用程序是在设备上构建的,因此注册表必须可从设备访问。base_image.api_url 必须指向设备可联网访问的地址。 要使上传的镜像在 OAK4 设备上正常工作,它必须作为 linux/arm64 镜像上传。

运行时和构建层

prepare_containerprepare_build_container 都是在容器中执行以准备相应层的命令数组。唯一的区别是构建层在运行时不存在。可用的命令类型有:
  • RUN - 在容器中运行命令
Toml
1prepare_container = [
2    { type = "RUN", command = "apt-get update" },
3    { type = "RUN", command = "apt-get install -y python3-pip" },
4]
  • COPY - 将应用程序目录中的文件复制到容器中,在应用程序层中更早。这对于复制依赖文件(如 requirements.txt)很有用。没有必要在此处复制实际的应用程序文件,因为它们稍后会在应用程序层中复制。
    • source - 相对于主机上应用程序目录的源文件路径
    • target - 容器内应用程序目录的路径(如果指定了 app_dir_name,则为相对路径)
Toml
1prepare_container = [
2    { type = "COPY", source = "requirements.txt", target = "requirements.txt" },
3]

应用程序层

首先,应用程序目录中的所有文件都将被复制到容器中(如果指定了 app_dir_name,则复制到其中)。然后,按顺序执行 build_steps 中的命令。
  • build_steps - 用于构建应用程序或其他准备命令的步骤(字符串数组)
Toml
1build_steps = [
2    "g++ -o /app/my_app /app/main.cpp",
3    "chmod +x /app/my_app",
4]
您可以通过在应用程序目录中添加 .oakappignore 文件来忽略复制到容器的文件。 语法类似于 .gitignore。例如:
Plain Text
1# 忽略所有 .log 文件
2*.log
3# 忽略 node_modules/ 目录
4node_modules/

挂载点

挂载点允许您将运行应用程序的设备上的目录或设备链接到应用程序容器中。您不能通过这种方式挂载主机上的目录。 必需的挂载点在构建时和运行时都必须存在。
  • required_mounts, required_devices - 必需的挂载点 - 如果在容器启动时不存在,应用程序将停止并报错
语法为 source[:target[:options]];默认值:
  • source=target
  • options="rbind,rw"
  • 所有挂载路径必须是绝对路径。对于 required_mounts, required_devices, optional_mounts, optional_devicesadditional_mountssource/target),相对路径将被拒绝。
示例:
Toml
1required_mounts = [
2    "/data/my-storage:/app/storage:rw,rbind",
3]
  • optional_mounts, optional_devices - 如果在容器启动时不存在,则忽略这些挂载点
  • additional_mountssource , target , type , options , required 对象数组,请参见下面的示例:
Toml
1additional_mounts = [
2    { source = "/run/user/1000/pulse", target = "/run/user/1000/pulse", type = "none", options = [
3        "rbind",
4        "rw",
5    ], required = true },
6    { source = "/home/root/.config/pulse/cookie", target = "/root/.config/pulse/cookie", type = "none", options = [
7        "bind",
8        "ro",
9    ], required = true },
10]
  • additional_build_mounts - 与 additional_mounts 相同,但仅用于构建时;这些挂载点在运行时不存在
  • allowed_devices - 应用程序允许在容器内访问的设备列表
Toml
1allowed_devices = [{ allow = true, access = "rwm" }]

静态前端

静态前端层允许您与应用程序一起构建和提供静态 Web 前端。请参阅 GitHub 上的示例
  • static_frontend
    • dist_path - 构建的前端文件的路径(相对于主机上的应用程序目录)
      • build(可选) - 前端的构建配置
        • source_path - 前端源文件的路径
        • steps - 用于构建前端的命令数组
Toml
1[static_frontend]
2dist_path = "./frontend/dist" # path to the built frontend files
3
4[static_frontend.build]
5source_path = "./frontend" # path to the frontend source files
6steps = ["cd /app/frontend/src && npm install && npm run build"]
  • assign_frontend_port - 如果设置为 true,将为容器内的 OAKAPP_STATIC_FRONTEND_PORT 环境变量分配一个可用端口;即使未指定 static_frontend,也可以使用此选项
Toml
1assign_frontend_port = true
  • static_frontend_dir_name (可选/高级;默认为 static_frontend) - 容器内挂载静态前端文件的目录(将存储在 OAKAPP_STATIC_FRONTEND_PATH 环境变量中);仅当您已将此目录名称用于其他用途时才使用

DepthAI 模型缓存

此部分允许您指定一个包含 *.yaml 格式的 DepthAI 模型文件夹,这些模型将在构建时缓存在容器中。这样,您可以创建无需在运行时下载模型的离线应用程序。
  • depthai_models
    • yaml_path - *.yaml 格式的 DepthAI 模型文件夹的路径
    • use_only_cache - 如果设置为 true,将仅使用缓存的模型,并且在运行时不会下载新模型(设置 DEPTHAI_ZOO_INTERNET_CHECK 环境变量)
Toml
1depthai_models = { yaml_path = "./backend/src/depthai_models" }
  • depthai_models_dir_name (可选/高级;默认为 depthai_models) - 容器内挂载 DepthAI 模型文件的目录;仅当您已将此目录名称用于其他用途时才使用

环境变量和构建参数

环境变量仅在运行时设置。
Toml
1[env]
2MY_ENV_VAR = "some_value"
3ANOTHER_ENV_VAR = "another_value"
构建参数仅在构建时设置,在运行时不可用。
Toml
1[arg]
2MY_BUILD_ARG = "some_build_value"
3ANOTHER_BUILD_ARG = "another_build_value"
环境变量和构建参数的优先级都低于用户在命令行中设置的变量 (oakctl app run --env MY_ENV_VAR=value)。