mcpField
Z
zeabur-template

zeabur-template

github.com/zeabur云与 DevOps39189 次安装7 周前更新
代码仓库

关于 zeabur-template

面向创建、调试和发布 Zeabur 模板的开发者,汇总模板结构、部署迭代及常见配置规则。内容还涵盖 Docker 镜像、端口、域名和内置变量等参考。

主要功能

  1. 01指导模板创建与发布
  2. 02提供 YAML 结构和变量参考
  3. 03介绍部署日志驱动的调试流程
  4. 04说明 Docker 镜像与服务配置规则
  5. 05涵盖域名和 TCP 端口配置

适用场景

  1. 01从现有 Docker 镜像创建模板
  2. 02排查模板部署故障
  3. 03配置模板中的数据库与公开域名
  4. 04检查 TCP 服务的端口转发配置

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/zeabur/agent-skills --skill zeabur-template

安装后在 Claude Code 中输入/zeabur-template确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
complexity-levels.md
database-configs.md
hard-won-lessons.md

详细介绍

Zeabur 模板知识库

始终使用 npx zeabur@latest 调用 Zeabur CLI。 切勿直接使用 zeabur 或通过其他安装方式使用。如果无法使用 npx,请先安装 Node.js。

本技能提供创建、调试和发布 Zeabur 模板所需的全面知识,结合了参考文档与真实模板开发中经实践验证的模式。

外部文档

如需获取最新架构和详细文档,请从 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

模板 YAML 架构也可在 https://schema.zeabur.app/template.json 获取,预构建服务架构可在 https://schema.zeabur.app/prebuilt.json 获取。


核心原则

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

模板中的每项服务都必须设置为 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):
    docker buildx build --platform linux/amd64 --target runner -t org/image:tag --push .
    
  5. 推送后,确认 Docker Hub 仓库为公开状态:
    curl -s "https://hub.docker.com/v2/repositories/ORG/IMAGE/" | grep is_private
    
    组织账号下的新仓库通常默认设为私有。如果 is_private: true,用户必须在 Docker Hub 上将其设为公开。
1. 切勿从头开始

收到创建模板的请求时,务必先查找现有配置:

  • 首先检查是否存在 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. 根据运行时日志迭代——不要指望一次成功

即使是经验丰富的开发者,也无法一次就创建出可正常运行的模板。工作流是一个迭代循环:

  1. 编写或更新模板 YAML
  2. 部署模板
  3. 很可能会失败——检查运行时日志以找到原因
  4. 修复模板中的问题
  5. 删除项目,并从头重新部署
  6. 重复以上步骤,直到模板实现一键部署成功

这是正常流程,并不意味着失败。不要试图在部署前把所有事情都做到完美——尽早部署、查看日志并持续迭代。

3. 复用现有模板——切勿从头编写常见服务

当模板需要常见服务(PostgreSQL、Redis、MySQL、MongoDB 等)时,不要自行编写服务定义。请改为:

  1. 搜索已使用该服务的现有模板:
    npx zeabur@latest template search postgres
    
  2. 找到包含所需服务的模板
  3. 获取模板的原始 YAML,查看确切的服务定义:
    npx zeabur@latest template get -c TEMPLATE_CODE --raw
    
  4. 将服务定义直接从该模板复制到你的模板中

如何判断模板是否可信:

  • 许多模板由普通用户创建,可能无法正常运行
  • 优先选择部署次数更多的模板——部署次数越多,经过的实战检验越充分
  • 优先选择官方模板,而非用户提交的模板——Zeabur 团队会审核官方模板

迭代循环的 CLI 命令

部署模板:

npx zeabur@latest template deploy -f YOUR_TEMPLATE.yaml

用于非交互模式(自动化):

npx zeabur@latest template deploy -i=false \
  -f YOUR_TEMPLATE.yaml \
  --project-id PROJECT_ID \
  --var PUBLIC_DOMAIN=myapp

列出服务(以获取 SERVICE_ID):

npx zeabur@latest service list --project-id PROJECT_ID

检查运行时日志:

npx zeabur@latest deployment log --service-id SERVICE_ID

在运行中的服务内执行命令(类似于 docker exec):

