name: lazycat-app-publisher description: Use when converting Docker Compose or Docker Run apps to LazyCat LPK v2, publishing or updating LazyCat apps, copying Docker images to the LazyCat registry, selecting images in multi-service manifests, using lzc-publish, or configuring permissions, passwordless login, app interconnect, resources, run_as, and file picker integration. preferences:
- id: add_root_to_public_path name: 添加 / 到 public_path description: 自动在生成的 manifest 中添加 "/" 到 application.public_path type: boolean default: true
- id: manifest_multilingual name: Manifest 多语言支持 description: 在 manifest 文件中生成中英文双语 locales type: boolean default: true
- id: simple_app_optimization name: 简单应用优化 description: 简单应用跳过 lzc-deploy-params.yml 生成 type: boolean default: true
- id: auto_healthcheck name: 自动健康检查 description: 自动为服务添加健康检查配置 type: boolean default: true
- id: auto_resource_limits name: 自动资源限制 description: 自动为服务添加合理的资源限制 type: boolean default: true
- id: minimal_docs name: 最简文档 description: 只生成 README.md,跳过其他 markdown 文件 type: boolean default: true
- id: background_task name: 后台任务模式 description: 默认将 application.background_task 设为 true,适用于长时间运行的后台服务 type: boolean default: false
- id: package_prefix name: 包名前缀 description: 应用包名默认前缀(community.lazycat.app、cloud.lazycat.app 或自定义) type: string default: cloud.lazycat.app
- id: generate_compose_override name: 生成 compose_override description: 在 lzc-build.yml 中为不支持的字段生成 compose_override 部分 type: boolean default: true
- id: passwordless_login name: 免密登录配置 description: 为有密码体系的应用自动配置免密登录(使用 injects) type: boolean default: true
LazyCat 应用发布助手
协助将 Docker Compose 文件和 Docker 命令转换为 LazyCat Cloud 应用配置,提供智能依赖分析和自动配置优化。
Reference Documents
OS Version Requirements
⚠️ LPK v2 格式强制要求:min_os_version: 1.5.0
LPK v2(tar 格式,包含 package.yml)是 lzcos v1.5.0+ 才支持的特性。如果使用 LPK v2 格式,必须设置 min_os_version: 1.5.0 或更高版本。
| Feature | Minimum Version | Notes |
|---|---|---|
LPK v2 / package.yml |
v1.5.0 | 强制要求!新项目默认使用 |
多入口 application.entries |
v1.4.3 | 多入口支持 - 主界面+管理后台等 ⭐ |
/lzcapp/documents (新路径) |
v1.5.0 | 替代旧路径 /lzcapp/document |
permissions 声明 |
v1.5.0 | 权限系统 |
services.[].healthcheck |
v1.4.1 | 100% Docker 兼容,详见下方映射表 |
compose_override |
v1.3.0 | For unsupported docker-compose params |
application.upstreams |
v1.3.8 | Recommended over routes |
services.[].mem_limit, shm_size |
v1.3.8 | Memory limits |
lzc-cli project workflow |
lzc-cli v2.0.0+ | Required for LPK v2 |
应用间访问 .lzcx |
v1.5.2 | app.<pkg>.lzcx 地址 ⭐ |
import_resources / resource_exports |
v1.5.2 | Skill/MCP 导入导出 |
lzcapp.self_delegate / lzcapp.user_delegate |
v1.5.2 | 应用间访问权限 |
run_as (UID/GID + owner 映射) |
v1.6.0+ | 容器数字 UID/GID + /lzcapp 持久目录 owner 映射 ⭐ |
hidden_from_launcher |
v1.5.3 | 从启动器隐藏应用入口 |
user.notify 权限 |
v1.6.0 | 向用户发送通知 |
| 文件选择器拦截 | v1.5.0+ | 应用商店强制:有上传/下载必须接入 ⭐ |
版本决策表:
| 格式/特性 | 设置 min_os_version |
|---|---|
| LPK v2 (tar, package.yml) | 1.5.0 (强制) |
| LPK v1 (zip) | 无限制 |
使用 /lzcapp/documents |
1.5.0 |
使用 permissions |
1.5.0 |
使用 多入口 entries |
1.4.3 ⭐ |
使用 upstreams, mem_limit |
1.3.8 |
使用 应用间访问 .lzcx |
1.5.2 ⭐ |
| 使用 Skill/MCP 导入导出 | 1.5.2 ⭐ |
使用 run_as (UID/GID owner 映射) |
1.6.0+ ⭐ |
使用 hidden_from_launcher |
1.5.3 |
使用 user.notify 权限 |
1.6.0 |
| 文件选择器拦截(应用商店强制) | 1.5.0 ⭐ |
详见 references/version-features.md 和 references/strict-constraints.md
Conversion Workflow
Phase 1: 输入分析
输入: Docker Compose 文件 或 Docker Run 命令 输出: 服务分类结果(Internal/External),参数需求清单
Step 1.1: 解析源文件
用户提供 docker-compose.yml 或 docker run 命令
→ 解析 services、ports、volumes、environment、depends_on 等
⚠️ 检查点 - 源文件有效性验证:
| 验证项 | 验证方法 | 失败处理 |
|---|---|---|
| YAML 语法 | 尝试 YAML 解析 | 提示 YAML 格式错误及具体行号 |
| Dockerfile/image 有效性 | 检查 image 字段是否为空 | 要求用户提供有效镜像名称 |
| 端口格式 | ports 是否为数字端口 | 提示修正格式(非数字/范围超出) |
| volumes 路径 | 检查 volumes 格式 | 提示正确格式 /host:/container |
| depends_on 循环依赖 | 依赖图检测 | 提示循环依赖的服务列表 |
Fallback:如果输入无法解析,引导用户使用交互式 CLI 模式逐步配置。
Step 1.2: 服务分类
使用智能分析逻辑判断服务类型:
| 判断条件 | 类型 | 处理方式 |
|---|---|---|
| 有 healthcheck + 无外部端口 | Internal | 自动配置密码 |
| 有外部端口 | External | 用户配置 upstreams |
| 有密码体系 | 密码应用 | ⚠️ 检查点:确认是否配置免密登录 |
Step 1.3: 检查应用商店
⚠️ 检查点: 自动搜索应用商店,确认同名应用是否已存在
GET https://search.lazycat.cloud/api/v1/app?keyword={app_name}&size=48
如果找到匹配:
- 提示用户:「应用商店已存在同名应用 XXX,是否继续创建?」
- 用户确认后继续,否则终止
详见 references/intelligent-analysis.md
Phase 2: 配置生成
输入: 服务分类结果 输出: package.yml + lzc-manifest.yml + lzc-build.yml(LPK v2 格式) 前置检查:
# 检查 lzc-cli 是否已安装
lzc-cli --version || echo "lzc-cli 未安装,请参考 https://docs.lazycat.cloud/cli/install"
# 检查 Docker CLI(如需镜像分析)
docker --version || echo "Docker CLI 未安装,手动提供镜像名称即可"
Step 2.1: 生成 package.yml(静态元数据)
⚠️ 检查点: 确认包名前缀(默认 cloud.lazycat.app)
⚠️ 检查点: 自动分析权限需求(根据 binds 路径自动声明)
权限自动分析逻辑:当 lzc-manifest.yml 中 services.*.binds 包含特定路径时,必须在 package.yml.permissions 中声明对应权限:
| binds 路径 | 必需权限 id | 说明 |
|---|---|---|
/lzcapp/documents |
document.private |
应用文稿目录,必须声明 |
/lzcapp/documents/${uid} |
document.private |
用户隔离文稿目录 |
/lzcapp/run/mnt/home |
document.read + document.write |
兼容旧路径(v1.7.0+ 需授权) |
/lzcapp/media |
media.read 或 media.write |
媒体目录访问 |
检测流程:
解析 services.*.binds 列表
→ 匹配路径前缀
→ 自动生成 permissions.required 或 permissions.optional
→ 提示用户确认权限声明
⚠️ 检查点: 如果检测到 /lzcapp/documents 挂载,必须暂停并告知用户:
- 「检测到应用文稿目录
/lzcapp/documents挂载,需要声明document.private权限」 - 「该权限允许应用使用私有文稿目录,实际数据按用户隔离存放」
⚠️ 检查点: 确认 author 来源(按以下优先级):
| 优先级 | 来源 | 规则 |
|---|---|---|
| 1 | 用户明确指定 | 使用用户输入的作者名 |
| 2 | GitHub URL | 从 homepage 提取 GitHub 用户名/组织名 |
| 3 | 默认生成 | 使用 应用名 + Team |
Author 自动填入示例:
| homepage | 提取结果 |
|---|---|
https://github.com/dani-garcia/vaultwarden |
dani-garcia |
https://github.com/blinkospace/blinko |
blinkospace |
https://nextcloud.com (非 GitHub) |
Nextcloud Team |
详见 references/intelligent-analysis.md 的 Author Auto-Fill Logic 章节
package: cloud.lazycat.app.myapp # 用户可修改前缀
version: 1.0.0
name: MyApp
description: "应用描述"
min_os_version: 1.5.0 # ✅ LPK v2 强制要求
homepage: https://github.com/user/repo
author: user # ✅ 从 GitHub URL 自动提取,或使用 "MyApp Team"
Step 2.2: 生成 lzc-manifest.yml(运行结构)
⚠️ 检查点: 确认路由方式(upstreams 或 ingress)
application:
subdomain: myapp
upstreams: # HTTP 服务推荐
- location: /
backend: http://web:8080/
# 或 ingress(TCP/UDP 服务)
# ingress:
# - port: 5432
# proto: tcp
services:
db:
image: postgres:15
environment:
- POSTGRES_PASSWORD={{.INTERNAL.db_password}} # Internal 服务自动配置
Step 2.3: 生成 lzc-build.yml(构建配置)
manifest: ./lzc-manifest.yml
pkgout: ./
icon: ./icon.png
# compose_override 用于不支持的字段(可选)
Step 2.4: 配置免密登录(密码应用必须)
⚠️ 检查点: 如果应用有密码体系,必须询问用户免密登录方案
| 方案 | 适用场景 | 配置复杂度 |
|---|---|---|
| simple-inject-password | 固定账号/部署参数提供 | 简单 |
| 三阶段联动 | 用户首次创建账号 | 中等 |
| Basic Auth Header | 上游服务验证 | 简单 |
详见 references/passwordless-login.md
Step 2.5: 配置资源导出(可选,v1.5.2+)
如果应用需要向微服提供 Skill 或 MCP 资源,在 lzc-build.yml 中配置 resource_exports:
# lzc-build.yml
resource_exports:
- kind: skills
source: ./resources/skills
- kind: mcp-providers
source: ./resources/mcp-providers
检查点: 如果应用提供 Skill/MCP,需确认 permissions 声明:
- 应用需访问其他应用 →
lzcapp.user_delegate - 应用只访问自己 →
lzcapp.self_delegate
使用 .lzcx 地址访问:
http://app.<目标包名>.lzcx<endpoint>
详见 references/resource-export.md 和 references/app-interconnect.md
Phase 3: 打包发布
输入: 配置文件已生成 输出: LPK 包 + 发布到应用商店
Step 3.0: 既有项目版本更新(推荐脚本)
已有 LPK 项目升级版本时,优先使用通用脚本。先按 manifest 镜像数量选模式:
| 场景 | 命令 | 结果 |
|---|---|---|
| 单镜像 | scripts/lzc-release-update.sh 1.2.3 --source-template 'ghcr.io/acme/app:{version}' |
自动更新唯一 service |
| 多镜像 | scripts/lzc-release-update.sh 1.2.3 --service web --source-template 'ghcr.io/acme/web:{version}' |
只更新 web |
| 发布审核 | scripts/lzc-release-update.sh 1.2.3 --service web --publish --changelog '更新到 1.2.3' |
构建后调用 lzc-publish |
# 不确定源镜像时直接指定完整镜像
scripts/lzc-release-update.sh 1.2.3 --service web --source-image ghcr.io/acme/web:1.2.3
多镜像规则:
- 如果
lzc-manifest.yml只有一个services.*.image,脚本可以自动更新。 - 如果有多个镜像,必须通过
--service <name>指明要更新哪个服务。 - 脚本会把选择记到
.lazycat-release.env;下次使用记忆值时仍会显式打印正在更新的 service。 - 镜像复制优先调用 fish 中的
lzc-copy-image,不存在时回退到lzc-cli appstore copy-image。 - 发布是显式动作:只有
--publish或配置publish=1时才调用lzc-publish <lpk> <changelog> [lang]。 - 如果
copy-image没有返回registry.lazycat.cloud/...,停止并保留原 manifest,不要猜测镜像地址。
Step 3.1: 本地验证
# 构建 LPK 包(默认 LPK v2)
lzc-cli project release -o app.lpk
# 查看包信息
lzc-cli lpk info app.lpk
⚠️ 检查点: 确认包内容正确后再发布
Step 3.2: 发布到应用商店
lzc-cli appstore publish app.lpk
Quick Start
Convert Docker Compose
输入格式: Docker Compose YAML 文件路径或内容 输出格式: LPK v2 包目录(package.yml + lzc-manifest.yml + lzc-build.yml)
Convert this docker-compose.yml to LazyCat app format:
[provide docker-compose.yml content or file path]
示例输入:
services:
web:
image: nginx:latest
ports:
- "80:80"
db:
image: postgres:15
environment:
POSTGRES_PASSWORD: mypassword
预期输出:
├── package.yml # 包元数据
├── lzc-manifest.yml # 运行配置
├── lzc-build.yml # 构建配置
└── icon.png # 应用图标(需用户提供)
Convert Docker Run
输入格式: Docker Run 命令字符串 输出格式: 同上(LPK v2)
Convert this docker run command to LazyCat app:
docker run -d -p 8080:80 -e APP_ENV=production --name myapp nginx:latest
解析规则:
- -p → application.upstreams 或 ingress
- -e → services.*.environment
- -v → services.*.binds
- --name → application.subdomain
Publish to Store
输入格式: LPK 包文件路径 输出: 发布到应用商店,返回应用 ID
Help me publish this application to LazyCat Cloud:
[provide LPK package path or directory]
步骤:
1. 验证 LPK 包结构
2. 确认应用商店无同名应用
3. 执行 lzc-cli appstore publish
4. 返回发布结果
Update Existing App Version
输入格式: 版本号 + 上游镜像(或镜像模板)
输出: 更新后的 package.yml、lzc-manifest.yml、LPK 包,可选发布
从注释自动推导(推荐)
在 lzc-manifest.yml 的 image: 行上方添加注释,记录上游镜像:
services:
web:
# ghcr.io/acme/web:v1.0.0 ← 脚本会读取这个注释
image: registry.lazycat.cloud/xxx/yyy:hash123
然后只需指定版本号:
# 自动从注释推导上游镜像
scripts/lzc-release-update.sh 1.2.3
# 多镜像时指定 service
scripts/lzc-release-update.sh 1.2.3 --service web
推导逻辑:
- 优先使用
--source-image或--source-template - 如果都没有,尝试从
image:行上方的注释推导 - 注释格式必须是
# org/repo:tag或# registry/org/repo:tag - 版本号会被替换为指定的新版本
其他方式
# 推荐:记录源镜像模板,后续只传版本
scripts/lzc-release-update.sh 1.2.3 --service web --source-template 'ghcr.io/acme/web:{version}'
# 如果项目只有一个镜像,可省略 --service
scripts/lzc-release-update.sh 1.2.3 --source-image ghcr.io/acme/web:1.2.3
# 发布更新到应用商店审核
scripts/lzc-release-update.sh 1.2.3 --service web --publish --changelog '更新到 1.2.3'
当 manifest 中有多个镜像时,先列出所有候选镜像并要求明确选择 service;不要静默批量替换,也不要默认替换第一个镜像。
Configure Multi-Entry Points
使用场景: 应用需要多个入口(如主界面 + 管理后台)
⚠️ 版本要求: lzcos v1.4.3+,需设置 min_os_version: 1.4.3
# lzc-manifest.yml
application:
subdomain: myblog
entries:
- id: main
title: "Blog"
path: /
- id: admin
title: "Admin"
path: /admin
# package.yml - 多语言本地化
locales:
en:
entries.main.title: "Blog"
entries.admin.title: "Admin Console"
zh:
entries.main.title: "博客"
entries.admin.title: "管理后台"
字段说明:
id: 入口唯一标识title: 显示名称(支持 locales)path: 入口路径(如/、/admin)prefix_domain: 可选,域名前缀(如admin→admin-myblog.xxx.lzcapp)
详细说明见 references/advanced-features.md
智能分析逻辑
服务分类
def classify_service(service_config):
has_healthcheck = 'healthcheck' in service_config
has_external_ports = 'ports' in service_config
# Internal 服务 = 有 healthcheck + 无外部端口
if has_healthcheck and not has_external_ports:
return 'INTERNAL' # 自动配置
else:
return 'EXTERNAL' # 用户配置
| 服务 | 健康检查 | 外部端口 | 类型 | 配置方式 |
|---|---|---|---|---|
| PostgreSQL | ✅ | ❌ | Internal | 自动生成密码 |
| Redis | ✅ | ❌ | Internal | 自动生成密码 |
| Web App | ❌ | ✅ | External | 用户配置 |
参数模板
| 场景 | 推荐函数 | 示例 |
|---|---|---|
| 内部服务密码 | {{.INTERNAL.xxx}} |
{{.INTERNAL.db_password}} |
| 用户必须配置 | {{.U.xxx}} |
{{.U.jwt_secret_key}} |
| 系统域名 | {{.S.AppDomain}} |
{{.S.AppDomain}} (不含协议) |
| 稳定密钥 | {{ stable_secret "seed"}} |
{{ stable_secret "api_key"}} |
| 运行时变量 | ${LAZYCAT_*} |
${LAZYCAT_APP_ID} |
| 条件渲染 | {{if}}/{{else}}/{{end}} |
根据参数动态配置 |
⚠️ 模板语法规范(重要)
字段名包含特殊字符时必须使用 index 语法,否则使用点语法:
# ✅ 正确:简单字段名(无特殊字符)使用点语法
{{ .U.login_user }}
{{ .U.target }}
{{ .INTERNAL.db_password }}
# ✅ 正确:字段名包含 "." 等特殊字符时使用 index 语法
{{ index .U "listen.port" }}
{{ index .U "api.endpoint" }}
# ❌ 错误:简单字段名不应该使用 index 语法
{{ index .U "login_user" }} # ❌ 应改为 {{ .U.login_user }}
{{ index .U "target" }} # ❌ 应改为 {{ .U.target }}
规则总结:
- 字段名不含
.→ 使用{{ .U.xxx }}点语法 - 字段名含
.→ 使用{{ index .U "xxx" }}index 语法
详见 references/intelligent-analysis.md 和 references/go-template-conditional.md ⭐
Setup Wizard 约束
生成 lzc-deploy-params.yml 时,严格按照官方规范:
允许的字段(完整列表)
- ✅
id- 参数 ID(推荐小写英文+下划线) - ✅
type- 仅支持bool、lzc_uid、string、secret - ✅
name- 参数名称(英文) - ✅
description- 参数描述(英文) - ✅
optional- 是否可选 - ✅
default_value- 默认值,支持$random(len=5) - ✅
hidden- 字段生效但不在界面中渲染
❌ 禁止使用的字段
以下字段不存在,禁止生成:
- ❌
placeholder- 不存在 - ❌
regex- 不存在 - ❌
regex_message- 不存在 - ❌
min- 不存在 - ❌
max- 不存在 - ❌
type: number- 不支持 - ❌
type: integer- 不支持 - ❌
type: email- 不支持 - ❌
type: url- 不支持 - ❌
required- 应使用optional: false - ❌
value- 应使用default_value
约束输入的正确做法
需要约束输入格式时,在 description 中说明:
# ✅ 正确做法
params:
- id: port_number
type: string # 使用 string 类型
name: "Port Number"
description: "Service port number (1-65535, default 8080)"
default_value: "8080"
详见 references/strict-constraints.md
Package Layout Constraints
生成应用文件时,默认使用 LPK v2 格式(需要 lzcos v1.5.0+ 和 lzc-cli v2.0.0+):
lzc-build.yml 允许的字段
- ✅
manifest- manifest.yml 文件路径(必需) - ✅
pkgout- LPK 输出路径(必需) - ✅
icon- 应用图标路径(必需,512x512 PNG) - ✅
contentdir- 内容目录(可选) - ✅
pkg_id- 覆盖 package.yml.package(可选) - ✅
pkg_name- 覆盖 package.yml.name(可选) - ✅
envs- 构建期变量(可选,KEY=VALUE数组) - ✅
buildscript- 构建脚本(可选) - ✅
images- 内嵌镜像构建(可选) - ✅
compose_override- compose 覆盖(可选)
❌ lzc-build.yml 禁止的字段
以下字段应放在其他文件:
- ❌
package,version,name,description,min_os_version,locales,author,license,homepage→ 应在package.yml - ❌
application,services,subdomain→ 应在lzc-manifest.yml - ❌
dockerfile,context→ 应在images配置内部
LPK v2 默认布局(推荐)
.
├── lzc-build.yml # 构建配置
├── lzc-build.dev.yml # 开发态覆盖(可选)
├── package.yml # 静态包元数据(LPK v2 必需)
├── lzc-manifest.yml # 运行结构定义
└── icon.png # 应用图标
package.yml 必须包含:
package- 包 IDversion- 版本name,description- 名称和描述min_os_version: 1.5.0- LPK v2 格式强制要求
lzc-manifest.yml 只保留运行结构:
application- 应用配置services- 服务配置ext_config- 扩展配置usage- 使用说明
详见 references/strict-constraints.md
Docker → LazyCat Mapping
| Docker Feature | LazyCat Equivalent |
|---|---|
ports (HTTP) |
application.upstreams ⭐ |
ports (TCP/UDP) |
application.ingress |
volumes |
services.*.binds |
environment |
services.*.environment |
depends_on |
services.*.depends_on |
command |
services.*.command (必须是字符串!) |
shm_size |
services.*.shm_size |
healthcheck |
services.*.healthcheck (v1.4.1+, 100%兼容) ⭐ |
Healthcheck 快速参考
v1.4.1+ 关键变更:
- ✅
healthcheck(无下划线)- 100% Docker Compose 兼容 - ❌
health_check(带下划线)- 已废弃,迁移时需改字段名并添加时间单位
# Docker Compose → LazyCat 完全兼容
services:
postgres:
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 30s
timeout: 10s
retries: 3
start_period: 30s # 必须带单位(旧格式可能无单位)
⚠️ Rule 1: 不要自动添加 healthcheck(容器可能缺少 curl/wget)
Volume Path Mapping
- Docker:
/some/path:/container/path - LazyCat:
/lzcapp/var/...:/container/path或/lzcapp/cache/...:/container/path
文档路径变更(v1.5.0+):
| 版本 | 路径 | 说明 |
|---|---|---|
| v1.5.0+ | /lzcapp/documents |
新路径,推荐 |
| < v1.5.0 | /lzcapp/document |
废弃,仅兼容 |
需要文档访问权限时,需在 manifest 中声明:
ext_config:
enable_document_access: true
详见 references/quick-reference.md
Passwordless Login Configuration
⚠️ 重要:所有自带密码体系的应用都必须配置免密登录!
LazyCat 微服要求应用提供良好的用户体验,用户不应该每次都手动输入密码。
三种常用方案
方案一:部署参数 + simple-inject-password(简单场景)
适用于登录账号固定或由部署参数提供的场景:
# lzc-deploy-params.yml
params:
- id: login_user
type: string
name: "Login User"
description: "Default login username"
default_value: "admin"
- id: login_password
type: secret
name: "Login Password"
description: "Default login password"
default_value: "$random(len=20)"
# lzc-manifest.yml
application:
injects:
- id: login-autofill
when:
- /login
- /signin
do:
- src: builtin://simple-inject-password
params:
# 简单字段名使用点语法:{{ .U.xxx }}
# 仅当字段名包含特殊字符(如 ".")时才使用 index 语法
user: "{{ .U.login_user }}"
password: "{{ .U.login_password }}"
方案二:三阶段联动(高级场景)
适用于用户首次创建账号、后续可能修改密码的场景:
# request 阶段:捕获用户名/密码
injects:
- id: capture-password
on: request
when:
- /api/login
- /api/setup
do: |
const payload = ctx.body.getJSON();
ctx.flow.set("pending_user", payload.username);
ctx.flow.set("pending_pass", payload.password);
# response 阶段:成功后持久化
- id: commit-password
on: response
when:
- /api/login
- /api/setup
do: |
if (ctx.status >= 200 && ctx.status < 300) {
ctx.persist.set("saved_user", ctx.flow.get("pending_user"));
ctx.persist.set("saved_pass", ctx.flow.get("pending_pass"));
}
# browser 阶段:自动填充
- id: autofill-login
when:
- /login
do:
- src: builtin://simple-inject-password
params:
user:
$persist: saved_user
password:
$persist: saved_pass
方案三:Basic Auth Header 注入
适用于上游服务使用 Basic Auth 的场景:
application:
injects:
- id: inject-basic-auth
on: request
auth_required: false
when:
- /api/*
do: |
ctx.headers.set("Authorization", "Basic " + ctx.base64.encode("admin:password"));
关键注意事项
on: request/response不能使用 hash 规则(如/#login)- request 阶段不要直接写入
persist,先存入flow,response 成功后再持久化 - 显式指定选择器,确保特殊命名页面也能正确填充
详见 references/passwordless-login.md
最佳实践
✅ Do - LPK v2 完整示例(推荐,lzcos v1.5.0+)
⚠️ 重要:LPK v2 格式必须设置 min_os_version: 1.5.0
# package.yml - 静态元数据(含自动生成的权限声明)
package: cloud.lazycat.app.myapp
version: 1.0.0
name: MyApp
description: "My application"
min_os_version: 1.5.0 # ✅ LPK v2 强制要求
author: "Developer"
license: MIT
homepage: https://example.com
locales:
zh:
name: "我的应用"
description: "我的应用描述"
en:
name: "My App"
description: "My application"
# ⚠️ 权限声明 - 根据 binds 路径自动分析生成
# 检测到 /lzcapp/documents → 添加 document.private
# 检测到网络服务 → 添加 net.internet
permissions:
required:
- net.internet # 网络访问(大部分应用必需)
- document.private # ⚠️ 检测到 /lzcapp/documents 挂载时自动添加
optional:
- document.read # 可选:读取用户文稿
- document.write # 可选:写入用户文稿
# lzc-manifest.yml - 运行结构(不包含静态元数据)
application:
subdomain: myapp
upstreams: # ✅ 推荐使用 upstreams 替代 routes
- location: /
backend: http://myapp:8080/
injects: # ✅ 免密登录配置
- id: login-autofill
when:
- /login
do:
- src: builtin://simple-inject-password
params:
# 简单字段名使用点语法:{{ .U.xxx }}
# 仅当字段名包含特殊字符(如 ".")时才使用 index 语法
user: "{{ .U.login_user }}"
password: "{{ .U.login_password }}"
services:
postgres:
image: postgres:15
environment:
- POSTGRES_PASSWORD={{.INTERNAL.db_password}}
healthcheck: # ✅ v1.4.1: 使用 'healthcheck' (无下划线)
test:
- CMD-SHELL
- pg_isready -U postgres
interval: 30s
timeout: 10s
retries: 3
start_period: 30s
binds:
- /lzcapp/var/db:/var/lib/postgresql/data
# lzc-build.yml - 构建配置(只包含构建相关字段)
manifest: ./lzc-manifest.yml
pkgout: ./
icon: ./icon.png
# ✅ 不包含 package, version, name 等静态元数据
# lzc-deploy-params.yml - 部署参数(严格按规范)
params:
- id: login_user # ✅ 小写英文+下划线
type: string # ✅ 只使用 string/secret/bool/lzc_uid
name: "Login User"
description: "Default login username"
default_value: "admin"
optional: true
- id: login_password
type: secret
name: "Login Password"
description: "Default login password"
default_value: "$random(len=20)"
optional: true
locales:
zh:
login_user:
name: "登录用户"
description: "默认登录用户名"
login_password:
name: "登录密码"
description: "默认登录密码"
❌ Avoid - 常见错误
发布更新反例黑名单:
| ❌ 不要做 | 后果 | ✅ 正确做法 |
|---|---|---|
对 image: .* 做全局 sed 替换 |
多镜像项目会更新错服务 | 用 scripts/lzc-release-update.sh --service <name> |
| 多镜像 manifest 未确认 service 就复制/发布 | 用户无法判断到底更新了哪个容器 | 先列出 services.*.image,要求显式选择或读取 .lazycat-release.env 并打印 |
| 构建后默认发布 | 未审核的 LPK 进入应用商店流程 | 只有用户要求或传 --publish 时调用 lzc-publish |
copy-image 解析不到 registry 地址仍继续 |
manifest 指向不存在或旧镜像 | 立即停止,保留文件,提示用户贴出完整输出 |
只改 manifest 不改 package.yml 版本 |
构建产物版本混乱,更新审核失败 | 同步更新 package.yml 顶层 version |
# ❌ 将静态包元数据放在 lzc-manifest.yml(LPK v2 不允许)
# 这些字段应该移到 package.yml
package: cloud.lazycat.app.myapp
version: 1.0.0
name: MyApp
# ❌ LPK v2 格式 min_os_version 设置过低
min_os_version: 1.3.8 # ❌ LPK v2 必须是 1.5.0
# ✅ 正确:min_os_version: 1.5.0
# ❌ lzc-build.yml 包含不存在的字段
package: myapp # ❌ 应在 package.yml
version: 1.0.0 # ❌ 应在 package.yml
subdomain: myapp # ❌ 应在 lzc-manifest.yml
# ❌ lzc-deploy-params.yml 包含不存在的字段
params:
- id: port
type: number # ❌ 不支持 number 类型
min: 1 # ❌ 不存在 min 字段
max: 65535 # ❌ 不存在 max 字段
placeholder: "8080" # ❌ 不存在 placeholder 字段
regex: "^[0-9]+$" # ❌ 不存在 regex 字段
# ❌ 旧格式 lzc-sdk-version
lzc-sdk-version: "0.1" # 已移除!
# ❌ 对 services 使用废弃的 health_check
services:
postgres:
health_check: # 已废弃!使用 'healthcheck'
# ❌ 使用 routes 而不是 upstreams
application:
routes:
- /=http://myapp:8080/ # 使用 upstreams 替代
# ❌ admin_only 不能与非空 public_path 同时存在
admin_only: true
application:
public_path:
- /
# ❌ 硬编码密钥
environment:
- PASSWORD=secret123 # 使用 {{.U.password}} 或 {{.INTERNAL.xxx}}
# ❌ v1.5.0+ 使用旧文档路径
binds:
- /lzcapp/document:/data # 使用 /lzcapp/documents
# ❌ 使用 /lzcapp/documents 但缺少权限声明
# ⚠️ 这是用户报告的实际问题:绑定 /lzcapp/documents 时未自动添加权限
services:
app:
binds:
- /lzcapp/documents:/data # ❌ 需要 document.private 权限声明
# package.yml 缺少 permissions:
# permissions:
# required:
# - document.private # ✅ 必须声明此权限
# ❌ command 使用数组而非字符串
services:
redis:
command: ["redis-server", "--requirepass", "mypass"] # ❌
# ✅ 正确:command: redis-server --requirepass mypass
# ❌ 缺少免密登录配置(密码体系应用必须有)
application:
subdomain: myapp
# 缺少 injects 配置,用户每次都要手动输入密码
开发工作流
环境要求
LPK v2 格式(默认,推荐):
- lzcos v1.5.0+
- lzc-cli v2.0.0+ (
npm install -g @lazycatcloud/lzc-cli@2.0.0)
安装 CLI:
npm install -g @lazycatcloud/lzc-cli
# 或指定 v2 版本
npm install -g @lazycatcloud/lzc-cli@2.0.0
快速决策表
| 目标 | 使用命令 |
|---|---|
| UI 热更新 | project deploy + npm run dev |
| 后端代码修改 | project deploy + project sync --watch + project exec |
| 构建发布包 | project release |
主要命令
# 从模板创建项目
lzc-cli project create myapp -t hello-vue
# 部署(有 lzc-build.dev.yml 则用,否则用 lzc-build.yml)
lzc-cli project deploy
# 使用 release 配置部署
lzc-cli project deploy --release
# 同步代码(监听模式)
lzc-cli project sync --watch
# 进入容器
lzc-cli project exec /bin/sh
# 查看日志
lzc-cli project log -f
# 构建发布包(默认 LPK v2,需 lzc-cli v2.0.0+)
lzc-cli project release -o app.lpk
# 查看 LPK 信息
lzc-cli lpk info app.lpk
# 发布到应用商店
lzc-cli appstore publish app.lpk
详见 references/dev-workflow.md 和 references/cli-reference.md
LPK v1 到 v2 迁移
使用转换脚本
提供 Python 脚本将现有 LPK v1 包转换为 v2 格式:
# 基本用法
python scripts/lpk_v1_to_v2.py app.lpk
# 指定输出
python scripts/lpk_v1_to_v2.py app.lpk new-app.lpk
# 输出到目录
python scripts/lpk_v1_to_v2.py app.lpk ./output/
转换器做什么:
- 解压 LPK v1(zip 格式)
- 将
manifest.yml拆分为:package.yml- 静态元数据(package, version, name, description 等)manifest.yml- 运行结构(application, services, ext_config)
- 重新打包为 LPK v2(tar 格式)
依赖要求:
pip install pyyaml
手动迁移
简单场景可以手动迁移:
# 1. 解压 v1
unzip app.lpk -d temp/
# 2. 从 manifest.yml 静态字段创建 package.yml
cat > package.yml << 'EOF'
package: your.app.id
version: 1.0.0
name: Your App
description: App description
min_os_version: 1.3.8
EOF
# 3. 从 manifest.yml 移除静态字段(只保留 application, services, ext_config, usage)
# 4. 重新打包为 v2
tar -cf app-v2.lpk package.yml manifest.yml content.tar.gz META/
injects allows you to inject scripts into browser, request, or response phases.
| Phase | Runtime | Use Case |
|---|---|---|
on=browser |
Browser | DOM manipulation, autofill |
on=request |
lzcinit | Header injection, routing |
on=response |
lzcinit | CORS/CSP modification |
application:
injects:
- id: dev-proxy
on: request
auth_required: false
when:
- "/*"
do:
- src: |
if (ctx.dev.id && ctx.net.reachable("tcp", "127.0.0.1", 3000, ctx.net.via.client(ctx.dev.id))) {
ctx.proxy.to("http://127.0.0.1:3000", {
via: ctx.net.via.client(ctx.dev.id),
use_target_host: true,
});
}
Critical Rules
🚨 TOP 9 CRITICAL RULES
执行转换时,遇到以下情况必须暂停并询问用户。每条 Rule 附带「失败后果」和「恢复路径」,便于快速定位问题。
❌ Rule 1: DO NOT Auto-Add Healthcheck
如果原始 docker-compose.yml 没有 healthcheck,不要自动添加。容器可能缺少 curl/wget 工具。
🔴 CHECKPOINT: 发现服务无 healthcheck 时,询问用户:
- 「服务 X 无健康检查配置,是否需要添加?」
- 若用户选择添加,提供常见的 healthcheck 模板(见 healthcheck.md)
| 失败后果 | 恢复路径 |
|---|---|
| 容器内无 curl/wget → healthcheck 永远失败 → 服务反复重启 | 删除 healthcheck 字段,或改用容器原生命令(如 pg_isready、redis-cli ping) |
❌ Rule 2: binds Only Supports Directories, Not Files
使用 contentdir + setup_script 替代文件挂载:
# lzc-build.yml
contentdir: ./content
# lzc-manifest.yml
services:
web:
setup_script: |
cp /lzcapp/pkg/content/nginx.conf /etc/nginx/nginx.conf
🔴 CHECKPOINT: 发现文件挂载(如 /path/file.conf:/etc/file.conf)时,提示用户转换为 contentdir 方案。
| 失败后果 | 恢复路径 |
|---|---|
binds 挂载文件 → lzcinit 拒绝启动 → 应用无法部署 |
改用 contentdir + setup_script 在容器启动时复制文件 |
❌ Rule 3: LPK v2 MUST Set min_os_version: 1.5.0
LPK v2 格式(tar + package.yml)是 v1.5.0+ 才支持的特性:
# package.yml
package: cloud.lazycat.app.myapp
version: 1.0.0
min_os_version: 1.5.0 # ✅ 必须设置
🔴 CHECKPOINT: 若用户需要兼容旧版本(< v1.5.0),提示切换到 LPK v1 格式(zip)。
| 失败后果 | 恢复路径 |
|---|---|
| 低版本 lzcos 无法解析 tar 格式 → 安装失败 | 降低 min_os_version 并切换到 LPK v1(zip 格式),或要求用户升级 lzcos |
❌ Rule 4: DO NOT Generate Invalid Fields
严格按官方规范生成配置文件,禁止生成不存在的字段:
- lzc-build.yml: 禁止
package,version,name,subdomain等 - lzc-deploy-params.yml: 禁止
placeholder,regex,min,max,type: number
🔴 CHECKPOINT: 每次生成配置后,对照 strict-constraints.md 验证字段有效性。
| 失败后果 | 恢复路径 |
|---|---|
| lzcinit 解析 manifest 报错 → 应用无法安装 | 删除无效字段,严格按 strict-constraints.md 的字段白名单生成 |
❌ Rule 5: All Password Apps MUST Have Passwordless Config
如果应用自带密码体系,必须配置免密登录:
- 使用
simple-inject-password自动填充 - 或使用三阶段联动记录用户修改的密码
🔴 CHECKPOINT: 检测到密码字段(如 PASSWORD, SECRET_KEY, ADMIN_PASSWORD)时,强制询问:
- 「检测到密码体系,请选择免密登录方案:[简单自动填充 / 三阶段联动 / Basic Auth]」
- 用户确认后才能继续生成配置
| 失败后果 | 恢复路径 |
|---|---|
| 用户每次打开应用都要手动输密码 → 体验极差 → 商店审核可能不通过 | 补充 injects 配置免密登录,参考 passwordless-login.md |
⚠️ Rule 6: usage 字段只支持字符串形式(防止幻觉)
usage 是简单字符串字段,不支持嵌套结构:
# ✅ 正确:字符串形式
usage: "简单使用说明"
usage: |
多行使用说明
第二行内容
# ❌ 错误:幻觉生成的嵌套结构
usage:
intro: "应用介绍" # ❌ 不存在
steps: # ❌ 不存在
- "第一步"
tips: "提示" # ❌ 不存在
🔴 CHECKPOINT: 生成 usage 时,只生成字符串内容,不要生成任何嵌套字段结构。详见 strict-constraints.md 的 usage 字段章节。
| 失败后果 | 恢复路径 |
|---|---|
| lzcinit 解析 manifest 报错或 usage 不显示 | 将嵌套结构展开为纯字符串,用换行符分隔段落 |
⚠️ Rule 7: 免密登录 when 路径必须与实际登录页匹配
when 条件的路径判定不正确会导致免密登录完全失效。
🔴 CHECKPOINT: 配置免密登录时,必须先确认实际登录页路径:
| 步骤 | 操作 |
|---|---|
| 1 | 在浏览器中打开应用,进入登录页 |
| 2 | 复制浏览器地址栏的完整路径 |
| 3 | 根据实际路径配置 when 条件 |
| 4 | 验证自动填充是否生效 |
常见应用登录页路径对照表(见 passwordless-login.md):
| 应用 | 实际登录页路径 |
|---|---|
| Jellyfin | /web/#/login.html |
| WordPress | /wp-login.php |
| Portainer | /#/login |
| 失败后果 | 恢复路径 |
|---|---|
| inject 不命中登录页 → 密码框不自动填充 → 用户每次手动输入 | 根据实际 URL 修正 when 路径,hash 路径(如 /#login)仅 browser 阶段支持 |
错误示例:
# ❌ 错误:when 路径不匹配实际登录页
injects:
- id: login
when:
- /login # ❌ Jellyfin 实际登录页是 /web/#/login.html
⚠️ Rule 8: binds 路径必须匹配权限声明(自动分析)
binds 中使用特定路径时,必须在 package.yml.permissions 中声明对应权限:
| binds 路径前缀 | 必需权限 id | 声明位置 |
|---|---|---|
/lzcapp/documents |
document.private |
permissions.required |
/lzcapp/documents/${uid} |
document.private |
permissions.required |
/lzcapp/run/mnt/home |
document.read + document.write |
permissions.required |
/lzcapp/media |
media.read 或 media.write |
按读写需求 |
🔴 CHECKPOINT: 检测到以下路径时,自动添加权限声明并提示用户确认:
# 检测流程
1. 解析 services.*.binds
2. 匹配路径前缀
3. 自动生成 permissions
4. 提示用户:「检测到应用文稿挂载,已自动添加 document.private 权限」
| 失败后果 | 恢复路径 |
|---|---|
| 缺少权限声明 → lzcinit 拒绝挂载该路径 → 应用启动后无法读写文件 | 在 package.yml 的 permissions.required 中补充对应权限 id |
正确示例:
# ✅ lzc-manifest.yml - 使用 /lzcapp/documents
services:
app:
binds:
- /lzcapp/documents:/data # ✅ 挂载应用文稿目录
# ✅ package.yml - 自动生成的权限声明
permissions:
required:
- net.internet
- document.private # ✅ 检测到 /lzcapp/documents 时自动添加
错误示例:
# ❌ 错误:使用 /lzcapp/documents 但缺少权限声明
services:
app:
binds:
- /lzcapp/documents:/data
# ❌ package.yml 缺少 permissions 声明 → 应用无法访问文稿目录
🚨 Rule 9: 有上传/下载功能必须接入文件选择器拦截
应用商店强制要求:有上传/下载功能的应用必须接入懒猫网盘自动拦截文件选择器,未接入无法上架。
检测条件:应用包含以下任一特征时触发此规则:
<input type="file">文件上传showOpenFilePicker()/showSaveFilePicker()API<a download>下载链接- 文件导入/导出功能
🔴 CHECKPOINT: 检测到文件操作时,必须配置文件选择器拦截:
# lzc-manifest.yml
application:
injects:
- id: open-save-chooser
on: browser
when:
- /*
do:
- src: file:///lzcapp/pkg/content/lazycat-injects/lzc-file-chooser-inject.js
同时需要将 lzc-file-chooser-inject.js 放入包的 content 目录。
| 失败后果 | 恢复路径 |
|---|---|
| 应用商店审核拒绝 → 无法上架 | 下载 lzc-file-chooser-inject.js 放入 content/lazycat-injects/,在 manifest 添加 inject 声明 |
详见 references/file-picker-intercept.md
⚠️ 边界条件与异常处理
每条异常采用「触发条件 → 一线修复 → 仍失败兜底」三段式,避免只写"处理方案"导致执行时无 fallback。
构建阶段异常
| 异常类型 | 触发条件 | 一线修复 | 仍失败兜底 |
|---|---|---|---|
| 镜像拉取失败 | lzc-cli project release 报错 timeout/404 |
检查镜像源是否可访问,提示用户配置代理 | 使用 registry.lazycat.cloud 镜像源,或 embed:<alias> 内嵌镜像构建 |
| manifest 验证失败 | 字段格式错误,lzcinit 拒绝解析 | 对照 strict-constraints.md 逐字段检查,删除无效字段 | 生成最小可用 manifest(仅保留 subdomain + 一个 upstream),让用户手动补充 |
| 图标文件缺失 | icon.png 不存在 | 提示用户准备 512x512 PNG 图标 | 使用占位图标继续构建(在 README 中标注需替换) |
| 权限不足 | 文件写入失败 | 检查目标目录权限,提示 chmod |
改为输出到当前用户有权限的目录(如 ~/output/) |
网络阶段异常
| 异常类型 | 触发条件 | 一线修复 | 仍失败兜底 |
|---|---|---|---|
| 应用商店 API 不可达 | GET search.lazycat.cloud 超时 | 提示用户检查网络,可跳过检查继续创建 | 进入离线模式,用户需手动确认无重名后继续 |
| 镜像源不可达 | docker pull 超时或 502 | 推荐 registry.lazycat.cloud 镜像源 |
配置 compose_override 使用备用源(dockerproxy.net 等),或内嵌镜像 |
发布更新阶段异常
| 异常类型 | 触发条件 | 一线修复 | 仍失败兜底 |
|---|---|---|---|
| 多镜像选择缺失 | lzc-manifest.yml 有多个 services.*.image 且未提供 --service |
列出 service/image 清单,要求用户指定 | 若 .lazycat-release.env 有 service,使用该值并显式打印 |
| 镜像地址解析失败 | copy-image 输出不含 registry.lazycat.cloud/... |
停止更新,要求用户贴完整输出 | 用 COPY_IMAGE_OUTPUT 复现解析,或手动传 --skip-copy --source-image <registry-image> |
| 发布参数缺失 | 用户要求发布但没有 changelog | 默认使用 更新到 <version> 并打印 |
用户要求自定义时重跑 --changelog '<message>' |
| LPK 文件名不匹配 | 构建输出不是 <package>-v<version>.lpk |
用 --lpk <file> 指定实际产物 |
检查 lzc-build.yml 的 pkgout/pkg_id 配置 |
运行时异常
| 异常类型 | 触发条件 | 一线修复 | 仍失败兜底 |
|---|---|---|---|
| 应用启动失败 | 健康检查超时(start_period 内未就绪) | 检查 start_period 是否过短,增大后重试 |
进入容器手动排查:lzc-cli project exec /bin/sh,查看进程状态和日志 |
| 502/404 错误 | HTTP 响应 502 或 404 | 通过 injects response 阶段拦截返回自定义页面 |
检查 upstream backend 地址是否正确,确认服务容器是否在运行 |
| 服务依赖超时 | depends_on 的服务未在超时内就绪 | 检查依赖服务的 healthcheck 和 start_period | 移除 depends_on 改用应用层重试逻辑(如 wait-for-it 脚本) |
兼容性警告
| 场景 | 问题描述 | 处理方案 |
|---|---|---|
| 系统降级 (v1.3.8+) | v1.3.8+ 降级后应用数据不可用 | ⚠️ 强制警告:告知用户升级后不可降级 |
| user 字段格式 (v1.4.2) | services.xx.user: 1000 会报错 |
必须使用引号:user: "1000" |
| environment 空值 (v1.4.2) | environment: 空数组会报错 |
不要留空,删除字段或填写值 |
| compose_override 使用 | 需联系官方备案 | ⚠️ 检查点:使用前提示用户联系开发者群或客服 |
| 文档路径 (v1.5.0) | /lzcapp/document 废弃 |
使用新路径 /lzcapp/documents |
| run_as 冲突 (v1.6.0) | application.run_as 与 user 同时使用 |
⚠️ 强制警告:run_as 不得与 user 在同一级别同时使用 |
| run_as + setup_script 冲突 (v1.6.0) | services.<name>.run_as 与 setup_script 同时使用 |
⚠️ 强制警告:service 级别 run_as 不得与 setup_script 同时使用 |
恢复流程
当构建或运行失败时,按以下步骤恢复:
# 1. 查看详细错误日志
lzc-cli project log -f
# 2. 进入容器排查
lzc-cli project exec /bin/sh
# 3. 检查 manifest 渲染结果
cat /lzcapp/run/manifest.yml
# 4. 回滚到上一版本(如果有)
# 手动删除失败的部署,重新执行 lzc-cli project release
自定义错误页面与请求拦截(injects 方式)
⚠️
handlers.error_page_templates已废弃,请使用injects的 response 阶段实现自定义错误页面。
使用场景
injects 的 on: response 阶段适用于以下场景:
场景一:帮助文件跳转 — 应用包含使用说明/帮助文档,用户访问不存在的页面时自动跳转到帮助页(代替旧版 handler+JS 重定向方案)。
# lzc-manifest.yml
application:
injects:
- id: redirect-404-to-help
on: response
auth_required: false
when:
- "/*"
do: |
if (ctx.status === 404) {
ctx.response.send(302, "", { location: "/help" });
return;
}
upstreams:
- location: /help
backend: file:///lzcapp/pkg/content/web/index.html
- location: /
backend: http://yourapp:8080/
public_path:
- /
- /help
配置要点:帮助页路径(
/help)须同时出现在upstreams和public_path中,否则无法访问。
真实项目参考:Ask4Me(easychen/ask4me)使用此模式实现 404 → 帮助页自动跳转,详见 references/real-world-examples.md 的示例 7。
场景二:自定义错误页面 — 应用后端返回 502/503 时,显示友好的错误提示而非浏览器默认白页:
application:
injects:
- id: custom-error-pages
on: response
auth_required: false
when:
- "/*"
do: |
if (ctx.status === 502) {
ctx.response.send(200, { "content-type": "text/html; charset=utf-8" }, `
<html>
<body>
<h1>应用暂时不可用</h1>
<p>请稍后再试</p>
</body>
</html>
`);
return;
}
场景三:维护模式 — 在特定路径下拦截所有请求,返回维护公告页面。
更多 injects 用法(CORS 修正、Basic Auth 注入、开发代理等)见 references/injects.md。完整的帮助文档跳转示例见 references/developer-guide.md。
应用商店检查(自动)
每当用户请求转换或创建应用时,技能会自动检查懒猫应用商店中是否已存在同名应用:
# 搜索 API
GET https://search.lazycat.cloud/api/v1/app?keyword={app_name}&size=48
如果找到匹配应用,会提示用户是否继续创建。
偏好设置
| 偏好 | 默认值 | 说明 |
|---|---|---|
| 添加 / 到 public_path | true | 自动添加 "/" 到 public_path |
| Manifest 多语言 | true | 生成中英文 locales |
| 简单应用优化 | true | 简单应用跳过 params 生成 |
| 自动健康检查 | true | 自动添加 healthcheck |
| 自动资源限制 | true | 自动添加资源限制 |
| 最简文档 | true | 只生成 README.md |
| 后台任务模式 | false | 设置 background_task: true |
| 包名前缀 | cloud.lazycat.app | 包名前缀 |
| 生成 compose_override | true | 生成 compose_override |
| 免密登录 | true | 为密码体系应用自动配置免密登录 |
示例
示例 1:简单 Web 应用
输入(docker-compose.yml):
services:
postgres:
image: postgres:15
environment:
- POSTGRES_PASSWORD=${DB_PASSWORD}
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
app:
image: myapp:latest
environment:
- DATABASE_URL=postgresql://postgres:${DB_PASSWORD}@postgres:5432/app
- SECRET_KEY=${SECRET_KEY}
depends_on:
- postgres
ports:
- "3000:3000"
输出(智能转换):
services:
postgres:
environment:
- POSTGRES_PASSWORD={{.INTERNAL.db_password}} # 自动
healthcheck: {...}
app:
environment:
- DATABASE_URL=postgresql://postgres:{{.INTERNAL.db_password}}@postgres:5432/app
- SECRET_KEY={{.U.secret_key}} # 用户配置
更多示例见 references/docker-compose-examples.md 和 references/real-world-examples.md