跳到主要内容

Hello World

本教程通过一个最简的 Hello World 应用,演示 NE503 容器应用的完整生命周期:编写应用 → 构建 ARM64 镜像 → 上传部署 → 启动 → Web 控制台验收 → 查看日志 → 清理。该最小闭环是后续迭代任何 AI 应用的基础。

Hello World 不依赖 AI SDK,在一个循环中持续打印计数,用于验证开发环境与部署流程是否打通。

跳过构建,直接体验

不想自己 build 镜像?下载预编译包 hello-world.tar,解压即得 app.yamlimage.tar,按 §4 部署到设备即可。

1. 前置条件

条件验证方法
NE503 设备已联网并运行浏览器访问 http://<设备IP>:8080,能看到 Web 登录页
开发机已安装 Docker终端执行 docker --version,版本 >= 20.10
开发机能 ping 通设备curl -o /dev/null -w "%{http_code}" http://<设备IP>:8080 返回 200
知道设备登录凭据Web 控制台默认 admin / password(首次登录后请修改)
架构说明

NE503 设备为 ARM64 架构。开发机为 Apple Silicon(M 系列芯片)时同为 ARM64,可原生构建,速度较快;x86 开发机上 Docker buildx 会通过 QEMU 模拟,耗时略长但功能完整。

开发机与设备端的容器运行时是两回事
  • 开发机装 Docker,仅用于 docker buildx 跨架构构建镜像(见 §3),是开发机上的一次性动作;
  • 设备端运行容器用的是 containerd,应用在设备上跑起来不依赖 Docker(设备系统虽内置 docker,但容器编排完全由 containerd 完成,无需你安装或配置)。

2. 应用结构

Hello World 应用由三个文件组成(完整源码在仓库 apps/hello-world/):

hello-world/
├── app.py # 应用主逻辑
├── app.yaml # 应用清单(资源/权限/配置)
└── Dockerfile # 容器构建定义

app.py —— 纯 Python,循环打印带计数的信息,并响应 SIGTERM 优雅退出(平台停止应用时会发 SIGTERM):

import os, time, signal

class HelloWorldApp:
def __init__(self):
self.running = True
self.app_id = os.environ.get("APP_ID", "hello_world") # 平台注入
self.counter = 0
signal.signal(signal.SIGTERM, self._signal_handler)

def _signal_handler(self, signum, frame):
self.running = False

def run(self):
while self.running:
self.counter += 1
print(f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] #{self.counter:06d} - Hello World from AIPC!")
time.sleep(1)

if __name__ == "__main__":
HelloWorldApp().run()

app.yaml —— 应用清单,声明镜像、资源限制与启动策略(Hello World 不需要任何权限):

apiVersion: v1
kind: Application
metadata:
id: hello-world
name: Hello World
version: 1.0.0
description: A simple hello world application that prints continuously
spec:
image: aipc/hello-world:1.0.0 # 必须与 docker build -t 的 tag 一致
resources:
cpu: "10%"
memory: "32Mi"
autostart: false
restart_policy: on-failure
restart_max_retries: 3

Dockerfile —— 基于 python:3.11-alpine,体积小:

FROM python:3.11-alpine3.19
WORKDIR /app
COPY app.py /app/app.py
ENV PYTHONUNBUFFERED=1
ENV APP_ID=hello_world
CMD ["python3", "/app/app.py"]

3. 构建镜像

在应用目录下构建 ARM64 镜像,导出为 tar,再打包成 .aipc 安装包:

cd apps/hello-world

# 1. 构建 ARM64 镜像(--load 载入本地 Docker)
docker buildx build --platform linux/arm64 --load -t aipc/hello-world:1.0.0 .

# 2. 导出镜像为 tar
docker save aipc/hello-world:1.0.0 -o image.tar

# 3. 打包成 .aipc(app.yaml + image.tar 的 zip)
zip hello-world.aipc app.yaml image.tar

构建产物(真实):

产物大小
Docker 镜像26.5 MB(磁盘占用 113 MB)
image.tar25 MB
hello-world.aipc25 MB

.aipc 只是 app.yaml + image.tar 的 zip 归档包,便于保存和分发。部署到设备时用的是里面的 image.tarapp.yaml 两个文件(见下节),.aipc 本身不参与 API 上传。

构建偶发失败?

在 macOS + Docker Desktop 上,apk add 偶尔报 Failed to create ...: I/O error。这是 buildx 的已知偶发问题,重新执行一次构建命令即可成功

4. 部署到设备

构建完成后手上有 app.yamlimage.tar。三种部署方式,推荐 Web 控制台(图形界面、无需 SSH):

提前准备

三种方式都需要 app.yamlimage.tar 两个独立文件。按 §3 的手动步骤构建后,两文件都在应用目录里。若用仓库 apps/<app>/build.sh(打包 .aipc 后会删掉中间的 image.tar),请先 unzip -o <app>.aipc 解压。

4.1 通过 Web 控制台上传(推荐)

  1. 浏览器打开 Web 控制台 http://<设备IP>:8080,用默认凭据 admin / password 登录。

  2. 在左侧导航点击 App Management(应用管理),进入应用列表页。页面右上角有一张 Import(导入)卡片,点击它。

  3. 弹出 Application Setup Wizard(应用安装向导)。在第一步 Source(来源)中选择第三种 Upload Package(上传应用包)——同时接收 app.yaml 清单和镜像文件。

  4. App Manifest (app.yaml) 一栏点击 Choose File,选择本地的 app.yaml;在 Container Image 一栏选择 image.tar

