1. Introduction
With the i-PRO Camera SDK that supports Container AdamApp, you can run containers with various configurations in the i-PRO camera by describing the app configuration in a Docker compose configuration file. This allows you to create new feature extension software in the form of a Docker containerdevelop camera application as docker application, and if you have already developed a Docker container that runs running on PC or another server or device, you can easily run port it on the camera by porting it according to this documentto camera. This document explains how to create a Container AdamApp with multiple containers using the docker_multi_images sample app included in the SDK as an example.
2. Overview
2.1
...
Design docker container architecture
Info |
---|
Please refer here for information on which to choose between the existing AdamApp, Container AdamApp and Cotainer AdamApp for AzureIoT, and the ext version of Container AdamApp. |
...
Azure IoT Edge. |
The container configuration depends on Docker compose configuration file (docker-compose.yaml). In the docker-compose.yaml file, you can start multiple containers
Multiple containers also work by specifying multiple service names in the file.
Below is a conceptual diagram showing Following diagram shows the difference in configuration between the conventional AdamApp(not the docker) and the example of Container AdamApp.
Drawio | ||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
The above is a conceptual diagram the example of running multiple containers within one extension software camera application (one ext format binary), but since the new X Series cameras allow for multiple apps to be installed, it is also possible to run multiple independent apps simultaneously.The following are guidelines for selecting the configuration depending on the application.
There are some options and the following are guidelines for selecting the architecture.
No. | Use Cases | Configure the app | Conceptual diagram | ||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1If | you want to containerize an app that has already been developed using Port existing docker application for AI processing on PC or another device to i-PRO CAMERA SDKAn existing app is simply containerized, creating one camera. | One app with one container configuration | |||||||||||||||||||||||||||||||||||||||||
Drawio | . Process to get video image and AI processing need to be replaced by ADAM API |
| |||||||||||||||||||||||||||||||||||||||||
2 | If you want to port an AI app developed for a device other than the iConvert exiting AdamApp (conventional i-PRO camera to the app) to Container AdamApp | An existing app is simply containerized, creating one app with one container. | |||||||||||||||||||||||||||||||||||||||||
3 | Port existing docker application without AI processing on PC or another device to i-PRO camera. | One app with one container configuration, replacing the AI functions and video acquisition parts of the existing app with the ADAM API | 3 | If you want to easily port an app that does not have AI functions and has been developed for devices other than the i-PRO camera to the i-PRO camera | One app that consists of two containers: one with management functions for i-PRO cameras and one that runs existing apps. | Drawio | | ||||||||||||||||||||||||||||||||||||
mVer | 2 | ||||||||||||||||||||||||||||||||||||||||||
simple | 0 | ||||||||||||||||||||||||||||||||||||||||||
zoom | 1 | ||||||||||||||||||||||||||||||||||||||||||
inComment | 0 | ||||||||||||||||||||||||||||||||||||||||||
pageId | 1474888488 | custContentId | 1532593214
| 4 | If you want to port an app with multiple container configurations, such as OSS, that has been developed for devices other than the i-PRO camera to the i-PRO camera | A container with management functions for i-PRO cameras and one application with multiple existing container configurations |
| ||||||||||||||||||||||||||||||||||||
5 | If you want to port two loosely related apps that do not communicate directly between each other and are developed by different companies to an i-PRO camera4 | Port two existing docker applications that has no relation each other. | Two apps |
| |||||||||||||||||||||||||||||||||||||||
6 | If you have multiple apps that want 5 | Multiple containers that both need to use the ADAM API | Two apps |
2.2 Configuration for
...
multiple containers
The dockersample application “docker_multi_images included in the SDK is a sample app that can be used as a reference if you choose use case 3 or 4 images” is the reference, especially for use case No.3 in Chapter 2.1. The docker_multi_images This sample app consists of two Docker images.
docker_multi_images image
It exists to start and stop This is for starting/stopping the application from the by camera body and to respond to firmware and for internal keep-alive messagesbetween application and firmware. In this document, it is called the "main image." Also, the container generated from this image is called the "main container." The sample application only runs an event loop and waits. It should be is built with using i-PRO CAMERA SDK.web image
This image is based on the lightweight version of nginx published on DockerHub, with only the default configuration file (default.conf) replaced. This document calls it a "subimage." Also, a container generated from this image is called a "subcontainer." It exposes nginx's TCP 80 port is associated to the outside as TCP 8081 port and accepts for http requests access from external devices. When creating Container AdamApp, it must be built as a Docker image in advancedevice. It is necessary to build as docker image before creating Container AdamApp using i-PRO CAMERA SDK.
If you want to run an existing container on an i-PRO camera, you can add the docker_multi_images image for management from the camera, and the existing container can be run on the camera with minimal changes.
Drawio | ||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
2.3 Porting Considerations
When running an existing container on an i-PRO camera, you need to consider the following three points:
Are there enough Camera resources RAM/ROM/CPU resources?Does it comply with the
Data storage
i-PRO camera security policy?
Is there only one container that uses the enough for using ADAM API?
These are explained below.
2.3.1 RAM / ROM /
...
新Xシリーズカメラが機能拡張アプリケーションで使用できるリソースは i-PROカメラへのソフトウェアインストール条件 - チュートリアル・FAQ - Development Partner Portal をご参照ください。
...
CPU resources
Please see here for resources for CV52 cameras that support docker capability.
Please make sure the app you are porting can work within these limits.
RAM/CPU limits are enforced by cgroups. If RAM usage exceeds the limit, the app will be killed by the OOM Killer.
2.3.2
...
Container AdamAppに関するセキュリティポリシーの詳細は アプリの開発と動作確認方法(Container Adamapp編) - チュートリアル・FAQ - Development Partner Portal (i-pro.com) をご覧ください。
移植に関して特に考慮する内容を説明します。
...
コンテナはroot権限で動作させることはできません。
カメラ内ではuid 1000、gid 1000のユーザー権限でアプリが動作します。
...
コンテナはread onlyでマウントされます。
コンテナ内に書き込みを行うことはできません。既存のアプリがコンテナ内に書き込みを行っている場合、一時的なデータであればtmpfs、永続的なデータであればボリュームを別途マウントし、そちらに書き込む必要があります。
...
--previledgedなどのセキュリティを緩和するオプションは使用できません。
...
Data storage
By mounting a volume, application can write data to the flash memory inside the camera. Since there is a limit to the number of times data can be written to flash memory,
Please use SD card for storing data if application needs to write frequently.
It is also possible to create a database SQLite on the SD card. This is implemented in the sample app sqlite_app.
2.3.3
...
Container AdamAppに複数のコンテナが含まれている場合、ADAM APIが使用できるコンテナはメインコンテナのみとなり、サブコンテナからは使用できません。
カメラの機能を使用したい場合は、メインイメージ内に実装し、カメラに依存しない汎用的な機能をそのままカメラ上で動かしたい場合はサブイメージ内に実装することをお勧めします。
メインイメージ・サブイメージ間のデータ共有は、3.4章で説明します。
3. 開発手順
3.1 プロジェクトの作成
プロジェクトディレクトリの準備
SDKのサンプルアプリに含まれる iPRO_CAMERA_SDK/src/adamapp/docker_multi_images をコピーし、任意の名前にリネームします。ディレクトリ名がメインイメージのイメージ名と一致するとわかりやすいため、全て小文字にすることを推奨します。
container/docker-compose.yaml に含まれる「docker_multi_images」という文字列をメインイメージの名前に一括変換します。
メインイメージのバイナリ (multiImages) は特に変更する必要はありません。変更する場合は、Configuration.txt及びMakefileの編集も実施する必要が有ります。
アプリの情報記載
configuration.txtを開き以下の項目を編集します。
アプリバージョン名
カメラブラウザの管理画面上に表示されるバージョン情報となります。メインイメージのタグ名と合わせるとわかりやすいです。アプリ名
カメラブラウザの管理画面上に表示されるアプリ名となります。各言語で記述することが可能です。リソース関連情報
アプリが使用するROM/RAM/CPU使用率 (申告値)を記載します。インストール時に他のアプリで申告された値の合計が制限を超えていないかチェックするために使用されます。全アプリの申告値の合計が制限を超える場合、アプリはインストールに失敗します。ライセンス関連情報
i-PROより割り当てられたFUNC IDを指定してください。
3.2 サブイメージ (移植対象イメージ) の準備
既存のコンテナイメージを移植する場合はそのイメージをサブイメージとして作成します。
Info |
---|
SDKのビルドスクリプトではサブイメージをビルドしませんので、事前に開発者自身でイメージを用意する必要があります。 |
別途DockerfileやDocker Composeを利用してサブイメージをビルドします。ビルド時のアーキテクチャ (プラットフォーム) はarm64を指定してください。
以下は、docker_multi_images内に含まれるnginxのイメージの準備を例に説明します。
...
docker_multi_images/web ディレクトリ以下にnginxのイメージに必要なファイルが含まれています。
web ディレクトリ以下に移動します。
Code Block |
---|
cd [iPRO_CAMERA_SDKディレクトリ]/src/Aadamapp/[アプリディレクトリ]/web |
docker imageをビルドします。
Code Block |
---|
docker build -t web:0.0.1-arm64v8 . |
...
dockerイメージがビルドされ開発環境に存在することを確認します。
Code Block |
---|
docker images |
出力例
Code Block |
---|
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
web 0.0.1-arm64v8 78a72756f85e 16 hours ago 16.6MB |
3.3 docker-compose.yaml の編集
docker-compose.yaml内にサブイメージに関する情報を記載します。 docker-compose.yamlの記述方法自体については、 https://docs.docker.jp/compose/compose-file/index.html などをご参照ください。
Info |
---|
ここで編集するdocker-compose.yaml はカメラ内でアプリ起動時に実行されます。 ファイル内でbuild コマンドを使用することはできません。 |
services キーの子レベルにサブイメージの情報を追加します。 サンプルアプリではすでに記載されていますのでその内容を説明します。
webサービスについての全体の記載は以下となります。
images:
ここには3.2で作成したイメージ名とタグを指定します。ここで指定したイメージが存在しない場合、アプリのビルドスクリプトは失敗します。networks:
コンテナ間で通信したい場合、同じネットワークを指定する必要があります。restart:
コンテナが終了したときにどのように復旧するかを指定します。ext形式Dockerの場合、メインコンテナはDockerの仕組みを使用せずにカメラファームウェアによって監視されるため、noを指定することで、適切に再起動します。一方サブコンテナはカメラファームウェアから監視されませんので、実動作に合わせて設定します。ports:
サブイメージが外部から接続できるポートを公開する場合、[カメラ側]:[コンテナ側]の書式で記載します。volumes:
ボリューム、バインドマウントを記載します。
volumeはこのdocker-compose.yaml内で定義されているボリュームのみ指定できます。また、ここに定義されているvolume名は別途yamlファイルトップのvolumes: セクションにも記載する必要があります。
バインドマウントできるディレクトリパスには制限があります。tmpfs:
セキュリティポリシーによりコンテナ内には書き込めないため、/var以下などのアプリが一時的に保存するディレクトリがある場合はここに指定します。
nginxの場合、 /var/cache/nginx、/var/run 以下に書き込みますので、これらをtmpfs として指定しています。必須のパラメータ
以下パラメータはi-RPOカメラのセキュリティポリシーを満たすために付与が必要です。 このままコピー&ペーストしてください。Code Block read_only: true user: 1000:1000 cap_drop: - "net_raw" security_opt: - "label=type:ipro-container.process" - "no-new-privileges" labels: com.i-pro.app-type: "ext" com.i-pro.device-category: "CV5x-A" com.i-pro.device-vendor: "i-PRO"
ルートレベルのvolumesの記載
yamlファイルのルート (トップ) 以下のvolumes: セクションに、ボリューム名を記載します。
3.4 独自の機能を実装する
3.4.1 コンテナ間の通信やデータ共有
メインイメージ・サブイメージ間や、コンテナとカメラ間でデータをやり取りするには以下の方法があります。
...
volumeを使用する。
docker-compose.yamlに記載することでvolumeをコンテナ間で共有することができますのでこの中でデータをやり取りできます。ただしこの領域はFlashROM上となり、寿命に影響がありますので大量なデータのやり取りには向きません。
共有が許可されているtmpfsを使用する。
ADAM_GetTmpDirPath() APIで取得できる領域はtmpfs上にあり、一時的なデータ保存用として利用できます。
サブコンテナからこの領域にアクセスするためには、docker-compose.yamlのサブイメージの記述内のvolumes: に以下を追加します。
...
About our security policy
Followings are important points when porting. For more information on Container AdamApp's security policy, please see here.
Containers cannot be run with root privileges. The app runs in the camera with user privileges of uid 1000, gid 1000.
The container is mounted read only.
You cannot write to the container. If an existing app is writing to the container, it will need to write to a tmpfs(RAM) for temporary data, or to a separate mounted volume for persistent data.Options that relax security, such as --previledged, cannot be used.
Docker images cannot be pulled from an external container registry directly from within the camera. The required docker images must be pulled and built on the development PC and included in the Container AdamApp(ext file).
Info |
---|
Impact of mounting data directories as read only in containers For the ADAM API, ADAM_GetAppDataDirPath is provided as an API that returns the path of the data directory on the flash ROM. For the Container AdamApp, this directory is read-only and cannot be written to. If you want to write data, use a volume. |
2.3.4 Restrictions on using ADAM API
2.3.4.1 Containers that can use the ADAM API
If Container AdamApp contains multiple containers, the ADAM API can only be used from the main container, not from sub containers.
It is better that main image has feature related to camera functions and sub images have features not related to camera functions. Chapter 3.4 shows how to share the data between main and sub images.
2.3.4.2 Directory path that can be obtained with ADAM API
The various directory paths that can be obtained by AdamApp, Container AdamAPp, and Container AdamApp for Azure IoT are shown in the table below. As mentioned in Chapter 2.3.3, in Container AdamApp, the paths that can be obtained by ADAM_GetAppTmpDirPath are read-only areas. In addition, the directories that can be obtained by ADAM_GetAppTmpDirPath are shared with the host side (camera body). Therefore, when temporarily storing data that you do not want to be accessed from the host side, please use the area defined in the tmpfs section of docker-compose.yaml.
| AdamApp | Container AdamApp | Container AdamApp for Azure IoT |
---|---|---|---|
ADAM_GetAppTmpDirPath | /dev/shm/Adamapp/[App-specific ID] | /dev/shm/Adamapp/[App-specific ID] | /tmp/local/appdata |
ADAM_GetAppDataDirPath | /app/data | /app/data | /ai_data |
3. Development Procedure
3.1 Create a project
Preparing the project directory
Copy iPRO_CAMERA_SDK/src/adamapp/docker_multi_images included in the SDK sample app and rename it to any name. It is recommended to use lowercase for all directory names to make it easier to understand if the directory name matches the image name of the main image.
Convert the string "docker_multi_images" contained in container/docker-compose.yaml to the name of the main image in one go.
There is no need to change the main image binary (multiImages). If you want to change it, you will also need to edit Configuration.txt and Makefile.
App information description
Open configuration.txt and edit the following items.
App Version Name
This is the version information displayed on the camera browser management screen. It is easy to understand if you match it with the tag name of the main image.App Name
This will be the app name displayed on the camera browser management screen. It can be written in any language.Resource Related Information
Describes the ROM/RAM/CPU usage (declared value) used by the app. This is used to check whether the total of the values declared by other apps at the time of installation exceeds the limit. If the total of the declared values of all apps exceeds the limit, the app will fail to install.License related information
Default value is OK for starting development. When you completed, please request FUNC ID to i-PRO and relace this value.
3.2 Preparing the sub-image (the image to be ported)
If you want to port an existing container image, create it as a subimage.
Info |
---|
The SDK build script does not build sub-images, so developers must prepare the images themselves in advance. |
Build a sub-image using a separate Dockerfile or Docker Compose. Specify arm64 as the architecture (platform) when building.
The following explains how to prepare the nginx image included in docker_multi_images as an example.
The docker_multi_images/web directory contains the files required for the nginx image.
Navigate to the web directory.
Code Block cd [iPRO_CAMERA_SDK directory]/src/Aadamapp/[app directory]/web
Build the docker image.
Code Block docker build -t web:0.0.1-arm64v8 .
Verify that the Docker image is built and exists in your development environment.
Code Block docker images
Example output
Code Block $ docker images REPOSITORY TAG source: "/dev/shm/Adamapp" IMAGE ID CREATED read_only: false SIZE web consistency: default
ただし、サブコンテナからはADAM_GetTmpDirPath()を呼ぶことができませんので、別途volumeを使う方法などでメインコンテナからパスを通知する必要があります。
HTTP経由で取得する。
Dockerでは各コンテナに仮想のIPアドレスが割り当てられるため、こちらを利用して、カメラ外と同様にWebAPIを呼ぶことができます。また、docker-compose.yamlのhostnameキーでドメイン名を指定すると、この名前で通信を行うこともできます。
メインコンテナでは、ADAMの仕組みとして、sendDataToAdamApplication WEB APIを使用して通信を行うことができます。この仕組みはカメラ本体がメインコンテナにデータを仲介する方法ですので、あて先はカメラ本体のIPアドレスとなります。
また、同様にカメラのCGIを利用してカメラ本体の設定値などを取得することができます。
Info |
---|
コンテナ内から仮想環境上のカメラ本体のIPアドレスはコンテナ内から/etc/hostsを参照し、一番最後のエントリの最下位バイトを1にしたものとなります。 WebAPIでアクセスする際、カメラのユーザー名・パスワードの指定が必要です。 |
3.4.2 サンプルアプリの実装例
...
0.0.1-arm64v8 78a72756f85e 16 hours ago 16.6MB
3.3 Editing docker-compose.yaml
Write information about the sub-image in docker-compose.yaml.
For information on how to write docker-compose.yaml, please see here etc.
Info |
---|
The docker-compose.yaml you edit here will be executed in the camera when the app starts. You cannot use the build command in the file. |
Add the sub-image information to the child level of the services key. This is already written in the sample app, so we will explain the contents here.
The complete description of the web service is as follows:
images:
Here you specify the image name and tag created in 3.2. If the image specified here does not exist, the app build script will fail.networks:
If you want containers to communicate with each other, they must specify the same network.restart:
Specifies how to recover when the container is terminated. In the case of ext format Docker, the main container is monitored by the camera firmware without using Docker mechanisms, so specifying "no" will restart it appropriately. On the other hand, subcontainers are not monitored by the camera firmware, so set it according to the actual operation.ports:
If the sub-image exposes a port that can be connected from outside, describe it in the format of [camera side]:[container side].volumes:
Describes volumes and bind mounts.
Only volumes defined in this docker-compose.yaml can be specified for volume. In addition, volume names defined here must also be separately listed in the volumes: section at the top of the yaml file.
There are restrictions on directory paths that can be bind mounted.
Data is written to the camera's internal flash memory. Since there is a limit to the number of times data can be written to flash memory, if you plan to write data frequently, we recommend using tmpfs or an SD card.tmpfs:
Security policies prevent writing to containers, so if there are directories under /var where apps temporarily store data, specify them here.
In the case of nginx, it writes to /var/cache/nginx and /var/run, so these are specified as tmpfs.
The data is written to the camera's internal RAM.Required parameters
The following parameters must be added to satisfy the security policy of the i-PRO camera. Please copy and paste as is.Code Block read_only: true user: 1000:1000 cap_drop: - "net_raw" security_opt: - "label=type:ipro-container.process" - "no-new-privileges" labels: com.i-pro.app-type: "ext" com.i-pro.device-category: "CV5x-A" com.i-pro.device-vendor: "i-PRO"
Listing root-level volumes
Enter the volume name in the volumes: section under the root of the yaml file.
3.4 Implementing your own functionality
3.4.1 Communication and data sharing between containers
There are the following methods to exchange data between the main image and sub-image.
volume.
By writing this in docker-compose.yaml, you can share volumes between containers, so you can exchange data within them. However, this is on FlashROM, and it affects the lifespan, so it is not suitable for frequent data exchange.tmpfs
The directory obtained with the ADAM_GetTmpDirPath() API is on tmpfs(RAM) and can be used to store temporary data.
To access this area from a subcontainer, add the following to volumes: in the subimage description in docker-compose.yaml.Code Block - type: bind target: "/dev/shm/Adamapp" source: "/dev/shm/Adamapp" read_only: false consistency: default
However, since ADAM_GetTmpDirPath() cannot be called from a subcontainer, you must notify the path from the main container using a separate volume, etc.
Local HTTP communication.
In Docker, each container is assigned a virtual IP address, which can be used to call the WebAPI in the same way as outside the camera. Also, when you specify a domain name in the hostname key of docker-compose.yaml, you can communicate using this name.
In the main container, ADAM WEB API sendDataToAdamApplication can be used to send data via HTTP. In this case, destination IP address will be camera firmware’s IP address. Main container will receive the data. In the same way, you can also use the camera firmware's API(CGI) to get camera setting or control camera's function, for example.
Info |
---|
The IP address of the camera in the virtual environment can be found from within the container by referencing /etc/hosts from within the container and setting the least significant byte of the last entry to 1. When accessing via WebAPI, you must specify the camera's user name and password. |
3.4.2 Example implementation of sample app
The sample application “docker_multi_images” uses the DNS function of the inter-container network to implement sample code that sends an HTTP request from the main container to a sub-container by container name.
The response_by_html function in ${SDK_DIR}/adamapp/docker_multi_images/main.cpp の response_by_html関数内で以下の様にcurlでリクエストを行うsystem関数を呼び出しています。 ここで “web” はdocker-compose.yamlに記載されているサービス名となります。calls the system function that makes a request with curl as follows. Here, “web” is the service name written in docker-compose.yaml.
Code Block |
---|
char cmd[256];
snprintf( cmd, 256, "curl http://web/index.html > /tmp/local/index.html");
if( system(cmd) != 0 ) {
ADAM_DEBUG_PRINT(ADAM_LV_ERR, "system error (%s)\n", cmd);
} |
カメラブラウザの「ソフトウェア管理画面」に表示された、「Dockerマルチイメージ」アプリの「設定画面へ」ボタンを押下することで、このコードが呼び出され、webコンテナのindex.htmlの内容をそのままブラウザに表示します。
3.5 アプリのビルド
開発環境構築については下記を参照ください。
...
, "system error (%s)\n", cmd);
} |
By pressing the "Go to Settings Screen" button for the "Docker Multi-Image" app displayed on the "Software Management Screen" of the camera browser, this code will be called and the contents of index.html of the web container will be displayed directly in the browser.
3.5 Building the app
Please refer to the following for information on building a development environment.
アプリ開発方法やビルドについては下記を参照ください。
開発方法(how develop編Please see below for information on how to develop and build apps.
How to develop(Container AdamApp) - Technology Partner FAQ (En) - Confluence (atlassian.net)