关于 eve-manifest-authoring
面向 Eve 项目维护者的技能,指导编写和迁移 v2 manifest,以统一描述构建、部署、服务、数据库和认证配置。
主要功能
- 01编写与迁移 v2 manifest
- 02配置服务构建与镜像仓库
- 03声明托管数据库与迁移任务
- 04定义环境、流水线和工作流
- 05设置域名、认证与权限
适用场景
- 01为 Eve 项目创建部署配置
- 02把旧版 components manifest 迁移到 services
- 03配置数据库部署与 SQL 迁移
- 04限制服务令牌及工作流步骤权限
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ incept5/ eve-skillpacks --skill eve-manifest-authoring安装后在 Claude Code 中输入/eve-manifest-authoring确认已加载。
详细介绍
Eve 清单编写
让清单成为构建和部署行为的唯一事实来源。
最简框架(v2)
schema: eve/compose/v2
project: my-project
registry: "eve" # Use managed registry by default for Eve apps
services:
api:
build:
context: ./apps/api # Build context directory
dockerfile: Dockerfile # Optional, defaults to context/Dockerfile
# image omitted by default; when build is present, Eve derives image name from service key
ports: [3000]
environment:
NODE_ENV: production
x-eve:
ingress:
public: true
port: 3000
environments:
staging:
pipeline: deploy
pipeline_inputs:
some_key: default_value
pipelines:
deploy:
steps:
- name: build
action:
type: build # Builds all services with build: config
- name: release
depends_on: [build]
action:
type: release
- name: deploy
depends_on: [release]
action:
type: deploy
镜像仓库标签
有些镜像仓库需要包元数据来继承权限和所有权。 如果镜像仓库支持,请在 Dockerfile 中添加这些标签:
LABEL org.opencontainers.image.source="https://github.com/YOUR_ORG/YOUR_REPO"
LABEL org.opencontainers.image.description="Service description"
为何重要:元数据有助于保留仓库所有权并提高可追溯性。Eve 构建器会自动注入这些标签,但仍建议在 Dockerfile 中包含它们。
对于多阶段 Dockerfile,请将标签添加到最终阶段(生产镜像)。
镜像仓库模式
registry: "eve" # Eve-native registry (internal JWT auth)
registry: "none" # Disable registry handling (public images)
registry: # BYO registry (full object — see section below)
host: public.ecr.aws/w7c4v0w3
namespace: myorg
auth: { username_secret: REGISTRY_USERNAME, token_secret: REGISTRY_PASSWORD }
对于自带镜像仓库/私有镜像仓库,请提供:
registry:
host: public.ecr.aws/w7c4v0w3
namespace: myorg
auth:
username_secret: REGISTRY_USERNAME
token_secret: REGISTRY_PASSWORD
托管数据库
使用 x-eve.role: managed_db 声明由平台配置的数据库:
services:
db:
x-eve:
role: managed_db
managed:
class: db.p1
engine: postgres
engine_version: "16"
不会部署到 K8s — 由编排器在首次部署时配置。
在其他位置引用托管值:${managed.db.url}。
使用 Eve-Migrate 进行数据库迁移
使用平台的迁移运行器,而不是 Flyway、TypeORM 或 Knex。它使用带时间戳前缀的纯 SQL 文件,并在 schema_migrations 中进行跟踪:
services:
migrate:
image: public.ecr.aws/w7c4v0w3/eve-horizon/migrate:latest
environment:
DATABASE_URL: ${managed.db.url}
MIGRATIONS_DIR: /migrations
x-eve:
role: job
files:
- source: db/migrations
target: /migrations
迁移文件:db/migrations/20260312000000_initial_schema.sql。x-eve.files 指令会将这些文件挂载到容器中的 /migrations。
在流水线中,migrate 步骤必须在部署后运行(托管数据库需要先完成配置):
pipelines:
deploy:
steps:
- name: build
action: { type: build }
- name: release
depends_on: [build]
action: { type: release }
- name: deploy
depends_on: [release]
action: { type: deploy }
- name: migrate
depends_on: [deploy]
action: { type: job, service: migrate }
对于本地开发,请通过 Docker Compose 使用相同的镜像,以保持一致:
# docker-compose.yml
services:
migrate:
image: ghcr.io/eve-horizon/eve-migrate:latest
environment:
DATABASE_URL: postgres://app:app@db:5432/myapp
volumes:
- ./db/migrations:/migrations:ro
depends_on:
db: { condition: service_healthy }
旧版清单
如果仓库仍使用旧版清单中的 components:,请迁移到 services:
并添加 schema: eve/compose/v2。端口和 env 键保持不变。
服务
- 提供
image,并可选择提供build(context 和 dockerfile)。 - 按需使用
ports、environment、healthcheck、depends_on。 - 对于托管在外部的服务,请使用
x-eve.external: true和x-eve.connection_url。 - 对于一次性服务(迁移、种子数据),请使用
x-eve.role: job。对于数据库迁移,优先使用 Eve 的eve-migrate镜像(见下文)。
构建配置
使用 Docker 镜像的服务应定义其构建配置:
services:
api:
build:
context: ./apps/api # Build context directory
dockerfile: Dockerfile # Optional, defaults to context/Dockerfile
# image: api # optional if using build; managed registry derives this
ports: [3000]
注意:每个部署流水线都应在 release 之前包含一个 build 步骤。构建步骤会创建有跟踪记录的 BuildSpec/BuildRun 记录,并生成镜像摘要,供发布流程用于实现确定性部署。
本地开发对齐
- 使服务名称和端口与 Docker Compose 保持一致。
- 优先使用
${secret.KEY},并将.eve/dev-secrets.yaml用于本地值。
环境、流水线、工作流
- 通过
environments.<env>.pipeline将每个环境关联到一个流水线。 - 设置
pipeline后,eve env deploy <env>会触发该流水线,而不是直接部署。 - 使用
environments.<env>.pipeline_inputs为流水线运行提供默认输入。 - 使用
eve env deploy <env> --ref <sha> --inputs '{"key":"value"}' --repo-dir ./my-app在运行时覆盖输入。 - 使用
--direct标志绕过流水线并直接部署:eve env deploy <env> --ref <sha> --direct --repo-dir ./my-app。 - 流水线步骤可以是
action、script或agent。 - 配置后,使用
action.type: create-pr执行 PR 自动化。 - 工作流位于
workflows下,通过 CLI 调用;db_access会生效。 - 工作流步骤支持为每个步骤设置
harness、harness_profile和harness_options(覆盖 Agent 解析的值)、用于根据上游步骤状态控制是否跳过的condition,以及git控制项(现已在调度时正确实例化)。完整的步骤结构请参阅references/manifest.md。 - 工作流级和步骤级的
scope块可缩小步骤作业令牌和组织文件系统挂载的权限范围。支持的维度:orgfs、orgdocs、envdb、cloud_fs。步骤范围与工作流范围取交集——调用范围可以进一步缩小,但不能扩大。可使用它仅授予步骤所需的路径、表和挂载权限,其余一律默认拒绝。
workflows:
create-design:
scope:
orgfs: { allow_prefixes: [/groups/projects/proj-a/**] }
steps:
- name: publish
scope:
cloud_fs: { allow_mount_ids: [mount_a] }
agent: { name: publisher }
请求中提供的 scope(工作流调用 API 正文)需要 jobs:harness_override。目前还没有 --scope-* CLI 标志。
自定义域名和稳定出口流量
自带主机名和选择启用的网络配置按服务声明:
services:
api:
x-eve:
ingress:
public: true
port: 3000
domains: ["app.example.com", "www.example.com"] # max 10
networking:
egress: stable # default 'nat'; opt in only when a vendor needs allowlisted source IPs
ingress.domains会在首次部署时绑定:第一个使用某主机名部署的环境拥有该主机名;其他引用同一主机名的环境会记录owned by environment "<A>"并跳过渲染。使用eve domain list|verify|status|transfer|unbind|remove管理所有权(参阅eve-deploy-debugging)。networking.egress: stable会将 Pod 调度到稳定出口节点组,并设置hostNetwork: true。它会绕过 NAT 并限制调度,仅在需要时启用。
完整字段结构(验证规则、最大数量、按环境覆盖)请参阅 references/manifest.md。
项目品牌和身份验证
面向应用的登录、邀请邮件和魔法链接邮件均限定于项目,并在 x-eve.branding / x-eve.auth 中声明。eve project sync 会将二者写入项目记录;SSO 代理和 Eve API 邮件发送器会从中读取配置。
x-eve.branding — 邀请邮件和魔法链接邮件品牌设置
x-eve:
branding:
app_name: "ACME Portal" # required, <=60 chars
app_logo_url: "https://app.example.com/logo.svg" # https only on emitted mail
primary_color: "#1f6feb" # six-digit hex
email_from_name: "ACME Portal" # From-name header
reply_to_email: "[email protected]"
support_email: "[email protected]"
support_url: "https://example.com/help"
email_from_name、reply_to_email、support_email 会为应用级邮件设置邮件头,同时保留平台已验证的发件人地址。第一阶段会在邀请邮件和魔法链接邮件模板中显示 Logo、名称和主色。
x-eve.auth.login_method: magic_link — 无密码应用
x-eve:
auth:
login_method: magic_link # password_or_magic_link | password | magic_link
self_signup: false
invite_requires_password: false
按项目选择启用。使用 magic_link 时,SSO 登录页面会隐藏密码和注册选项;Eve API 会通过 POST /auth/magic-link(而非直接调用 GoTrue)发送品牌化魔法链接邮件,因此当 self_signup: false 时,对于未知邮箱会返回通用成功响应,但不会创建 GoTrue 用户。设置 invite_requires_password: false 后,接受邀请即可建立会话,并跳过 /set-password。使用 password_or_magic_link 可保留密码登录,并增加次要的品牌化魔法链接控件。
x-eve.auth.org_access.domain_signup — 预先批准的邮箱域名
x-eve:
auth:
org_access:
mode: allowlist
allowed_orgs: [org_acme, org_partner]
domain_signup:
enabled: true
domains:
- { domain: acme.com, target_org: org_acme, role: member }
- { domain: partner.example, target_org: org_partner }
- { domain: "*.acme.com", target_org: org_acme } # wildcard; apex needs its own rule
v2 结构(2026-05-12)。每个 domains[] 条目都是一个带有独立必填 target_org 的对象;不再接受旧版的字符串列表加块级 target_org 结构。每个 target_org 必须已出现在 allowed_orgs 中。匹配时按声明顺序采用第一条规则;更具体的模式应优先声明。与 login_method: password 同时使用时无效。免费邮箱域名(free-mail.example、outlook.com 等)会触发一致性警告——声明这些域名意味着地球上的任何人都可以加入。
x-eve.auth.allowed_redirect_origins — 自定义域名应用
x-eve:
auth:
allowed_redirect_origins:
- https://app.example.com
- https://www.example.com
仅限来源 — scheme://host[:port]。路径、查询参数、片段和用户信息会在同步时被拒绝。http:// 仅允许用于 localhost、环回 IP 和 *.lvh.me。SSO broker 还会自动纳入项目符合条件的 custom_domains 行,以及(在 allowlist 模式下)由 allowed_orgs 中的同级组织拥有的自定义域名,因此,已注册自定义域名的项目无需在此重复填写。使用 eve project auth-context <project_id> 确认解析后的列表。
完整验证规则(电子邮件域名语法、IDN 规范化、重复项检测、重定向来源规范化)请参阅 references/manifest.md。
服务令牌权限
每个已部署的服务都会自动注入一个 EVE_SERVICE_TOKEN,其默认权限为只读。请明确声明所需的任何写入范围 — 未声明的权限一律拒绝:
services:
api:
x-eve:
permissions: [jobs:write, events:write, threads:write]
已声明的权限会与只读默认权限合并;你只需列出新增的权限。默认不声明任何权限,并在服务确实需要时逐项授予写入范围。完整权限目录请参阅 references/manifest.md。
平台注入的环境变量
Eve 会自动将以下变量注入所有已部署的服务容器:
| 变量 | 描述 |
|---|---|
EVE_API_URL | 用于服务端到服务端调用的内部集群 URL |
EVE_PUBLIC_API_URL | 面向浏览器应用的公共入口 URL |
EVE_PROJECT_ID | 项目 ID |
EVE_ORG_ID | 组织 ID |
EVE_ENV_NAME | 环境名称 |
容器中的后端调用请使用 EVE_API_URL。浏览器/客户端代码请使用 EVE_PUBLIC_API_URL。服务可以在其 environment 部分覆盖这些变量。
插值和机密信息
- 环境变量插值:
${ENV_NAME}、${PROJECT_ID}、${ORG_ID}、${ORG_SLUG}、${COMPONENT_NAME}。 - 机密信息插值:
${secret.KEY}从 Eve 机密信息或.eve/dev-secrets.yaml中读取。 - 托管数据库插值:
${managed.<service>.<field>}在部署时解析。 - 本地覆盖请使用
.eve/dev-secrets.yaml;生产环境的真实机密信息请通过 API 设置。
Eve 扩展
- 通过
x-eve.defaults设置顶层默认值(env、harness、harness_profile、harness_options、hints、git、workspace)。 - 通过
x-eve.agents设置顶层 Agent 策略(profiles、councils、availability rules)。 - 通过
x-eve.packs配置 Agent 包,并可选设置x-eve.install_agents默认值。 - 通过
x-eve.agents.config_path和x-eve.agents.teams_path配置 Agent 配置路径。 - 通过
x-eve.chat.config_path配置聊天路由。 - 在
x-eve下配置服务扩展(ingress、role、API 规范、worker pools、cli、object_store、networking、permissions)。 - API 规范:
x-eve.api_spec或x-eve.api_specs(默认情况下,规范 URL 相对于服务)。 - 应用 CLI:
x-eve.cli为服务声明适合 Agent 使用的 CLI(见下文)。 - 工具链:Agent 级别的
toolchains声明可按需注入运行时(见下文)。 - 云文件系统挂载:通过集成配置,而非通过清单配置(参见
references/integrations.md)。 - 按组织配置 OAuth:每个组织通过
eve integrations configure注册自己的 OAuth 应用凭据(参见eve-auth-and-secrets)。
示例:
x-eve:
agents:
version: 1
config_path: agents/agents.yaml
teams_path: agents/teams.yaml
chat:
config_path: agents/chat.yaml
install_agents: [claude-code, codex]
packs:
- source: ./skillpacks/my-pack
应用 CLI 框架
建议所有带 API 的应用都采用。 将服务 API 封装为 CLI,并在此处注册。Agent 非常偏好 CLI 命令,而非直接调用 REST — CLI 会透明地处理身份验证、URL 构造和错误格式化。这是 Eve 推荐的方式:编码 Agent 应在代码库中构建 CLI 并在清单中注册,而不是让 Agent 直接调用 API。
平台会从清单中自动发现带有 x-eve.cli 或 x-eve.api_spec 的服务,并将其提供给项目中所有 Agent 作业使用,通过 $PATH 调用 — 无需显式设置 with_apis。只需在此处声明 CLI,所有 Agent 即可使用。
services:
api:
x-eve:
api_spec:
type: openapi
cli:
name: myapp # Binary name (goes on $PATH)
bin: cli/bin/myapp # Path relative to repo root (pre-bundled)
对于已编译的 CLI,请使用基于镜像的分发方式:
services:
api:
x-eve:
cli:
name: myapp
image: ghcr.io/org/myapp-cli:latest # Pre-built image
工作原理
- 清单同步会将 CLI 元数据与
api_spec一同存储。 - 作业工作区设置(克隆后)会运行
chmod +x,并将二进制文件符号链接到/usr/local/bin/。 - 对于基于镜像的 CLI,初始化容器会从镜像中复制二进制文件。
- CLI 会读取
EVE_APP_API_URL_{SERVICE}和EVE_JOB_TOKEN(这两者已注入),无需手动配置身份验证或 URL。
CLI 命名规则
- 使用小写字母、数字和连字符:
[a-z][a-z0-9-]* - 每个项目中的名称必须唯一
- 该名称会成为 Agent 调用的命令(例如
eden projects list)
Worker 工具链声明
Agent 声明所需的运行时工具链。平台会将它们作为初始化容器注入,无需使用臃肿的 Worker 镜像。
# In agents.yaml
agents:
data-analyst:
name: Data Analyst
skill: analyze-data
harness_profile: claude-sonnet
toolchains: [python] # Needs python + uv
doc-processor:
name: Document Processor
skill: process-documents
harness_profile: claude-sonnet
toolchains: [media] # Needs ffmpeg + whisper
可用工具链:python、media、rust、java、kotlin。
工作流可以覆盖 Agent 的默认设置:
workflows:
process-document:
steps:
- name: process
agent: doc-processor
toolchains: [media, python] # Override: needs both
工具链会挂载到 /opt/eve/toolchains/{name}/,其二进制文件位于 $PATH 中。默认 Worker 镜像为 base(约 800 MB);工具链只会添加每个作业所需的内容。
Cloud FS 挂载
可以通过云 FS 集成将 Google Drive 文件夹挂载到组织文件系统中。配置通过集成系统完成,而非通过清单。
# Org admin registers Google Drive OAuth app credentials (BYOA)
eve integrations configure google-drive \
--client-id "xxx.apps.googleusercontent.com" \
--client-secret "GOCSPX-xxx"
# Connect and mount a Drive folder
eve integrations connect google-drive
eve cloud-fs mount --org org_xxx \
--provider google-drive \
--folder-id <drive-folder-id> \
--label "Shared Drive"
开发者可以使用 eve cloud-fs ls 浏览已挂载的内容,并使用 eve cloud-fs search 搜索。挂载会存储提供商文件夹 ID,以及可选的、人类可读的根文件夹路径提示;没有单独的 CLI --mount-path 设置。
应用对象存储
在清单中声明应用级对象存储桶。每个桶会在部署期间按环境进行配置,在 eve env diagnose 中跟踪,并通过环境变量注入凭据。
services:
api:
x-eve:
object_store:
buckets:
- name: uploads
visibility: private
- name: avatars
visibility: public
cors:
origins: ["*"]
methods: [GET, PUT, HEAD]
max_age_seconds: 3600
自动注入的存储环境变量
配置对象存储桶后,这些环境变量会注入服务容器:
| 变量 | 描述 |
|---|---|
STORAGE_ENDPOINT | 兼容 S3 的端点 URL |
STORAGE_REGION | 存储区域 |
STORAGE_ACCESS_KEY_ID | 面向应用的访问密钥 |
STORAGE_SECRET_ACCESS_KEY | 面向应用的密钥 |
STORAGE_BUCKET_<NAME> | 每个逻辑桶对应的物理桶名称 |
STORAGE_FORCE_PATH_STYLE | MinIO 本地开发时为 true,AWS S3 中则省略 |
在 AWS staging 环境中,应用目前共用一个作用域限定为
demo-eve-app-* 的应用桶 IAM 主体。它无法访问平台内部桶或组织文件系统
桶,但应用桶之间并未相互隔离。后续生产环境将采用按应用划分的 IRSA。
设计规则
- 每种用途使用一个桶。 将
uploads、avatars和exports分开。 - 谨慎设置可见性。 只有用于提供公共资源的桶才应设置为
visibility: public。 - 浏览器上传时使用 CORS。 前端通过预签名 URL 直接上传时,设置
cors.origins和cors.methods。 - 桶名称在同一服务中必须唯一。 平台会根据项目、环境和逻辑名称生成物理桶名称。
如需了解存储层的详细文档,请参阅 eve-read-eve-docs 技能:references/object-store-filesystem.md。