skills/incept5/eve-skillpacks/eve-manifest-authoring

eve-manifest-authoring

SKILL.md

Eve Manifest Authoring

Keep the manifest as the single source of truth for build and deploy behavior.

Minimal skeleton (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

Registry Image Labels

Some registries require package metadata for permission and ownership inheritance. Add these labels to your Dockerfiles when supported by your registry:

LABEL org.opencontainers.image.source="https://github.com/YOUR_ORG/YOUR_REPO"
LABEL org.opencontainers.image.description="Service description"

Why this matters: Metadata helps preserve repository ownership and improves traceability. The Eve builder injects these labels automatically, but including them in your Dockerfile is still recommended.

For multi-stage Dockerfiles, add the labels to the final stage (the production image).

Registry Modes

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 }

For BYO/private registries, provide:

registry:
  host: public.ecr.aws/w7c4v0w3
  namespace: myorg
  auth:
    username_secret: REGISTRY_USERNAME
    token_secret: REGISTRY_PASSWORD

Managed Databases

Declare platform-provisioned databases with x-eve.role: managed_db:

services:
  db:
    x-eve:
      role: managed_db
      managed:
        class: db.p1
        engine: postgres
        engine_version: "16"

Not deployed to K8s — provisioned by the orchestrator on first deploy. Reference managed values elsewhere: ${managed.db.url}.

Eve-Migrate for Database Migrations

Use the platform's migration runner instead of Flyway, TypeORM, or Knex. It uses plain SQL files with timestamp prefixes, tracked in 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

Migration files: db/migrations/20260312000000_initial_schema.sql. The x-eve.files directive mounts them into the container at /migrations.

In the pipeline, the migrate step must run after deploy (managed DB needs provisioning):

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 }

For local dev, use the same image via Docker Compose for parity:

# docker-compose.yml
services:
  migrate:
    image: ghcr.io/incept5/eve-migrate:latest
    environment:
      DATABASE_URL: postgres://app:app@db:5432/myapp
    volumes:
      - ./db/migrations:/migrations:ro
    depends_on:
      db: { condition: service_healthy }

Legacy manifests

If the repo still uses components: from older manifests, migrate to services: and add schema: eve/compose/v2. Keep ports and env keys the same.

Services

  • Provide image and optionally build (context and dockerfile).
  • Use ports, environment, healthcheck, depends_on as needed.
  • Use x-eve.external: true and x-eve.connection_url for externally hosted services.
  • Use x-eve.role: job for one-off services (migrations, seeds). For database migrations, prefer Eve's eve-migrate image (see below).

Build configuration

Services with Docker images should define their build configuration:

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]

Note: Every deploy pipeline should include a build step before release. The build step creates tracked BuildSpec/BuildRun records and produces image digests that releases use for deterministic deployments.

Local dev alignment

  • Keep service names and ports aligned with Docker Compose.
  • Prefer ${secret.KEY} and use .eve/dev-secrets.yaml for local values.

Environments, pipelines, workflows

  • Link each environment to a pipeline via environments.<env>.pipeline.
  • When pipeline is set, eve env deploy <env> triggers that pipeline instead of direct deploy.
  • Use environments.<env>.pipeline_inputs to provide default inputs for pipeline runs.
  • Override inputs at runtime with eve env deploy <env> --ref <sha> --inputs '{"key":"value"}' --repo-dir ./my-app.
  • Use --direct flag to bypass pipeline and do direct deploy: eve env deploy <env> --ref <sha> --direct --repo-dir ./my-app.
  • Pipeline steps can be action, script, or agent.
  • Use action.type: create-pr for PR automation when configured.
  • Workflows live under workflows and are invoked via CLI; db_access is honored.

Platform-Injected Environment Variables

Eve automatically injects these into all deployed service containers:

Variable Description
EVE_API_URL Internal cluster URL for server-to-server calls
EVE_PUBLIC_API_URL Public ingress URL for browser-facing apps
EVE_PROJECT_ID The project ID
EVE_ORG_ID The organization ID
EVE_ENV_NAME The environment name

Use EVE_API_URL for backend calls from your container. Use EVE_PUBLIC_API_URL for browser/client-side code. Services can override these in their environment section.

Interpolation and secrets

  • Env interpolation: ${ENV_NAME}, ${PROJECT_ID}, ${ORG_ID}, ${ORG_SLUG}, ${COMPONENT_NAME}.
  • Secret interpolation: ${secret.KEY} pulls from Eve secrets or .eve/dev-secrets.yaml.
  • Managed DB interpolation: ${managed.<service>.<field>} resolves at deploy time.
  • Use .eve/dev-secrets.yaml for local overrides; set real secrets via the API for production.

Eve extensions

  • Top-level defaults via x-eve.defaults (env, harness, harness_profile, harness_options, hints, git, workspace).
  • Top-level agent policy via x-eve.agents (profiles, councils, availability rules).
  • Agent packs via x-eve.packs with optional x-eve.install_agents defaults.
  • Agent config paths via x-eve.agents.config_path and x-eve.agents.teams_path.
  • Chat routing config via x-eve.chat.config_path.
  • Service extensions under x-eve (ingress, role, api specs, worker pools).
  • API specs: x-eve.api_spec or x-eve.api_specs (spec URL relative to service by default).

Example:

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

App Object Store

Status: Schema exists, provisioning logic pending. The database schema (storage_buckets table) and bucket naming convention are implemented. Automatic provisioning from the manifest is not yet wired.

Declare app-scoped object storage buckets in the manifest. Each bucket is provisioned per environment with credentials injected as environment variables.

services:
  api:
    x-eve:
      object_store:
        buckets:
          - name: uploads
            visibility: private
          - name: avatars
            visibility: public
            cors:
              allowed_origins: ["*"]

Auto-Injected Storage Environment Variables

When object store buckets are provisioned, these env vars are injected into the service container:

Variable Description
STORAGE_ENDPOINT S3-compatible endpoint URL
STORAGE_ACCESS_KEY Access key for the bucket
STORAGE_SECRET_KEY Secret key for the bucket
STORAGE_BUCKET Physical bucket name
STORAGE_FORCE_PATH_STYLE true for MinIO (local dev), false for cloud

Design Rules

  • One bucket per concern. Separate uploads from avatars from exports.
  • Set visibility intentionally. Only buckets serving public assets should be visibility: public.
  • Use CORS for browser uploads. Set cors.allowed_origins when the frontend uploads directly via presigned URLs.
  • Bucket names must be unique within a service. The platform derives the physical bucket name from the project, environment, and logical name.

For detailed storage layer documentation, see the eve-read-eve-docs skill: references/object-store-filesystem.md.

Weekly Installs
129
First Seen
Feb 8, 2026
Installed on
gemini-cli129
codex129
claude-code127
pi35
opencode26
github-copilot26