Skip to main content

App Reference

This document is the complete configuration reference for NE503 container applications, covering all app.yaml field definitions, Dockerfile authoring patterns, security sandbox model, and multi-container architecture. For a step-by-step tutorial for beginners, please refer to SDK Examples.

1. Application Overview​

Applications on the NE503 platform run as OCI containers, with their lifecycle managed by the App Manager. Each application declares its image, resource requirements, and permissions through an app.yaml manifest file.

Core Concepts:

  • Single-Container Mode -- Most applications only need one container. Simply specify the image in spec.image.
  • Multi-Container Mode -- Complex applications can be split into main + sub containers for process-level isolation. Only the main container has platform service access.
  • Principle of Least Privilege -- All permissions (video streams, inference, device control, etc.) must be explicitly declared. Undeclared permissions are not available.

Project File Structure:

my-app/
β”œβ”€β”€ app.yaml # Application manifest (required)
β”œβ”€β”€ Dockerfile # Build definition (required)
β”œβ”€β”€ app.py # Entry point
β”œβ”€β”€ requirements.txt # Python dependencies (optional)
└── config/ # Configuration files (optional)

2. app.yaml Complete Reference​

The application manifest is the core configuration file of the AIPC platform. This section explains all fields level by level.

2.1 Minimal Configuration​

apiVersion: v1
kind: Application
metadata:
id: my_app
name: My Application
version: 1.0.0
spec:
image: aipc/my_app:1.0.0

2.2 Complete Single-Container Configuration​

The following example includes all available fields, grouped and explained by level:

apiVersion: v1
kind: Application

metadata:
id: my_app # Required - unique identifier
name: My Application # Required - display name
version: 1.0.0 # Required - semantic version
description: Application description # Optional - application description
author: Developer # Optional - author
email: dev@example.com # Optional - contact email

spec:
image: aipc/my_app:1.0.0 # Required - container image (docker.io/ prefix is automatically added when no registry prefix is specified)

# ── Resource Limits ──────────────────────────────
resources:
cpu: "50%" # CPU limit, supports percentage ("50%") or core count ("1.5")
memory: "256Mi" # Memory limit, supports Mi/Gi suffix ("512Mi", "1Gi")

