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
ugclito create a Docker app project - Write the application configuration file
project.yaml - Write
docker-compose.yamland configure compose variables - Copy the application image to the
imagesdirectory of the corresponding architecture in the app project - Create the application icon and copy it to the
rootfs_commondirectory of the app project - Use the developer tool
ugclito 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:
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:
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:
# 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.0Ultimately, 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:
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, onlyicon.pnganddocker-compose.yamlfiles are allowed. - Under each architecture directory, only the
images/directory is allowed, and only.tarimage 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_versionto depend on the Docker suite - Define configurable items during installation through
parameters, these configuration items will be used as variables in compose
Example:
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.cnparameters 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:
| Field | Type | Required | Description |
|---|---|---|---|
key | string | Yes | Configuration item identifier (variable name), it is recommended to use uppercase with underscores, such as ACCOUNT, LOG_LEVEL. |
type | string | Yes | Configuration item type, optional: string, path, number, password. |
multi | bool | No | Whether to support multiple values. |
required | bool | No | Whether it is required. |
changeable | bool | No | Whether it is allowed to be modified after installation is complete. |
max_length | int | No | Maximum input length, 0 means no limit. |
min_length | int | No | Minimum input length, 0 means no limit. |
max_values_count | int | No | Maximum number of configurable values, only effective when multi: true. |
verify_regexp | string | No | Regular expression for verifying input values, empty means no verification. |
i18n | map | Yes | Multilingual 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:
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Configuration item name (display name on the interface). |
description | string | Yes | Configuration item description (filling specification, format constraint, example, etc.). |
Configuration item type description:
type Value | Meaning | Typical Scenario | Example Value | Remarks |
|---|---|---|---|---|
string | Ordinary string | Text parameters such as account, switch identifier, log level | admin, INFO | Can be combined with min_length / max_length / verify_regexp for format constraints. |
path | Path type string | Directory or file path mounted in the container | /mnt/user/data | Can be used with multi: true when multiple paths are required. |
number | Number type input | Numerical parameters such as port, retry count, threshold | 8080, 3 | When configured by the user, the input is restricted to numbers only. |
password | Sensitive string | Sensitive information such as password, token, secret key | MySecret123 | Used for input items that need to be hidden. |
multiis recommended to be mainly used in thetype: pathscenario (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 inparameters, and the variable nameVARmust be consistent with thekeyof the configuration item.
Variable Sources
Built-in variables (No need to declare in
parametersofproject.yaml, injected by the Docker suite during installation):TZ: Time zone, for exampleAsia/Shanghai
Installation parameter variables: Correspond one-to-one with the
keyofparametersinproject.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.
- If a variable is used in compose, the corresponding key should be defined in
Example (correspondence between project.yaml and compose):
# project.yaml
parameters:
- key: PATH
type: path
multi: true
required: true
- key: ACCOUNT
type: string
required: true
- key: LOG_LEVEL
type: string
required: falseReference Variables in Compose
In docker-compose.yaml, you can directly reference the above variables, for example:
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:
imagemust be consistent with the tag included in the image in the tar file placed inrootfs_<arch>/images/, andlatestcannot be used. - Multi-value parameters: When
type: pathandmulti: trueinparameters, 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 usinghostnetwork. It will be detected and alerted during packing. - Only use keys declared in
parametersor built-in variables (such asTZ) 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 examplerootfs_amd64/images/myapp-0.1.0.tar - arm64: under
rootfs_arm64/images/, for examplerootfs_arm64/images/myapp-0.1.0-arm64.tar
- amd64: under
- 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:
ugcli pack --build 1--buildis the build number, which together withversioninproject.yamlforms the final version number (for example, if0.1.0uses build number1, the final version number is0.1.0.1).- You can specify
--arch amd64or--arch arm64to pack only a certain architecture, defaulting to generate according tosupport_arch.
The generated UPK file is located in build_dir/, with the naming format: {amd64|arm64}_{appid}_{version}.upk.