npx zeabur@latest service exec --id SERVICE_ID -- SHELL_COMMAND

这对调试非常有用——可检查文件路径、环境变量、测试连接、查看文件系统等。示例:

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 或强制重新拉取):

npx zeabur@latest service restart --id SERVICE_ID -i=false -y

删除项目并重新开始:

npx zeabur@latest project delete --id PROJECT_ID

危险操作——删除项目之前,必须征得用户的明确确认,并清楚说明 Project ID、Name 和 createdAt 时间戳。未经确认,绝不删除。

发布新模板:

npx zeabur@latest template create -f YOUR_TEMPLATE.yaml

这会返回一个模板 URL,例如 https://zeabur.com/templates/XXXXXX,其中包含模板代码。

更新现有模板:

npx zeabur@latest template update -c TEMPLATE_CODE -f YOUR_TEMPLATE.yaml

快速参考:模板框架

# 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: |
      # ...

快速参考:内置变量

变量用途
${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}。

快速参考:command 的位置

重要:command 必须放在 source 内,与 image 并列。不得放在 spec 层级。

# WRONG -- command at spec level (will be IGNORED, container uses default CMD)
spec:
  source:
    image: python:3.12-slim
  command:
    - /bin/sh
    - -c
    - /opt/app/start.sh

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

注意: 外部文档可能会将 command 放在 spec 层级。这是不正确的。请始终将 command 放在 source 内,JSON schema(schema.zeabur.app/prebuilt.json)已确认此做法。

快速参考:YAML 注意事项

# RISKY -- @ at start of value is a YAML reserved indicator (may cause parse errors)
description: @BotFather token

# SAFE -- quote the value or avoid @ at start
description: "Token from @BotFather for Telegram bot"
description: Telegram bot token from BotFather

快速参考:Docker 镜像 ENTRYPOINT

某些基础镜像设置了 ENTRYPOINT,这会与 command 冲突。

镜像ENTRYPOINT问题
ghcr.io/astral-sh/uv:python3.12-*uvcommand 会变成传给 uv 的参数,容器会显示 uv help 后退出
node:*无可安全使用
python:*无可安全使用

如果使用的镜像设置了 ENTRYPOINT,请换用普通基础镜像(例如 python:3.12-slim-bookworm)或未设置 ENTRYPOINT 的镜像。

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

非 Web 应用的服务——例如 HTTP 代理(Tinyproxy、Squid)、数据库、游戏服务器、VPN 服务器,或客户端通过 TCP/UDP 直接连接的任何服务——不得使用 HTTP 端口类型或 domainKey。请改为:

  1. 使用 type: TCP(或 UDP)——这样可防止 Zeabur 的反向代理(Ingress)拦截流量
  2. 设置 portForwarding: enabled: true——自动将端口暴露到外部,以便客户端直接连接
  3. 不要使用 domainKey——TCP 服务不需要域名;用户通过转发的主机名和端口连接
# CORRECT -- TCP service (e.g. HTTP proxy, database, game server)
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:
    # ...

# WRONG -- using HTTP type for a TCP proxy
spec:
  ports:
    - id: proxy
      port: 8888
      type: HTTP         # Zeabur's Ingress will intercept CONNECT requests
  # Missing portForwarding — users must manually enable in Dashboard

为什么不能使用 HTTP? Zeabur 的 HTTP 端口类型会通过反向代理(Ingress/Envoy)路由流量,由该代理终止 TLS 并执行基于 Host 的路由。这会导致 HTTP CONNECT(代理使用的协议)、原始 TCP 数据流(数据库使用)和自定义二进制协议(游戏服务器使用)等协议无法正常工作。

端口转发变量(用于 instructions 或 readme):

  • ${PORT_FORWARDED_HOSTNAME} — 外部主机名
  • ${PROXY_PORT_FORWARDED_PORT} — 外部端口(格式:${[PORTID]_PORT_FORWARDED_PORT})

TCP 服务部署后的测试:

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

  1. 首先检查内部连接(在容器内):

    npx zeabur@latest service exec --id SERVICE_ID -- curl -x http://127.0.0.1:8888 https://ifconfig.co
    
  2. 从 Dashboard 的 Networking 标签页获取转发的主机名和端口,或使用:

    npx zeabur@latest service network --id SERVICE_ID
    
  3. 测试外部连接:

    curl -x http://FORWARDED_HOST:FORWARDED_PORT https://ifconfig.co
    