# ── Permission Declarations ──────────────────────
permissions:
video: # Video stream access
- sub.raw # Raw video stream (sub publishes NV12 frames, DMA-BUF zero-copy, used for inference)
- main # Encoded video stream (H264, for RTSP pull, cannot subscribe for inference)
inference: # AI inference
models: [hailo_yolov8n_384_640] # Allowed model list (must match models loaded on the device)
max_qps: 30 # Maximum inference requests per second
max_concurrent: 2 # Maximum concurrent inferences
allow_register_model: false # Whether to allow dynamic registration of new models
events: # Event bus
publish: [app/my_app/*] # Publishable topics (supports * wildcard)
subscribe: [model/*/detections, system/*] # Subscribable topics
device: # Device control
light: true # Fill light
ir_cut: true # IR-CUT filter
ptz: false # PTZ control
lens: false # Lens zoom/focus
gpio:
read: [12, 13] # Readable GPIO pin numbers
write: [21, 22] # Writable GPIO pin numbers
network: # Network access
mode: isolated # Network mode: isolated (default) or host
outbound: # Outbound whitelist (only effective in isolated mode)
- "https://api.example.com"
- "mqtt://broker.example.com:8883"
inbound: # Inbound ports (only effective in host mode)
- 8554

# ── Environment Variables ────────────────────────
env:
- name: LOG_LEVEL
value: INFO
- name: CUSTOM_CONFIG
value: "production"

# ── Volume Mounts ────────────────────────────────
volumes:
- host: /opt/aipc/data/my_app # Host path (automatically adapts to deployment prefix)
container: /app/data # Container path
readonly: false # Whether read-only mount

# ── Security Sandbox ────────────────────────────
security:
no_new_privileges: true # Disable privilege escalation (default: true)
readonly_rootfs: true # Read-only root filesystem (default: true)

# ── Startup Policy ──────────────────────────────
autostart: true # Auto-start on boot (default: false)
restart_policy: on-failure # Basic restart policy: always | on-failure | no
restart_max_retries: 3 # Maximum restart attempts for basic restart

# ── Health Check ────────────────────────────────
healthcheck:
enabled: true
type: command # Check type: command | http | tcp
command: "/app/main --health" # command type: command to execute
path: /healthz # http type: check path
port: 8080 # http/tcp type: port number
interval: 30s # Check interval
timeout_seconds: 5 # Timeout in seconds
retries: 3 # Consecutive failure threshold

# ── Auto Restart (Enhanced, with exponential backoff) ──
auto_restart:
enabled: true # Enable auto restart
max_retries: 3 # Maximum restart attempts (0 = unlimited)
retry_delay_seconds: 10 # Initial retry delay in seconds
backoff_multiplier: 2.0 # Backoff multiplier (each failure delay x this value, capped at 5 minutes)
health_check_interval_seconds: 30 # Health check polling interval in seconds

# ── Plugin System ───────────────────────────────
plugin:
capabilities:
- id: rtsp-server # Capability unique identifier
version: "1.0" # Capability version
transport: both # Communication mode: grpc | event | both
description: RTSP streaming service
proto: "rtsp.RtspService" # gRPC service definition (required for grpc/both)
topics: # Event topics (required for event/both)
publish:
- "plugin/rtsp/stream-status"
subscribe:
- "system/video-config-changed"

plugin_dependencies: # Declare dependencies on other plugin capabilities
- capability: rtsp-server # Capability identifier
min_version: "1.0" # Minimum version requirement
required: true # Whether this is a hard dependency

2.3 Top-Level Fields​

FieldTypeRequiredDescription
apiVersionstringYesAPI version, currently fixed as v1
kindstringYesResource type: Application, ModelService, BusinessService
metadataobjectYesApplication metadata, see 2.4 metadata Field
specobjectYesApplication spec, see 2.5 spec Field

2.4 metadata Field​

FieldTypeRequiredDescription
idstringYesUnique identifier, lowercase letters/digits/underscores, immutable after creation
namestringYesApplication display name
versionstringYesSemantic version number (major.minor.patch)
descriptionstringNoApplication description
authorstringNoAuthor name
emailstringNoContact email

2.5 spec Field​

FieldTypeRequiredDescription
imagestringRequired for single-containerContainer image reference, registry prefix is automatically completed
resourcesobjectNoResource limits (cpu, memory)
permissionsobjectNoPermission declarations, see 2.6 permissions Field
envarrayNoEnvironment variable list, each item contains name and value
volumesarrayNoVolume mount list, see description below
securityobjectNoSecurity sandbox configuration, see 4 Permission Model
autostartboolNoAuto-start on boot, default false
restart_policystringNoBasic restart policy: always, on-failure, no (default)
restart_max_retriesintNoMaximum restart attempts for basic restart
healthcheckobjectNoHealth check configuration
auto_restartobjectNoEnhanced auto restart configuration (with exponential backoff, takes priority over restart_policy)
pluginobjectNoPlugin capability declaration
plugin_dependenciesarrayNoPlugin dependency declaration
containersmapNoMulti-container mode, see 5 Multi-Container Configuration
networkingobjectNoMulti-container network configuration
lifecycleobjectNoMulti-container lifecycle configuration

2.6 permissions Field​

video -- Video stream access list:

ValueDescription
sub.rawRaw video stream (the sub stream publishes NV12 frames, DMA-BUF shared-memory zero-copy, used for inference subscription)
mainEncoded video stream (H264, for RTSP pull, cannot be used for inference subscription)

When declaring a .raw stream, the platform automatically mounts the /dev/dma_heap device (in multi-container mode, the main container additionally shares the host IPC namespace) to support DMA-BUF zero-copy memory mapping. main only publishes encoded H264; subscribe(stream="main") hangs forever β€” inference must use sub.

inference -- AI inference permissions:

FieldTypeDefaultDescription
modelsstring[]--Allowed model ID list (required, automatically registered with AI Runtime at startup)
max_qpsint0Maximum inference requests per second
max_concurrentint0Maximum concurrent inferences
allow_register_modelboolfalseWhether to allow dynamic registration of new models at runtime

events -- Event bus permissions:

FieldTypeDescription
publishstring[]Publishable topic patterns, supports * wildcard (e.g., app/my_app/*)
subscribestring[]Subscribable topic patterns, supports * wildcard (e.g., model/*/detections)

device -- Device control permissions:

FieldTypeDescription
lightboolFill light control
ir_cutboolIR-CUT filter control
ptzboolPTZ control
lensboolLens zoom/focus control
gpio.readint[]List of readable GPIO pin numbers
gpio.writeint[]List of writable GPIO pin numbers

network -- Network access permissions:

FieldTypeDescription
modestringisolated (default, independent network namespace) or host (shared host network)
outboundstring[]Outbound whitelist, only effective in isolated mode
inboundint[]Inbound port list, only effective in host mode

2.7 volumes Field​

Each volume mount item contains:

FieldTypeRequiredDescription
hoststringYesHost path (/opt/aipc prefix is automatically adapted to the actual deployment path)
containerstringYesMount path inside the container
readonlyboolNoWhether to mount as read-only, default false

The platform automatically mounts the /run/aipc directory, enabling the container to access all IPC Sockets (ai-runtime.sock, event-bus.sock, etc.). No manual declaration is needed.

2.8 healthcheck Field​

FieldTypeDescription
enabledboolWhether to enable health checks
typestringCheck type: command (execute command), http (HTTP request), tcp (TCP connection)
commandstringCommand to execute when type=command
pathstringRequest path when type=http
portintPort number when type=http or type=tcp
intervalstringCheck interval (e.g., 30s)
timeout_secondsintSingle check timeout in seconds
retriesintNumber of consecutive failures before marking as unhealthy

2.9 auto_restart Field​

Enhanced auto restart policy with exponential backoff support. When auto_restart.enabled is true, it takes priority over restart_policy.

FieldTypeDefaultDescription
enabledboolfalseWhether to enable auto restart
max_retriesint0Maximum restart attempts (0 means unlimited retries)
retry_delay_secondsint5Initial retry delay in seconds
backoff_multiplierfloat1.5Backoff multiplier, each failure delay is multiplied by this value, capped at 5 minutes
health_check_interval_secondsint30Background health check polling interval in seconds

Backoff Calculation Example (retry_delay_seconds: 10, backoff_multiplier: 2.0):

  • 1st restart: 10 seconds delay
  • 2nd restart: 20 seconds delay
  • 3rd restart: 40 seconds delay
  • ...capped at 300 seconds (5 minutes)

2.10 plugin Field​

Declares the plugin capabilities provided by the application for other applications to discover and depend on.

capabilities item:

FieldTypeRequiredDescription
idstringYesCapability unique identifier
versionstringYesCapability semantic version
transportstringYesCommunication mode: grpc, event, both
descriptionstringNoCapability description
protostringRequired for grpc/bothgRPC service definition (e.g., "rtsp.RtspService")
topicsobjectRequired for event/bothContains publish and subscribe topic lists

The plugin runtime Socket path is /run/aipc/plugins/<app_id>.sock.

plugin_dependencies item:

FieldTypeRequiredDescription
capabilitystringYesDependent capability ID
min_versionstringNoMinimum version requirement
requiredboolNoWhether this is a hard dependency (when true, the application cannot start if the dependency is not met)

2.11 Validation Rules​

The App Manager performs the following validations during installation:

  1. apiVersion must be v1
  2. kind must be Application, ModelService, or BusinessService
  3. metadata.id, metadata.name, metadata.version are required
  4. In single-container mode, spec.image is required; in multi-container mode, each container's image is required
  5. network.mode only allows isolated or host; inbound is only available in host mode
  6. In multi-container mode, there must be exactly one container with role: main, and sub containers cannot declare any permissions
  7. Plugin capability event topics must have corresponding publish/subscribe permissions in permissions.events

3. Dockerfile Patterns​

The SDK is pre-installed in the base image, no additional installation steps required:

FROM aipc/python-base:1.0
WORKDIR /app
COPY . /app/
RUN if [ -f requirements.txt ]; then pip install --no-cache-dir -r requirements.txt; fi
RUN useradd -m -u 1000 appuser && chown -R appuser:appuser /app
USER appuser
CMD ["python", "app.py"]

3.2 Python -- Wheel File (Offline Environment)​

