zeabur-template

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Zeabur Template Knowledge Base

Zeabur模板知识库

Always use
npx zeabur@latest
to invoke Zeabur CLI.
Never use
zeabur
directly or any other installation method. If
npx
is not available, install Node.js first.
This skill provides comprehensive knowledge for creating, debugging, and publishing Zeabur templates. It combines reference documentation with battle-tested patterns from real template development.
请始终使用
npx zeabur@latest
调用Zeabur CLI。
切勿直接使用
zeabur
或其他安装方式。如果没有
npx
,请先安装Node.js。
本技能提供创建、调试和发布Zeabur模板的全面知识,结合了参考文档与实际模板开发中经过验证的模式。

External Documentation

外部文档

For the latest schema and detailed docs, fetch from
https://raw.githubusercontent.com/zeabur/zeabur-template-doc/main/
:
User NeedDocument to FetchPath
Create a template from scratchStep-by-step guide
docs/GUIDE.md
Convert docker-compose.ymlMigration guide
docs/DOCKER_COMPOSE_MIGRATION.md
Look up YAML fields or built-in variablesTechnical reference
docs/REFERENCE.md
Naming, design patterns, best practicesBest practices
docs/BEST_PRACTICES.md
Debug template errorsTroubleshooting
docs/TROUBLESHOOTING.md
Pre-deployment checklistChecklist
docs/CHECKLIST.md
Quick all-in-one overviewComprehensive prompt
prompt.md
The template YAML schema is also available at https://schema.zeabur.app/template.json and the prebuilt service schema at https://schema.zeabur.app/prebuilt.json.

如需获取最新的Schema和详细文档,请从
https://raw.githubusercontent.com/zeabur/zeabur-template-doc/main/
获取:
用户需求需获取的文档路径
从零开始创建模板分步指南
docs/GUIDE.md
转换docker-compose.yml迁移指南
docs/DOCKER_COMPOSE_MIGRATION.md
查询YAML字段或内置变量技术参考
docs/REFERENCE.md
命名、设计模式、最佳实践最佳实践
docs/BEST_PRACTICES.md
排查模板错误故障排除
docs/TROUBLESHOOTING.md
部署前检查清单检查清单
docs/CHECKLIST.md
快速全面概览综合提示
prompt.md

Core Principles

核心原则

0. All services MUST use PREBUILT_V2 with Docker images

0. 所有服务必须使用带有Docker镜像的PREBUILT_V2

Every service in a template MUST be
template: PREBUILT_V2
with a Docker image as the source.
Never use
template: GIT
,
ARBITRARY_GIT
, or
GITHUB
source — these are NOT supported in templates.
If the project does not have a published Docker image (on Docker Hub, GHCR, etc.), tell the user they need to build and publish a Docker image first before a template can be created. Do not attempt to work around this.
If the user asks you to build the image, follow this workflow:
  1. Clone the project repo and find its
    Dockerfile
    (usually at repo root)
  2. Study the Dockerfile to understand build stages — use the production stage (often named
    runner
    or
    production
    )
  3. Study
    docker-compose.yml
    or
    docker-compose.fullapp.yml
    for the correct startup command, env vars, and volumes — this is the battle-tested production config
  4. Build for amd64 (Zeabur servers are amd64, local Macs are arm64):
    bash
    docker buildx build --platform linux/amd64 --target runner -t org/image:tag --push .
  5. After pushing, verify the Docker Hub repo is public:
    bash
    curl -s "https://hub.docker.com/v2/repositories/ORG/IMAGE/" | grep is_private
    New repos under org accounts often default to private. If
    is_private: true
    , the user must make it public on Docker Hub.
