Skip to content

Docker Application Development

Docker Application development on UGOS Pro system mainly includes the following steps:

  • Prepare the application image (build and export as a tar file)
  • Use the developer tool ugcli to create a Docker app project
  • Write the application configuration file project.yaml
  • Write docker-compose.yaml and configure compose variables
  • Copy the application image to the images directory of the corresponding architecture in the app project
  • Create the application icon and copy it to the rootfs_common directory of the app project
  • Use the developer tool ugcli to pack the app

The following will introduce how to pack a Docker app from scratch and generate a UPK installation package, including project structure, configuration instructions, and compose settings.

Prepare Application Image

A Docker app is based on a Docker image. You need to complete the building and exporting of the image first.

Build Image

Use a Dockerfile to build the image locally or in CI, and ensure the image can run on the target architecture (such as amd64, arm64). Example:

dockerfile
FROM alpine:3.18
RUN apk add --no-cache your-runtime
COPY . /app
WORKDIR /app
ENTRYPOINT ["/app/entrypoint.sh"]

Build and tag the image, for example:

shell
docker build -t docker.io/mycompany/myapp:0.1.0 .

Export as tar

Use docker save to export the image and generate a tar file. Example:

shell
# Export the current architecture image as tar (you can export one for amd64/arm64 as needed)
docker save -o myapp-0.1.0.tar docker.io/mycompany/myapp:0.1.0

Ultimately, you need to prepare at least one image tar file for each supported architecture and place it in the project directory rootfs_<arch>/images/ in subsequent steps.

Application image tar file specification

  • All images used by the application need to be exported as independent tar files.
  • Each image tar file can only have one tag, which must be consistent with the configuration used in docker-compose.
  • If the application supports both amd64 and arm64 architectures, you need to export the tar files for both architectures respectively.

Create Application Project

Run ugcli create com.mycompany.docker.myapp to create an application project. In the interactive prompt, select Yes for "Is it a Docker application?". After creation, a project directory will be generated in the current directory with the following structure:

shell
com.mycompany.docker.myapp
├── project.yaml              # Application configuration file
├── rootfs_amd64              # amd64 architecture
   └── images                # Place the image tar file for this architecture
├── rootfs_arm64              # arm64 architecture
   └── images                # Place the image tar file for this architecture
└── rootfs_common             # Shared by all architectures
    ├── icon.png              # Application icon
    └── docker-compose.yaml   # Compose orchestration file (see next section)

Directory specification

  • Under rootfs_common, only icon.png and docker-compose.yaml files are allowed.
  • Under each architecture directory, only the images/ directory is allowed, and only .tar image files can be placed inside it.

Write Application Configuration File

Modify project.yaml in the project root directory to configure the basic information of the application and the required configuration items for the Docker app. The main differences between a Docker app and a native app are as follows:

  • Must set is_docker_app: true
  • Must set depend_docker_version to depend on the Docker suite
  • Define configurable items during installation through parameters, these configuration items will be used as variables in compose

Example:

yaml
spec_version: "2.1"
app_id: com.mycompany.docker.myapp
version: 0.1.0
support_arch:
  - amd64
  - arm64
is_docker_app: true
only_admin: true
port: 29090
open_type: tab
tag_types:
  - utility
depend_fw_version: 1.13.0.0000
depend_docker_version: 1.7.0.0000
parameters:
  - key: PATH
    type: path
    multi: true
    required: true
    i18n:
      en-US:
        name: Resource Access Paths
        description: Multiple paths can be configured
      zh-CN:
        name: 资源访问路径
        description: 可配置多个路径
  - key: ACCOUNT
    type: string
    i18n:
      en-US:
        name: Login Account
        description: 6-8 characters
      zh-CN:
        name: 登录账号
        description: 长度6-8位
i18n:
  en-US:
    name: My Docker APP
    description: My Docker APP Desc
    author: My Company
    official: https://myapp.example.com
    help: https://myapp.example.com/help
    publisher: My Company
    publisher_link: https://mycompany.example.com
  zh-CN:
    name: 我的Docker应用
    description: 我的Docker应用描述
    author: 演示应用开发者
    official: https://myapp.example.com.cn
    help: https://myapp.example.com.cn/help
    publisher: 演示应用发布者
    publisher_link: https://mycompany.example.com.cn

parameters Configuration Item

parameters is an array where each element corresponds to a configuration item, used to declare variables that can be input when installing/configuring the application. The variable name referenced in Compose (${VAR}) needs to be consistent with the key of the configuration item.

Configuration item field description:

FieldTypeRequiredDescription
keystringYesConfiguration item identifier (variable name), it is recommended to use uppercase with underscores, such as ACCOUNT, LOG_LEVEL.
typestringYesConfiguration item type, optional: string, path, number, password.
multiboolNoWhether to support multiple values.
requiredboolNoWhether it is required.
changeableboolNoWhether it is allowed to be modified after installation is complete.
max_lengthintNoMaximum input length, 0 means no limit.
min_lengthintNoMinimum input length, 0 means no limit.
max_values_countintNoMaximum number of configurable values, only effective when multi: true.
verify_regexpstringNoRegular expression for verifying input values, empty means no verification.
i18nmapYesMultilingual display information, key is the language code (such as en-US, zh-CN), value is the configuration item name and description.

The i18n.<lang> field is as follows:

FieldTypeRequiredDescription
namestringYesConfiguration item name (display name on the interface).
descriptionstringYesConfiguration item description (filling specification, format constraint, example, etc.).

Configuration item type description:

type ValueMeaningTypical ScenarioExample ValueRemarks
stringOrdinary stringText parameters such as account, switch identifier, log leveladmin, INFOCan be combined with min_length / max_length / verify_regexp for format constraints.
pathPath type stringDirectory or file path mounted in the container/mnt/user/dataCan be used with multi: true when multiple paths are required.
numberNumber type inputNumerical parameters such as port, retry count, threshold8080, 3When configured by the user, the input is restricted to numbers only.
passwordSensitive stringSensitive information such as password, token, secret keyMySecret123Used for input items that need to be hidden.
  • multi is recommended to be mainly used in the type: path scenario (such as multiple mount paths).
  • Other types usually use a single value (multi: false) to avoid inconsistency with the actual usage of the variable.

Write Docker Compose File

For a Docker app, place docker-compose.yaml (standard Docker Compose format) under rootfs_common.

File Location and Format

  • Path: rootfs_common/docker-compose.yaml
  • Format: Standard Docker Compose (such as Compose Spec v2/v3), use variable syntax ${VAR} to reference the configuration items declared in parameters, and the variable name VAR must be consistent with the key of the configuration item.

Variable Sources

  1. Built-in variables (No need to declare in parameters of project.yaml, injected by the Docker suite during installation):

    • TZ: Time zone, for example Asia/Shanghai
  2. Installation parameter variables: Correspond one-to-one with the key of parameters in project.yaml (case-sensitive). The values filled in by the user during installation/configuration of the application will be substituted into compose.

    • If a variable is used in compose, the corresponding key should be defined in parameters.
    • It is recommended to use uppercase with underscores for variable naming (such as ACCOUNT, LOG_LEVEL) to distinguish them from ordinary strings.

Example (correspondence between project.yaml and compose):

yaml
# project.yaml
parameters:
  - key: PATH
    type: path
    multi: true
    required: true
  - key: ACCOUNT
    type: string
    required: true
  - key: LOG_LEVEL
    type: string
    required: false

Reference Variables in Compose

In docker-compose.yaml, you can directly reference the above variables, for example:

yaml
services:
  app:
    image: docker.io/mycompany/myapp:0.1.0
    volumes:
      - ./config:/opt/myapp
      - ${PATH}
    network_mode: bridge
    ports:
      - 29090:9090
    environment:
      - UMASK=022
      - TZ=${TZ}
      - ACCOUNT=${ACCOUNT}
      - LOG_LEVEL=${LOG_LEVEL}
    restart: always
  • Image: image must be consistent with the tag included in the image in the tar file placed in rootfs_<arch>/images/, and latest cannot be used.
  • Multi-value parameters: When type: path and multi: true in parameters, it will be processed as multiple values in compose (such as mounting multiple paths); other types are single values in the template.

Security and Specification Recommendations

  • Do not use privileged, cap_add, host pid/ipc, and avoid using host network. It will be detected and alerted during packing.
  • Only use keys declared in parameters or built-in variables (such as TZ) to avoid validation failure during packing caused by undefined variables.

Copy Application Image and Icon

  • Image: Place the image tar file of each architecture into the corresponding directory:
    • amd64: under rootfs_amd64/images/, for example rootfs_amd64/images/myapp-0.1.0.tar
    • arm64: under rootfs_arm64/images/, for example rootfs_arm64/images/myapp-0.1.0-arm64.tar
  • Icon: Create a 256×256 PNG icon (refer to the general icon specification) and replace rootfs_common/icon.png. (The default icon can be temporarily used during the development phase.)

Pack Application

Execute in the application project root directory:

shell
ugcli pack --build 1
  • --build is the build number, which together with version in project.yaml forms the final version number (for example, if 0.1.0 uses build number 1, the final version number is 0.1.0.1).
  • You can specify --arch amd64 or --arch arm64 to pack only a certain architecture, defaulting to generate according to support_arch.

The generated UPK file is located in build_dir/, with the naming format: {amd64|arm64}_{appid}_{version}.upk.