FROM python:3.9-slim
WORKDIR /app
COPY hailo_ipc_sdk-*.whl /tmp/
RUN pip install --no-cache-dir /tmp/hailo_ipc_sdk-*.whl && rm /tmp/*.whl
COPY . /app/
RUN useradd -m -u 1000 appuser && chown -R appuser:appuser /app
USER appuser
CMD ["python", "app.py"]

3.3 Go -- Multi-Stage Build​

FROM golang:1.25-alpine AS builder
WORKDIR /build
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o /app/main ./cmd/main

FROM alpine:3.18
RUN apk --no-cache add ca-certificates tzdata
COPY --from=builder /app/main /app/main
RUN addgroup -g 1000 appgroup && adduser -u 1000 -G appgroup -s /bin/sh -D appuser
USER appuser
HEALTHCHECK --interval=30s --timeout=5s --start-period=5s --retries=3 \
CMD /app/main --health-check
ENTRYPOINT ["/app/main"]

3.4 Best Practices​

  • Non-root execution -- Create a dedicated user (UID 1000) and switch using the USER directive. The platform automatically injects the AIPC group GID (1001) for Socket access; no manual configuration needed.
  • Image slimming -- Use multi-stage builds, --no-cache-dir, and clean up temporary files to reduce image size.
  • Read-only filesystem compatibility -- Avoid writing to system directories such as /etc and /var. Data should be written to volumes mount paths.
  • Proxy builds -- Use --build-arg HTTP_PROXY=... when cross-compiling on x86 development machines.
  • Cross-architecture -- Use docker buildx build --platform linux/arm64 to build ARM images.

4. Permission Model​

NE503 employs a multi-layer security sandbox. All security policies are enforced by the platform; developers do not need to configure them in the Dockerfile.

4.1 Linux Capabilities​

The following dangerous capabilities are automatically dropped when a container starts:

Dropped CapabilityRisk
CAP_SYS_ADMINSuperuser privileges
CAP_NET_ADMINNetwork configuration modification
CAP_SYS_MODULEKernel module loading
CAP_SYS_TIMESystem clock modification
CAP_SYS_BOOTSystem reboot
CAP_SYS_NICEProcess priority modification
CAP_SYS_RESOURCEBypass resource limits
CAP_SYS_RAWIODirect I/O port access
CAP_SYS_PTRACEProcess tracing
CAP_SYS_CHROOTRoot directory modification
CAP_MKNODDevice file creation

4.2 Seccomp System Call Filtering​

The App Manager loads a Seccomp configuration file when starting a container. The default policy uses a whitelist mode (defaultAction: SCMP_ACT_ERRNO), allowing only common system calls. The configuration file path is set by the platform administrator; developers do not need to be concerned with it.

4.3 Filesystem and Namespace Isolation​

Security MechanismDefaultOverridable via app.yaml
no_new_privilegestruesecurity.no_new_privileges: false
readonly_rootfstruesecurity.readonly_rootfs: false
PID namespace isolationIndependentNot overridable
Mount namespace isolationIndependentNot overridable
UTS namespace isolationIndependentShared in host network mode
Network namespace isolationIndependentShared when permissions.network.mode: host
IPC namespace isolationIndependentShared with host IPC when a multi-container main container declares a video stream (required for DMA-BUF mmap)
PIDs limit128Not overridable

4.4 Network Isolation​

  • Isolated mode (default): The container has an independent network namespace and can only access external addresses through the outbound whitelist.
  • Host mode: The container shares the host network stack and can declare ports to listen on via inbound. Suitable for scenarios that require exposing services externally, such as RTSP streaming.

4.5 Socket Access Mechanism​

The platform mounts the /run/aipc directory into all containers. This directory contains all IPC Sockets. Containers gain access through the AIPC group GID (1001). This mechanism is automatically injected by the platform; developers do not need to add user group configurations in the Dockerfile.

5. Multi-Container Configuration​

When an application requires process-level isolation, multi-container mode can be used. For example, splitting the inference engine and business logic into separate containers enables independent updates and resource limits.

5.1 Architecture Model​

RolePlatform Service AccesspermissionsTypical Use
mainHas access to AI Runtime, Event Bus, and other platform SocketsCan be declaredBusiness logic, platform interaction
subNone, fully isolatedCannot be declaredIndependent algorithm processes, third-party services

Constraints:

  • There must be exactly one container with role: main
  • Sub containers cannot declare any permissions
  • Containers communicate with each other through shared network namespace

5.2 Complete Example​

apiVersion: v1
kind: Application
metadata:
id: smart_detection
name: Smart Detection
version: 1.0.0
spec:
containers:
main:
image: smart-detection-main:1.0
role: main # Must be declared
permissions:
video: [sub.raw]
inference:
models: [hailo_yolov8n_384_640]
resources:
cpu: "100%"
memory: "512Mi"
ports:
- containerPort: 8080
protocol: TCP
name: http # Service discovery name
env:
- name: SUB_DETECTOR_ADDR
value: "detector:50051"
volumes:
- name: shared-data # Container-level volume mount
container: /app/shared
readonly: false
security:
readonly_rootfs: false

detector:
image: smart-detection-detector:1.0
role: sub # Sub container, cannot declare permissions
resources:
cpu: "50%"
memory: "256Mi"
ports:
- containerPort: 50051
protocol: TCP
command: ["/app/detector"] # Override ENTRYPOINT
args: ["--workers=4"] # Append arguments

networking:
mode: internal # internal (default) | bridge | host
ingress:
- port: 8080 # External port
target: main:8080 # Target container:port
protocol: HTTP # HTTP | TCP | UDP

lifecycle:
startup_order: [detector, main] # Start sub first
shutdown_order: [main, detector] # Stop main first

volumes: # Application-level shared volumes (visible to all containers)
- host: /opt/aipc/data/smart_detection
container: /app/data

5.3 ContainerSpec Field​

Each container (entries under containers) supports the following fields:

FieldTypeDescription
imagestringContainer image
rolestringmain or sub
permissionsobjectPermission declarations (only main container can declare)
resourcesobjectResource limits (cpu, memory)
envarrayEnvironment variable list
portsarrayPort declaration list, each item contains containerPort, protocol, name
commandstring[]Override image ENTRYPOINT
argsstring[]Append arguments
healthcheckobjectContainer-level health check
volumesarrayContainer-level volume mounts, each item contains name, container, readonly
securityobjectContainer-level security configuration (inherits application-level spec.security when not set)

5.4 Network Modes​

ModeDescriptionUse Case
internalContainers share network namespace, not externally accessible (default)Internal microservice communication
bridgeConnect to LAN via aipc-br0 bridgeServices requiring LAN discovery
hostShare host network stackServices that need to expose ports externally

5.5 Startup and Shutdown Order​

  • startup_order -- Specifies the container startup order. When not specified, all sub containers are started first, then the main container.
  • shutdown_order -- Specifies the container stop order. When not specified, it defaults to the reverse of the startup order (stop main first, then sub).

5.6 Auto-Injected Environment Variables​

In multi-container mode, the platform automatically injects the following environment variables for each container:

VariableDescription
APP_IDApplication ID (from metadata.id)
APP_ROLEContainer role (main or sub)
CONTAINER_NAMEContainer name (key name in containers)
AIPC_HOST_PREFIXPlatform deployment path prefix (e.g., /data/aipc)

6. Lifecycle Management​

The complete lifecycle from installation to uninstallation is managed by the App Manager:

PhaseCLI CommandDescription
installaipc-cli app install <yaml> <tar>Import image, validate manifest, register to application repository
startaipc-cli app start <id>Preload models, create container, start running
stopaipc-cli app stop <id>Gracefully stop container (default timeout 10 seconds)
uninstallaipc-cli app remove <id>Stop container, delete image and instance data, unregister
updateStop + uninstall old version, then install + start new versionHot update is not currently supported; manual replacement required

Installation Methods:

  • Local image file -- Pass a .tar or .tar.gz file, which is directly imported into containerd.
  • Remote image registry -- Pass an image reference (e.g., docker.io/my/app:1.0), which is automatically pulled and normalized to a full reference.

Fault Recovery:

  • At startup, overlayfs snapshot corruption is detected (common after power loss), and the image is automatically re-unpacked from the content store.
  • At installation, the image tar backup is saved for rebuilding after power loss recovery.

7. Environment Variable Reference​

Container environment variables automatically injected by the platform:

VariableSourceDescription
APP_IDmetadata.idApplication unique identifier
APP_ROLEcontainerSpec.roleContainer role (multi-container mode only)
CONTAINER_NAMEcontainers key nameContainer name (multi-container mode only)
AIPC_HOST_PREFIXPlatform configurationDeployment path prefix, used for path conversion
<Custom>spec.envVariables declared by the user in app.yaml

Connection configuration variables automatically read by the SDK (usually no modification needed; the platform provides them through Socket mounting):

VariableDefaultDescription
AI_RUNTIME_ENDPOINTunix:///run/aipc/ai-runtime.sockAI Runtime gRPC endpoint
EVENT_BUS_ENDPOINTunix:///run/aipc/event-bus.sockEvent Bus gRPC endpoint
DEVICE_CONTROL_ENDPOINTunix:///run/aipc/device-control.sockDevice control gRPC endpoint
CAMERA_CONTROL_ENDPOINTunix:///run/aipc/camera-control.sockCamera control gRPC endpoint
SHM_BASE_PATH/run/aipc/shmShared memory base path
LOG_LEVELINFOLog level
DEBUG0Debug mode switch