模板中的每个服务必须设置为
template: PREBUILT_V2
,并以Docker镜像作为源。
切勿使用
template: GIT
ARBITRARY_GIT
GITHUB
作为源——这些在模板中不受支持。
如果项目没有已发布的Docker镜像(在Docker Hub、GHCR等平台),请告知用户需要先构建并发布Docker镜像,然后才能创建模板。请勿尝试绕过此步骤。
如果用户要求你构建镜像,请遵循以下流程:
  1. 克隆项目仓库并找到其
    Dockerfile
    (通常位于仓库根目录)
  2. 研究Dockerfile以了解构建阶段——使用生产阶段(通常命名为
    runner
    production
  3. 查看
    docker-compose.yml
    docker-compose.fullapp.yml
    获取正确的启动命令、环境变量和卷配置——这是经过验证的生产配置
  4. amd64架构构建镜像(Zeabur服务器为amd64架构,本地Mac通常为arm64):
    bash
    docker buildx build --platform linux/amd64 --target runner -t org/image:tag --push .
  5. 推送后,验证Docker Hub仓库是否公开
    bash
    curl -s "https://hub.docker.com/v2/repositories/ORG/IMAGE/" | grep is_private
    组织账户下的新仓库通常默认设为私有。如果返回
    is_private: true
    ,用户必须在Docker Hub上将其设为公开。

1. Never start from scratch

1. 切勿从零开始

When asked to create a template, always look for existing configuration first:
  • First check if a Docker image exists — search Docker Hub, GHCR (
    ghcr.io/org/repo
    ), or the project's CI/CD for published images. If none exists, stop and inform the user.
  • Search for the project's
    docker-compose.yml
    ,
    docker-compose.yaml
    , or
    compose.yml
  • Look for Helm charts (
    Chart.yaml
    ,
    values.yaml
    )
  • Check the project's GitHub repo for any deployment YAML files
  • Use these as the foundation to build the Zeabur template, not as a loose reference — they contain battle-tested environment variables, port mappings, volume mounts, and service dependencies
当被要求创建模板时,务必先寻找现有配置:
  • 首先检查是否存在Docker镜像——搜索Docker Hub、GHCR(
    ghcr.io/org/repo
    )或项目的CI/CD流程中是否有已发布的镜像。如果没有,请告知用户并停止操作。
  • 搜索项目的
    docker-compose.yml
    docker-compose.yaml
    compose.yml
    文件
  • 查找Helm Chart(
    Chart.yaml
    values.yaml
  • 检查项目的GitHub仓库中是否有任何部署YAML文件
  • 将这些作为构建Zeabur模板的基础,而非松散参考——它们包含经过验证的环境变量、端口映射、卷挂载和服务依赖关系

2. Iterate via runtime logs — never expect one-shot success

2. 通过运行时日志迭代——切勿期望一次性成功

Even experienced humans cannot create a working template in one shot. The workflow is an iterative loop:
  1. Write/update the template YAML
  2. Deploy the template
  3. It will likely fail — check runtime logs to find the cause
  4. Fix the issue in the template
  5. Delete the project and redeploy from scratch
  6. Repeat until the template achieves one-click deployment success
This is the normal process, not a sign of failure. Do not try to get everything perfect before deploying — deploy early, read logs, and iterate.
即使是经验丰富的开发者也无法一次性创建可用的模板。工作流程是一个迭代循环
  1. 编写/更新模板YAML
  2. 部署模板
  3. 很可能会失败——查看运行时日志找出原因
  4. 在模板中修复问题
  5. 删除项目并重新部署
  6. 重复直到模板实现一键部署成功
这是正常流程,并非失败的标志。不要试图在部署前做到完美——尽早部署、读取日志并迭代。

3. Reuse from existing templates — never write common services from scratch

3. 复用现有模板——切勿从零编写通用服务

When your template needs a common service (PostgreSQL, Redis, MySQL, MongoDB, etc.), do not write the service definition yourself. Instead:
  1. Search for existing templates that already use that service:
    bash
    npx zeabur@latest template search postgres
  2. Find a template that includes the service you need
  3. Get the raw template YAML to see the exact service definition:
    bash
    npx zeabur@latest template get -c TEMPLATE_CODE --raw
  4. Copy the service definition directly from that template into yours
How to judge template trustworthiness:
  • Many templates are created by regular users and may not work correctly
  • Prefer templates with more deployments — higher deployment count = more battle-tested
  • Prefer official templates over user-submitted ones — official templates are vetted by Zeabur team

当你的模板需要通用服务(PostgreSQL、Redis、MySQL、MongoDB等)时,请勿自行编写服务定义。请按以下步骤操作:
  1. 搜索已使用该服务的现有模板:
    bash
    npx zeabur@latest template search postgres
  2. 找到包含所需服务的模板
  3. 获取原始模板YAML以查看确切的服务定义:
    bash
    npx zeabur@latest template get -c TEMPLATE_CODE --raw
  4. 将该服务定义直接复制到你的模板中
如何判断模板的可信度:
  • 许多模板由普通用户创建,可能无法正常工作
  • 优先选择部署次数更多的模板——部署次数越多,经过的验证越充分
  • 优先选择官方模板而非用户提交的模板——官方模板经过Zeabur团队审核

CLI Commands for the Iteration Loop

迭代循环中的CLI命令

Deploy a template:
bash
npx zeabur@latest template deploy -f YOUR_TEMPLATE.yaml
For non-interactive mode (automation):
bash
npx zeabur@latest template deploy -i=false \
  -f YOUR_TEMPLATE.yaml \
  --project-id PROJECT_ID \
  --var PUBLIC_DOMAIN=myapp
List services (to get SERVICE_ID):
bash
npx zeabur@latest service list --project-id PROJECT_ID
Check runtime logs:
bash
npx zeabur@latest deployment log --service-id SERVICE_ID
Execute a command inside a running service (like
docker exec
):
bash
npx zeabur@latest service exec --id SERVICE_ID -- SHELL_COMMAND
This is extremely useful for debugging — check file paths, env vars, test connectivity, inspect the filesystem, etc. Examples:
bash
npx zeabur@latest service exec --id SERVICE_ID -- ls /app
npx zeabur@latest service exec --id SERVICE_ID -- env | grep DATABASE
npx zeabur@latest service exec --id SERVICE_ID -- nc -z localhost 5432
Restart a service (useful to clear ImagePullBackOff or force re-pull):
bash
npx zeabur@latest service restart --id SERVICE_ID -i=false -y
Delete the project and start over:
bash
npx zeabur@latest project delete --id PROJECT_ID
DANGEROUS OPERATION — Before deleting a project, you MUST ask the user for explicit confirmation, clearly stating the Project ID, Name, and createdAt timestamp. Never delete without confirmation.
Publish a new template:
bash
npx zeabur@latest template create -f YOUR_TEMPLATE.yaml
This returns a template URL like
https://zeabur.com/templates/XXXXXX
with a template code.
Update an existing template:
bash
npx zeabur@latest template update -c TEMPLATE_CODE -f YOUR_TEMPLATE.yaml

部署模板:
bash
npx zeabur@latest template deploy -f YOUR_TEMPLATE.yaml
非交互模式(自动化):
bash
npx zeabur@latest template deploy -i=false \
  -f YOUR_TEMPLATE.yaml \
  --project-id PROJECT_ID \
  --var PUBLIC_DOMAIN=myapp
列出服务(获取SERVICE_ID):
bash
npx zeabur@latest service list --project-id PROJECT_ID
查看运行时日志:
bash
npx zeabur@latest deployment log --service-id SERVICE_ID
在运行中的服务内执行命令(类似
docker exec
):
bash
npx zeabur@latest service exec --id SERVICE_ID -- SHELL_COMMAND
这对调试非常有用——检查文件路径、环境变量、测试连接、检查文件系统等。示例:
bash
npx zeabur@latest service exec --id SERVICE_ID -- ls /app
npx zeabur@latest service exec --id SERVICE_ID -- env | grep DATABASE
npx zeabur@latest service exec --id SERVICE_ID -- nc -z localhost 5432
重启服务(用于清除ImagePullBackOff或强制重新拉取镜像):
bash
npx zeabur@latest service restart --id SERVICE_ID -i=false -y
删除项目并重新开始:
bash
npx zeabur@latest project delete --id PROJECT_ID
危险操作——删除项目前,必须向用户确认,明确说明项目ID、名称和创建时间。未经确认切勿删除。
发布新模板:
bash
npx zeabur@latest template create -f YOUR_TEMPLATE.yaml
这会返回一个模板URL,例如
https://zeabur.com/templates/XXXXXX
,并附带一个模板代码。
更新现有模板:
bash
npx zeabur@latest template update -c TEMPLATE_CODE -f YOUR_TEMPLATE.yaml

Quick Reference: Template Skeleton

快速参考:模板骨架

yaml
undefined
yaml
undefined

yaml-language-server: $schema=https://schema.zeabur.app/template.json

yaml-language-server: $schema=https://schema.zeabur.app/template.json

apiVersion: zeabur.com/v1 kind: Template metadata: name: ServiceName spec: description: | English description (1-3 sentences) icon: https://raw.githubusercontent.com/zeabur/service-icons/main/marketplace/service.svg coverImage: https://example.com/cover.webp tags: - Category variables: [] readme: | # Service Name English documentation... services: - name: service-name icon: https://raw.githubusercontent.com/zeabur/service-icons/main/marketplace/service.svg template: PREBUILT_V2 spec: source: image: image:tag command: # MUST be inside source, alongside image - /bin/sh - -c - /opt/app/startup.sh ports: - id: web port: 8080 type: HTTP portForwarding: enabled: true # Auto-expose TCP/UDP ports externally (default: true) healthCheck: # ensures port is ready before dependents start type: TCP port: web # references the port ID above volumes: - id: data dir: /path/to/data configs: - path: /opt/app/startup.sh permission: 493 # 0755 envsubst: false template: | #!/bin/sh exec node server.js env: VAR_NAME: default: value expose: true localization: zh-TW: description: ... variables: [] readme: | # ... zh-CN: description: ... variables: [] readme: | # ... ja-JP: description: ... variables: [] readme: | # ... es-ES: description: ... variables: [] readme: | # ... id-ID: description: ... variables: [] readme: | # ...
undefined
apiVersion: zeabur.com/v1 kind: Template metadata: name: ServiceName spec: description: | 英文描述(1-3句话) icon: https://raw.githubusercontent.com/zeabur/service-icons/main/marketplace/service.svg coverImage: https://example.com/cover.webp tags: - Category variables: [] readme: | # 服务名称 英文文档... services: - name: service-name icon: https://raw.githubusercontent.com/zeabur/service-icons/main/marketplace/service.svg template: PREBUILT_V2 spec: source: image: image:tag command: # 必须在source内,与image同级 - /bin/sh - -c - /opt/app/startup.sh ports: - id: web port: 8080 type: HTTP portForwarding: enabled: true # 自动向外暴露TCP/UDP端口(默认:true) healthCheck: # 确保端口就绪后再启动依赖服务 type: TCP port: web # 引用上方的端口ID volumes: - id: data dir: /path/to/data configs: - path: /opt/app/startup.sh permission: 493 # 0755 envsubst: false template: | #!/bin/sh exec node server.js env: VAR_NAME: default: value expose: true localization: zh-TW: description: ... variables: [] readme: | # ... zh-CN: description: ... variables: [] readme: | # ... ja-JP: description: ... variables: [] readme: | # ... es-ES: description: ... variables: [] readme: | # ... id-ID: description: ... variables: [] readme: | # ...
undefined

Quick Reference: Built-in Variables

快速参考:内置变量

VariablePurpose
${PASSWORD}
Auto-generated secure password
${ZEABUR_WEB_URL}
Full public URL (e.g.
https://app.zeabur.app
)
${ZEABUR_WEB_DOMAIN}
Domain only (e.g.
app.zeabur.app
)
${CONTAINER_HOSTNAME}
Internal hostname for inter-service communication
${[PORTID]_PORT}
Port value by port ID (e.g.
${DATABASE_PORT}
)
${PORT_FORWARDED_HOSTNAME}
External hostname for port forwarding (auto-set when enabled, usable in env vars and
instructions
)
${[PORTID]_PORT_FORWARDED_PORT}
External forwarded port number (auto-set when enabled, usable in env vars and
instructions
)
The
ZEABUR_<PORT_ID>_URL
pattern: for a port named
web
, it becomes
${ZEABUR_WEB_URL}
; for
console
, it becomes
${ZEABUR_CONSOLE_URL}
.
变量用途
${PASSWORD}
自动生成的安全密码
${ZEABUR_WEB_URL}
完整的公共URL(例如
https://app.zeabur.app
${ZEABUR_WEB_DOMAIN}
仅域名(例如
app.zeabur.app
${CONTAINER_HOSTNAME}
服务间通信的内部主机名
${[PORTID]_PORT}
通过端口ID获取端口值(例如
${DATABASE_PORT}
${PORT_FORWARDED_HOSTNAME}
端口转发的外部主机名(启用时自动设置,可用于环境变量和
instructions
${[PORTID]_PORT_FORWARDED_PORT}
端口转发的外部端口号(启用时自动设置,可用于环境变量和
instructions
ZEABUR_<PORT_ID>_URL
模式:对于名为
web
的端口,变量为
${ZEABUR_WEB_URL}
;对于
console
端口,变量为
${ZEABUR_CONSOLE_URL}

Quick Reference: command Placement

快速参考:command的位置

IMPORTANT:
command
MUST be inside
source
, alongside
image
. NOT at
spec
level.
yaml
undefined
重要提示:
command
必须在
source
内,与
image
同级。不能在
spec
层级。
yaml
undefined

WRONG -- command at spec level (will be IGNORED, container uses default CMD)

错误写法 -- command在spec层级(会被忽略,容器使用默认CMD)

spec: source: image: python:3.12-slim command: - /bin/sh - -c - /opt/app/start.sh
spec: source: image: python:3.12-slim command: - /bin/sh - -c - /opt/app/start.sh

CORRECT -- command inside source

正确写法 -- command在source内

spec: source: image: python:3.12-slim command: - /bin/sh - -c - /opt/app/start.sh

> **Note:** The external docs may show `command` at `spec` level. This is incorrect. Always place `command` inside `source` as confirmed by the JSON schema at `schema.zeabur.app/prebuilt.json`.
spec: source: image: python:3.12-slim command: - /bin/sh - -c - /opt/app/start.sh

> **注意:** 外部文档可能显示`command`在`spec`层级,这是错误的。请始终按照`schema.zeabur.app/prebuilt.json`中的JSON Schema要求,将`command`放在`source`内。

Quick Reference: YAML Gotchas

快速参考:YAML陷阱

yaml
undefined
yaml
undefined

RISKY -- @ at start of value is a YAML reserved indicator (may cause parse errors)

风险 -- 值以@开头是YAML保留标识符(可能导致解析错误)

description: @BotFather token
description: @BotFather token

SAFE -- quote the value or avoid @ at start

安全写法 -- 给值加引号或避免@开头

description: "Token from @BotFather for Telegram bot" description: Telegram bot token from BotFather
undefined
description: "来自@BotFather的Telegram机器人令牌" description: Telegram机器人令牌(来自BotFather)
undefined

Quick Reference: Docker Image ENTRYPOINT

快速参考:Docker镜像ENTRYPOINT

Some base images have ENTRYPOINT set, which conflicts with
command
.
ImageENTRYPOINTProblem
ghcr.io/astral-sh/uv:python3.12-*
uv
command
becomes args to
uv
, container shows
uv help
and exits
node:*
noneSafe to use
python:*
noneSafe to use
If using an image with ENTRYPOINT, switch to a plain base image (e.g.
python:3.12-slim-bookworm
) or one without ENTRYPOINT.
某些基础镜像设置了ENTRYPOINT,这会与
command
冲突。
镜像ENTRYPOINT问题
ghcr.io/astral-sh/uv:python3.12-*
uv
command
会成为
uv
的参数,容器会显示
uv help
并退出
node:*
可安全使用
python:*
可安全使用
如果使用带有ENTRYPOINT的镜像,请切换到纯基础镜像(例如
python:3.12-slim-bookworm
)或无ENTRYPOINT的镜像。

Quick Reference: TCP Services (proxy, database, game server, etc.)

快速参考:TCP服务(代理、数据库、游戏服务器等)

Services that are NOT web apps — such as HTTP proxies (Tinyproxy, Squid), databases, game servers, VPN servers, or any service that clients connect to directly via TCP/UDP — should NOT use HTTP port type or
domainKey
. Instead:
  1. Use
    type: TCP
    (or
    UDP
    )
    — this prevents Zeabur's reverse proxy (Ingress) from intercepting traffic
  2. Set
    portForwarding: enabled: true
    — this auto-exposes the port externally so clients can connect directly
  3. Do NOT use
    domainKey
    — TCP services don't need a domain; users connect via the forwarded hostname:port
yaml
undefined
非Web应用服务——例如HTTP代理(Tinyproxy、Squid)、数据库、游戏服务器、VPN服务器或任何客户端直接通过TCP/UDP连接的服务——不应使用HTTP端口类型或
domainKey
。请按以下步骤操作:
  1. 使用
    type: TCP
    (或
    UDP
    ——这可防止Zeabur的反向代理(Ingress)拦截流量
  2. 设置
    portForwarding: enabled: true
    ——这会自动向外暴露端口,以便客户端直接连接
  3. 不要使用
    domainKey
    ——TCP服务不需要域名;用户通过转发的主机名:端口连接
yaml
undefined

CORRECT -- TCP service (e.g. HTTP proxy, database, game server)

正确写法 -- TCP服务(例如HTTP代理、数据库、游戏服务器)

spec: source: image: some/tcp-service:latest ports: - id: proxy port: 8888 type: TCP # NOT HTTP — clients connect directly portForwarding: enabled: true # Auto-expose this port externally env: # ...
spec: source: image: some/tcp-service:latest ports: - id: proxy port: 8888 type: TCP # 不要用HTTP——客户端直接连接 portForwarding: enabled: true # 自动向外暴露此端口 env: # ...

WRONG -- using HTTP type for a TCP proxy

错误写法 -- 为TCP代理使用HTTP类型

spec: ports: - id: proxy port: 8888 type: HTTP # Zeabur's Ingress will intercept CONNECT requests

Missing portForwarding — users must manually enable in Dashboard


**Why not HTTP?** Zeabur's HTTP port type routes traffic through a reverse proxy (Ingress/Envoy) that terminates TLS and performs Host-based routing. This breaks protocols like HTTP CONNECT (used by proxies), raw TCP streams (databases), and custom binary protocols (game servers).

**Port Forwarding variables** (for use in `instructions` or readme):
- `${PORT_FORWARDED_HOSTNAME}` — the external hostname
- `${PROXY_PORT_FORWARDED_PORT}` — the external port (pattern: `${[PORTID]_PORT_FORWARDED_PORT}`)

**Post-deployment testing for TCP services:**

After deploying a TCP service, verify port forwarding is working:

1. Check internal connectivity first (from inside the container):
   ```bash
   npx zeabur@latest service exec --id SERVICE_ID -- curl -x http://127.0.0.1:8888 https://ifconfig.co
  1. Get the forwarded host:port from the Dashboard's Networking tab, or use:
    bash
    npx zeabur@latest service network --id SERVICE_ID
  2. Test external connectivity:
    bash
    curl -x http://FORWARDED_HOST:FORWARDED_PORT https://ifconfig.co
If port forwarding shows as DISABLED, enable it:
bash
npx zeabur@latest service port-forward --id SERVICE_ID --enable
spec: ports: - id: proxy port: 8888 type: HTTP # Zeabur的Ingress会拦截CONNECT请求

缺少portForwarding——用户必须在控制台手动启用


**为什么不使用HTTP?** Zeabur的HTTP端口类型通过反向代理(Ingress/Envoy)路由流量,终止TLS并基于主机名进行路由。这会破坏HTTP CONNECT(代理使用)、原始TCP流(数据库)和自定义二进制协议(游戏服务器)等协议。

**端口转发变量**(用于`instructions`或readme):
- `${PORT_FORWARDED_HOSTNAME}` —— 外部主机名
- `${PROXY_PORT_FORWARDED_PORT}` —— 外部端口(模式:`${[PORTID]_PORT_FORWARDED_PORT}`)

**TCP服务部署后测试:**

部署TCP服务后,验证端口转发是否正常工作:

1. 首先检查内部连通性(从容器内部):
   ```bash
   npx zeabur@latest service exec --id SERVICE_ID -- curl -x http://127.0.0.1:8888 https://ifconfig.co
  1. 从控制台的网络选项卡获取转发的主机:端口,或使用以下命令:
    bash
    npx zeabur@latest service network --id SERVICE_ID
  2. 测试外部连通性:
    bash
    curl -x http://FORWARDED_HOST:FORWARDED_PORT https://ifconfig.co
如果端口转发显示为禁用,启用它:
bash
npx zeabur@latest service port-forward --id SERVICE_ID --enable

Quick Reference: Headless Services (no HTTP)

快速参考:无头服务(无HTTP)

If a service does NOT listen on any HTTP port (502 Bad Gateway), see
zeabur-port-mismatch
skill for the fix.
如果服务未监听任何HTTP端口(出现502 Bad Gateway错误),请查看
zeabur-port-mismatch
技能获取解决方案。

Quick Reference: Critical Rules

快速参考:关键规则

yaml
undefined
yaml
undefined

WRONG -- using :latest tag (may serve cached/stale image)

错误写法 -- 使用:latest标签(可能提供缓存/过时的镜像)

image: rajnandan1/kener:latest
image: rajnandan1/kener:latest

CORRECT -- pin to specific version

正确写法 -- 固定到特定版本

image: rajnandan1/kener:4.0.16
image: rajnandan1/kener:4.0.16

WRONG -- hardcoded password

错误写法 -- 硬编码密码

POSTGRES_PASSWORD: default: mypassword123
POSTGRES_PASSWORD: default: mypassword123

CORRECT -- use ${PASSWORD}

正确写法 -- 使用${PASSWORD}

POSTGRES_PASSWORD: default: ${PASSWORD} expose: true
POSTGRES_PASSWORD: default: ${PASSWORD} expose: true

WRONG -- PUBLIC_DOMAIN gives incomplete URL

错误写法 -- PUBLIC_DOMAIN提供不完整的URL

APP_URL: default: https://${PUBLIC_DOMAIN}
APP_URL: default: https://${PUBLIC_DOMAIN}

CORRECT -- ZEABUR_WEB_URL gives full URL

正确写法 -- ZEABUR_WEB_URL提供完整URL

APP_URL: default: ${ZEABUR_WEB_URL} readonly: true
APP_URL: default: ${ZEABUR_WEB_URL} readonly: true

WRONG -- other services can't reference without expose

错误写法 -- 未声明依赖就引用变量

POSTGRES_HOST: default: ${CONTAINER_HOSTNAME}
  • name: app spec: env: DB: ${POSTGRES_HOST}

CORRECT -- expose + readonly for connection info

正确写法 -- 先声明依赖

POSTGRES_HOST: default: ${CONTAINER_HOSTNAME} expose: true readonly: true
  • name: app dependencies:
    • postgresql spec: env: DB: ${POSTGRES_HOST}

WRONG -- referencing variables without declaring dependency

错误写法 -- 为TCP代理/数据库/游戏服务器使用HTTP类型

  • name: app spec: env: DB: ${POSTGRES_HOST}
ports:
  • id: proxy port: 8888 type: HTTP

CORRECT -- declare dependency first

正确写法 -- 非Web服务使用TCP类型+portForwarding

  • name: app dependencies:
    • postgresql spec: env: DB: ${POSTGRES_HOST}
ports:
  • id: proxy port: 8888 type: TCP portForwarding: enabled: true

---

WRONG -- HTTP type for a TCP proxy/database/game server

域名绑定

ports:
  • id: proxy port: 8888 type: HTTP
在需要公共域名的服务上使用
domainKey
。它会映射到
spec.variables
中定义的
type: DOMAIN
类型的变量。
单个域名:
yaml
domainKey: PUBLIC_DOMAIN
多个域名(不同端口):
yaml
domainKey:
    - port: web
      variable: ENDPOINT_DOMAIN
    - port: console
      variable: ADMIN_ENDPOINT_DOMAIN

CORRECT -- TCP type + portForwarding for non-web services

常见数据库配置

ports:
  • id: proxy port: 8888 type: TCP portForwarding: enabled: true

---
请查看
references/database-configs.md
获取可直接复制的PostgreSQL、MySQL/MariaDB、Redis配置和标准卷路径。

Domain Binding

模板复杂度等级

Use
domainKey
on the service that needs a public domain. It maps to a variable defined in
spec.variables
with
type: DOMAIN
.
Single domain:
yaml
domainKey: PUBLIC_DOMAIN
Multiple domains (different ports):
yaml
domainKey:
    - port: web
      variable: ENDPOINT_DOMAIN
    - port: console
      variable: ADMIN_ENDPOINT_DOMAIN

请查看
references/complexity-levels.md
获取5级复杂度指南(从单服务到大规模多服务平台)。

Common Database Configs

编写名称、描述、readme、图标和封面图

See
references/database-configs.md
for copy-paste PostgreSQL, MySQL/MariaDB, Redis configs and standard volume paths.

信息收集来源(优先级排序):
  1. 项目的GitHub仓库README
  2. 项目的官方网站
  3. 其他公开来源(博客文章、文档网站等)
关键规则:
  1. 请勿直接复制原始README。 请为该项目的Zeabur模板编写介绍,而非项目本身的介绍。readme应:
    • 简要介绍项目是什么
    • 重点说明如何使用此模板(部署步骤、配置、域名绑定)
    • 包含与Zeabur部署相关的重要注意事项和故障排除提示
  2. 始终包含许可和归属信息。 如果原始项目采用MIT、Apache或其他许可证:
    • 在readme中提及许可证
    • 链接到原始仓库
    • 如果有官方网站,也请链接
    • 这是法律要求——切勿遗漏
  3. 图标和封面图:从项目的GitHub仓库或官方网站获取项目标志。使用直接的图片URL(SVG、PNG或WebP格式)。始终验证URL返回HTTP 200状态码
    bash
    curl -s -o /dev/null -w "%{http_code}" "URL"
    常见陷阱:
    raw.githubusercontent.com
    URL中的分支名称错误(
    develop
    main
    master
    混淆)。

Template Complexity Levels

本地化要求

See
references/complexity-levels.md
for the 5-level complexity guide (single service → large-scale multi-service platform).

需要支持6种语言:en-US(在
spec
中)、zh-TW、zh-CN、ja-JP、es-ES、id-ID。
需要翻译的内容:
description
variables[].name
variables[].description
readme
请勿翻译的内容:
key
type
${VARIABLE_NAMES}
、URL

Writing name, description, readme, icon, and coverImage

经验教训

Where to collect information (in priority order):
  1. The project's GitHub repo README
  2. The project's official website
  3. Other public sources (blog posts, documentation sites, etc.)
Key rules:
  1. Do NOT copy-paste the original README. Write the introduction for this project's Zeabur template, not for the project itself. The readme should:
    • Briefly introduce what the project is
    • Focus on how to use this template (deployment steps, configuration, domain binding)
    • Include important caveats and troubleshooting tips specific to Zeabur deployment
  2. Always include licensing and attribution. If the original project has an MIT, Apache, or other license:
    • Mention the license in the readme
    • Link to the original repo
    • Link to the official website if available
    • This is legally required -- never skip it
  3. icon and coverImage: Find the project's logo from their GitHub repo or official website. Use a direct URL to an image (SVG, PNG, or WebP). Always verify the URL returns HTTP 200:
    bash
    curl -s -o /dev/null -w "%{http_code}" "URL"
    Common pitfall: wrong branch name in
    raw.githubusercontent.com
    URLs (
    develop
    vs
    main
    vs
    master
    ).
请查看
references/hard-won-lessons.md
获取经过验证的模式:等待数据库就绪、首次运行初始化标记、OOM恢复、ImagePullBackOff等内容。

Localization Requirements

6 languages required: en-US (in
spec
), zh-TW, zh-CN, ja-JP, es-ES, id-ID.
Translate:
description
,
variables[].name
,
variables[].description
,
readme
Do NOT translate:
key
,
type
,
${VARIABLE_NAMES}
, URLs

Hard-Won Lessons

See
references/hard-won-lessons.md
for battle-tested patterns: wait-for-db, first-run init markers, OOM recovery, ImagePullBackOff, and more.