Configuration

Shipyard reads one YAML file at startup — .shipyard.yaml in the working directory, or the path given with -config. Restart Shipyard after editing it by hand; projects added in the console are written to the file and take effect at once.

-config also accepts an HTTPS URL. Shipyard downloads the file at startup and treats it as read-only: the console cannot add projects to it. If the server needs a token, put it in SHIPYARD_CONFIG_TOKEN; it is sent as a bearer token.

SHIPYARD_CONFIG_TOKEN=… shipyard -config https://config.example.com/shipyard.yaml

Unknown keys, duplicate keys, a second YAML document and files over 1 MiB are rejected at startup. Errors name the offending line.

Minimal file

listen: 127.0.0.1:8080
projects:
  - id: my-app
    repository: you/my-app
    enabled: true
    issue_label: agent-ready
    release_interval: 48h
    content:
      interval: 168h
      publish_mode: pull_request

Everything else has a default.

Server and access

Key Default Meaning
listen — Address and port, e.g. 127.0.0.1:8080.
runtime.api_token_env — Name of the environment variable holding the API token.
runtime.embedded_worker false Run the queue worker inside the server process.

Without a token the console is read-only, and Shipyard only starts on a loopback address. With a token:

  • queuing, cancelling and retrying runs require it;
  • reading runs, logs, pipelines and /metrics requires it too.

If api_token_env names a variable that is not set, Shipyard refuses to start.

Projects

projects:
  - id: my-app
    repository: you/my-app
    enabled: true
    issue_label: agent-ready
    auto_merge: false
    release_interval: 48h
    models:
      verification: code
    content:
      enabled: true
      interval: 168h
      min_score: 70
      target: blog
      topics: [Go, static sites]
      publish_mode: pull_request
Key Meaning
id Unique ID: letters, digits, ., _, -.
repository owner/name.
enabled Only enabled projects accept runs.
issue_label Label that marks issues ready for automated work.
auto_merge Must be false: every change goes through review.
release_interval Release cadence as a duration, e.g. 48h.
models Per-project override of the AI role routing below.
content.interval How often content is reviewed, e.g. 168h.
content.min_score Score from 0 to 100 a topic needs before an article is drafted.
content.publish_mode pull_request: articles are proposed as pull requests.
runs_on Labels such as arch=arm64; runs go to a ship that carries all of them. See Ships.

AI providers and models

ai:
  providers:
    primary:
      type: openai-compatible
      base_url: https://api.openai.com/v1
      api_key_env: OPENAI_API_KEY
      timeout: 120s
    local:
      type: openai-compatible
      base_url: http://127.0.0.1:11434/v1
  models:
    code:
      provider: primary
      model: your-coding-model-id
      max_output_tokens: 8192
    researcher:
      provider: local
      model: your-local-model-id
  tasks:
    coding: code
    research: researcher
    writing: code
    verification: code
    release_notes: code
  • Providers — type: openai-compatible works with OpenAI and with local servers that speak the same API (Ollama, vLLM, LM Studio). base_url defaults to OpenAI; it must be HTTPS, or HTTP on loopback. timeout defaults to 120s.
  • Credentials — set exactly one of api_key_env (environment variable), api_key_file (file such as /run/secrets/openai_key, up to 64 KiB) or api_key (inline; keep that file private). Local servers need none.
  • Models — an alias names a provider and the provider's model ID. max_output_tokens defaults to 4096.
  • Roles — tasks maps the roles coding, research, writing, verification and release_notes to model aliases. A project's models overrides them. A role without a model fails the run instead of silently using another one.

Keys are read when a run needs them, so the server starts without AI credentials.

Storage, logs and retention

Key Default Meaning
storage.path ./data/shipyard.db SQLite database: queue, history, audit.
logging.directory ./data/logs One JSONL log per run attempt.
logging.max_run_size_mb 50 Log size cap per run.
retention.logs_days 30 Delete run logs after this many days.
retention.completed_runs_days 90 Delete finished runs after this many days.
retention.audit_days 365 Delete audit entries and alert records after this many days.
retention.max_disk_size_mb 2048 When the log directory reaches this size, new runs are refused until retention frees space.

Keep both paths on a local disk. logs_days cannot exceed completed_runs_days. Details in Monitoring and retention.

Monitoring and alerts

Key Default Meaning
observability.metrics false Serve Prometheus metrics on /metrics.
observability.otel_endpoint — OTLP/HTTP collector for traces, e.g. http://127.0.0.1:4318.
prometheus.<name>.url — Prometheus server for prometheus pipeline steps.
prometheus.<name>.query — The PromQL instant query the step runs.
prometheus.<name>.token_env — Optional bearer token variable for that server.
alerts.token_env — Token variable Alertmanager must send.
alerts.project_label shipyard_project Alert label that names the project.
alerts.enqueue_diagnostics false Queue a diagnostic run for each firing alert.

Fleet

Key Default Meaning
fleet.listen — Address of the ship endpoint, e.g. 0.0.0.0:8443. Unset means no ships.
fleet.address — host:port ships dial; used in join commands.
fleet.hosts — DNS names and IPs written into the endpoint's certificate.
fleet.directory <storage dir>/fleet Where the fleet certificate authority is kept. Back it up: losing it means re-joining every ship.

The fleet requires runtime.api_token_env. Setup is described in Ships and docks.

Pipelines

pipelines:
  project-check:
    steps:
      - id: config
        type: diagnostic
        timeout: 30s

A pipeline has 1 to 20 steps with unique IDs. Step types and examples are in Pipelines.

Secrets in logs

Configured API keys and tokens are masked in run logs and errors, together with text that looks like token=…, password: … or an Authorization header. Do not put other secrets into run input.