如果端口转发显示为 DISABLED,请启用它:

npx zeabur@latest service port-forward --id SERVICE_ID --enable

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

如果服务没有监听任何 HTTP 端口(502 Bad Gateway),请参阅 zeabur-port-mismatch 技能了解修复方法。

快速参考:关键规则

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

# CORRECT -- pin to specific version
image: rajnandan1/kener:4.0.16

# WRONG -- hardcoded password
POSTGRES_PASSWORD:
  default: mypassword123

# CORRECT -- use ${PASSWORD}
POSTGRES_PASSWORD:
  default: ${PASSWORD}
  expose: true

# WRONG -- PUBLIC_DOMAIN gives incomplete URL
APP_URL:
  default: https://${PUBLIC_DOMAIN}

# CORRECT -- ZEABUR_WEB_URL gives full URL
APP_URL:
  default: ${ZEABUR_WEB_URL}
  readonly: true

# WRONG -- other services can't reference without expose
POSTGRES_HOST:
  default: ${CONTAINER_HOSTNAME}

# CORRECT -- expose + readonly for connection info
POSTGRES_HOST:
  default: ${CONTAINER_HOSTNAME}
  expose: true
  readonly: true

# WRONG -- referencing variables without declaring dependency
- name: app
  spec:
    env:
      DB: ${POSTGRES_HOST}

# CORRECT -- declare dependency first
- name: app
  dependencies:
    - postgresql
  spec:
    env:
      DB: ${POSTGRES_HOST}

# WRONG -- HTTP type for a TCP proxy/database/game server
ports:
  - id: proxy
    port: 8888
    type: HTTP

# CORRECT -- TCP type + portForwarding for non-web services
ports:
  - id: proxy
    port: 8888
    type: TCP
portForwarding:
  enabled: true

域名绑定

在需要公共域名的服务上使用 domainKey。它对应于 spec.variables 中定义的 type: DOMAIN 变量。

单个域名:

domainKey: PUBLIC_DOMAIN

多个域名(不同端口):

domainKey:
    - port: web
      variable: ENDPOINT_DOMAIN
    - port: console
      variable: ADMIN_ENDPOINT_DOMAIN

常见数据库配置

请参阅 references/database-configs.md,查看可直接复制粘贴的 PostgreSQL、MySQL/MariaDB、Redis 配置以及标准卷路径。


模板复杂度级别

请参阅 references/complexity-levels.md,了解 5 级复杂度指南(从单个服务到大型多服务平台)。


编写 name、description、readme、icon 和 coverImage

信息来源(按优先级排序):

  1. 项目的 GitHub 仓库 README
  2. 项目的官方网站
  3. 其他公开来源(博客文章、文档网站等)

关键规则:

  1. 不要直接复制粘贴原始 README。 请撰写关于该项目的 Zeabur 模板的介绍,而不是介绍项目本身。readme 应:
    • 简要介绍项目是什么
    • 重点说明如何使用此模板(部署步骤、配置、域名绑定)
    • 包含与 Zeabur 部署相关的重要注意事项和故障排除技巧
  2. 始终注明许可证和出处。 如果原项目采用 MIT、Apache 或其他许可证:
    • 在 readme 中注明许可证
    • 链接到原始仓库
    • 如果有官方网站,也要添加链接
    • 这是法律要求——绝不可省略
  3. icon 和 coverImage:从项目的 GitHub 仓库或官方网站查找其 Logo。使用指向图片(SVG、PNG 或 WebP)的直接 URL。务必确认 URL 返回 HTTP 200:
    curl -s -o /dev/null -w "%{http_code}" "URL"
    
    常见问题:raw.githubusercontent.com URL 中的分支名称错误(develop、main 或 master)。

本地化要求

必须提供 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


经验教训

请参阅 references/hard-won-lessons.md,了解经过实践验证的模式:wait-for-db、首次运行初始化标记、OOM 恢复、ImagePullBackOff 等。

评论

支持 Markdown