Docker开发
概述
Docker 应用运行在 TOS 7 Docker 引擎管理的容器中。
前提条件: Docker Engine 并非 TOS 7 预装组件。它作为应用在 TOS 应用中心提供,需要用户自行安装并启用。当用户安装基于 Docker 的应用时,平台会自动检测 Docker Engine,若缺失或未启用则提示安装 — 开发者无需额外操作。
核心要求:
- 必须提供兼容 Compose Spec 3.8+ 的
docker-compose.yml - 数据必须通过卷挂载持久化到 NAS 可访问目录
- 严格禁止使用特权模式
- 严格禁止占用系统核心端口(22、80、443、8181、5050)
目录结构
<appid>-docker/ # 仓库根目录
├── config.ini # 应用元数据
├── app.lang # 多语言文件(14种语言)
├── docker-compose.yml # 【必填】容器编排配置
├── .env.example # 【可选】环境变量示例
├── README.md # 双语文档
└── images/
└── icons/
└── <appid>.svg # 应用图标
docker-compose.yml 规范
version: "3.8"
services:
<appid>:
image: <registry>/<image>:<tag> # 镜像仅限 Docker Hub
container_name: <appid>
restart: unless-stopped
Volumes:
- /Volume*/DockerAppData/<appid>/config:/config
- /Volume*/DockerAppData/<appid>/data:/data
ports:
- "<宿主端口>:<容器端口>"
environment:
- TZ=Asia/Shanghai
user: "1000:1000"
x-app-meta:
web:
port: <宿主端口>
protocol: http
说明:
/Volume*/中的*代表用户安装时选择的卷号(例如 Volume1、Volume2)。
规则:
- 版本:必须兼容 Compose Spec 3.8 及以上
- x-app-meta:对于有 UI 的 Docker 应用,必须在
docker-compose.yml文件末尾(services 块之后)追加x-app-meta标签,包含web.port(Web UI 端口号)和web.protocol(请求协议,通常为http)。x-app-meta:
web:
port: 8080
protocol: http - 数据持久化:所有数据目录必须挂载到宿主路径。仅存储在容器内的数据会在容器删除时丢失。
- 端口映射:
- 禁用端口:22、80、443、8181、5050(系统服务)
- 推荐范围:8000-19999
- 提交前确认所选端口在 TNAS 上未被占用
- 特权模式:严格禁止。必须使用
user字段指定 UID/GID。 - 时区:默认配置
TZ=Asia/Shanghai。用户可自行修改。 - 容器名称:必须与应用
id一致 - 重启策略:普通服务使用
unless-stopped - 网络模式:
network_mode: host严格禁止,仅系统级网络工具除外。系统级网络工具需在提交时明确说明理由,经审核同意后方可使用。普通应用一律禁止。使用宿主机网络模式破坏容器隔离,存在安全风险。改用端口映射:ports:
- "8080:8080" - 时区:容器时区必须显式配置:
environment:
- TZ=Asia/Shanghai
- TZ=${TZ:-Asia/Shanghai} # 允许用户覆盖
请勿将时区留空 — 时间戳不一致会导致时间敏感应用数据损坏。
镜像与安全要求
-
镜像来源(仅限 Docker Hub):所有 Docker 镜像必须来自 Docker Hub,非 Docker Hub 镜像直接驳回。 镜像必须托管在 Docker Hub(hub.docker.com)。不支持其他镜像仓库(如 ghcr.io、quay.io、自建私有仓库等)。
优先级 来源 示例 1(首选) Docker Hub 官方项目镜像 nginx、postgres2 Docker Hub 已验证发布者 带 Verified badge 的 Docker Hub 镜像 3 Docker Hub 知名社区镜像 linuxserver/jellyfin(100M+ 拉取量、活跃维护)❌ 驳回 非 Docker Hub 来源的镜像 私有仓库、ghcr.io、quay.io 等 ❌ 驳回 Docker Hub 上未经验证的个人镜像 拉取量少、无文档的 Docker Hub 镜像
强制要求: 镜像必须托管在 Docker Hub 上。审核时将验证镜像来源。使用非 Docker Hub 镜像将被直接驳回。 来自非 Docker Hub 来源或未经验证的 Docker Hub 镜像将在安全审核中被驳回。
- 镜像体积:使用多阶段构建或 Alpine 基础镜像以减小体积。
- 敏感信息:禁止在镜像或 compose 文件中硬编码密码、Token 或密钥。使用环境变量或
.env文件。 - 安全扫描:提交前运行
docker scan或trivy检查已知漏洞。 - 用户权限:**严格禁止使用 root 用户,严格禁止使用
--privileged特权模式。**必须通过user字段指定非 root 用户。
完整示例
应用概览:
- ID:
myapp-docker - 类型:Docker 应用
- 镜像:
linuxserver/myapp:latest - 端口:8080
- 依赖:DockerEngine
config.ini
{
"id": "myapp-docker",
"icon": "/images/icons/myapp-docker.svg",
"publisher": "开发者名称",
"path": "http://${ip}:8080",
"exec": true,
"open_path": true,
"resize": true,
"maxmin": true,
"width": 0,
"height": 0,
"help": "https://github.com/example/myapp/wiki",
"version": "1.0.0",
"recommend": false,
"beta": false,
"low_version": "TOS7.0",
"category": ["Utilities"],
"depend": ["DockerEngine"],
"relation": ["docker", "DockerEngine"],
"platform": "x86_64",
"official": "https://example.com",
"application_type": "docker",
"system_id": "",
"package": "",
"compose_project": "myapp-docker",
"user": "myapp",
"all_user_display": true,
"allow_open_in_mobile": false
}
docker-compose.yml
version: "3.8"
services:
myapp-docker:
image: linuxserver/myapp:1.0.0
container_name: myapp-docker
restart: unless-stopped
Volumes:
- /Volume*/DockerAppData/myapp-docker/config:/config
- /Volume*/DockerAppData/myapp-docker/data:/data
ports:
- "8080:8080"
environment:
- TZ=Asia/Shanghai
- PUID=1000
- PGID=1000
x-app-meta:
web:
port: 8080
protocol: http
说明:
/Volume*/中的*代表用户安装时选择的卷号(例如 Volume1、Volume2)。该应用为 WebUI 外部打开,因此path使用http://${ip}:<端口>格式。
多容器服务启动顺序: 对于具有多个服务的应用(如 Web + 数据库):
services:
app-db:
image: postgres:16
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
app-web:
image: myapp:1.0.0
depends_on:
app-db:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 30s
timeout: 10s
retries: 3
- 使用
depends_on并设置condition: service_healthy确保正确的启动顺序 - 每个服务必须定义健康检查
- 平台验证:所有服务必须健康后应用才显示为"运行中"
健康检查失败处理:
- 连续 3 次健康检查失败后,容器标记为"不健康"
- 应用中心将应用显示为"异常"
- Docker 的重启策略(
unless-stopped)将尝试重启不健康的容器 - 如果容器进入重启循环,平台将标记应用需要开发者关注
数据备份、迁移和重置:
| 操作 | 路径 | 方法 |
|---|---|---|
| 备份配置 | /Volume*/DockerAppData/<appid>/config | tar 或 rsync 备份 |
| 备份数据 | /Volume*/DockerAppData/<appid>/data | tar 或 rsync 备份 |
| 迁移 | 全部 /Volume*/DockerAppData/<appid>/ | 复制到新设备,相同路径 |
| 重置为默认 | 停止容器 → 删除 /Volume*/DockerAppData/<appid>/config → 重启 | 容器创建全新配置 |
| 完全删除数据 | 停止容器 → 删除 /Volume*/DockerAppData/<appid>/ | 所有数据永久删除 |
注意:配置和数据分开存储,支持独立备份/恢复。重大升级前务必备份。