上传应用包:选择 app.yaml + image.tar

  1. 点击右下角的 Install。向导自动完成后面的步骤(解析清单 → 导入镜像 → 注册应用),通常 10–15 秒。回到应用列表即可看到 Hello World(初始为 Stopped 状态,下一节启动)。

4.2 通过 aipc-cli 命令行部署(备选)

已 SSH 登录设备时,用平台自带的 aipc-cli 一条命令装好。先把 app.yamlimage.tar 传到设备:

scp app.yaml image.tar root@<设备IP>:/tmp/
ssh root@<设备IP>

然后在设备上执行:

aipc-cli app install app.yaml image.tar

4.3 通过 HTTP API 部署(备选)

适合脚本化 / CI 自动化。流程为两步上传 + 异步安装:登录取 token → 分别上传镜像与清单 → 触发安装并轮询进度。

旧的单文件上传 curl -F 'app=@xxx.aipc' /api/v1/apps 已失效,必须用下面的两步流程。

# 登录取 token(返回值含 "Bearer " 前缀,后续整串作为 Authorization 头)
curl -X POST http://<设备IP>:8080/api/login \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"password"}'

# 上传镜像与清单(字段名均为 file,返回各自的 path)
curl -X POST http://<设备IP>:8080/api/v1/apps/upload-image \
-H "Authorization: Bearer <token>" -F "file=@image.tar"
curl -X POST http://<设备IP>:8080/api/v1/apps/upload-manifest \
-H "Authorization: Bearer <token>" -F "file=@app.yaml"

# 触发异步安装(JSON body 传入上面两个 path),再用返回的 task_id 轮询到 phase=complete
curl -X POST http://<设备IP>:8080/api/v1/apps/install-package \
-H "Authorization: Bearer <token>" -H "Content-Type: application/json" \
-d '{"manifest_path":"<manifest path>","image_path":"<image path>","force":true}'
# → {"data":{"task_id":"0f26285a"}}
curl http://<设备IP>:8080/api/v1/apps/install-progress/<task_id> \
-H "Authorization: Bearer <token>"

通常 10–15 秒完成。

5. 启动与验收

5.1 启动应用

部署完成后应用处于 Stopped 状态,需要手动启动一次。两种方式任选其一。

方式一:Web 控制台启动(推荐)

进入 App Management(应用管理),找到 Hello World 卡片(状态显示 Stopped),点击卡片上的 Start 按钮。正常情况下几秒内状态徽章由 Stopped 切换为 Running。

方式二:HTTP API 启动

curl -X POST http://<设备IP>:8080/api/v1/apps/hello-world/start \
-H "Authorization: Bearer <token>"
首次启动超时?

首次启动某个镜像时,平台需要把它载入容器运行时,可能超过接口的 10 秒超时,返回 code:6002 DeadlineExceeded。这不是错误——再调用一次启动接口(或 Web 上再点一次 Start)即可成功。

5.2 在 Web 控制台验收

用浏览器登录 http://<设备IP>:8080admin / password),从用户视角确认应用运行:

Web 控制台登录页

Dashboard 顶部展示设备状态,中部 Applications 区域可见运行中的应用:

Dashboard 仪表盘(Hello World 运行中)

进入左侧 Applications,Hello World 处于 Running 并显示实时资源占用:

应用管理页(Hello World Running)

详情页可见应用 ID、版本、运行时长及 Stop / Restart / Uninstall 操作——应用已被平台纳管:

Hello World 应用详情

5.3 查看运行日志

应用日志也可通过接口获取(返回 NDJSON 格式,每行一个 JSON 对象):

curl "http://<设备IP>:8080/api/v1/apps/hello-world/logs?max_lines=10" \
-H "Authorization: Bearer <token>"
{"timestamp":1781509897838838800,"level":"info","message":"[2026-06-15 07:51:23] #000011 - Hello World from AIPC!"}
{"timestamp":1781509897838892960,"level":"info","message":"[2026-06-15 07:51:24] #000012 - Hello World from AIPC!"}
{"timestamp":1781509897838901400,"level":"info","message":"[2026-06-15 07:51:25] #000013 - Hello World from AIPC!"}

计数每秒递增,说明应用正在稳定运行。

6. 停止与清理

验收完成后,停止并卸载应用:

# 停止
curl -X POST http://<设备IP>:8080/api/v1/apps/hello-world/stop -H "Authorization: Bearer <token>"
# → {"data":{"message":"App stopped successfully"}}

# 卸载
curl -X DELETE http://<设备IP>:8080/api/v1/apps/hello-world -H "Authorization: Bearer <token>"
# → {"data":{"message":"App uninstalled successfully"}}

7. 小结

本教程完成了 NE503 容器应用的完整闭环演练:

  1. 编写 —— app.py + app.yaml + Dockerfile 三件套
  2. 构建 —— docker buildx build --platform linux/arm64docker savezip .aipc
  3. 部署 —— Web 控制台上传(推荐)/ aipc-cli / HTTP 两步上传,三选一
  4. 验收 —— Web 控制台确认 Running + 查看日志确认输出
  5. 清理 —— 停止 + 卸载