Buildpack plugins

Plugins add framework support on the server. They do not run inside your repo.

Relay buildpack plugins are JSON definitions stored on the agent. They participate in framework detection before the built-in buildpacks, then render a Dockerfile template when they match.

Example install
relay plugin install ./plugins/astro-static.json \
  --url http://127.0.0.1:8080 \
  --token YOUR_TOKEN

relay plugin list --url http://127.0.0.1:8080 --token YOUR_TOKEN
Plugin model

A plugin is a detection rule set plus a Docker plan template.

This is deliberately smaller than a generic code plugin system. The agent needs enough information to decide whether the plugin matches a repo and how to build and run that repo if it does.

Detection happens on the agent

Relay inspects the uploaded repo snapshot on the server. Plugins are applied there, so every deploy for that agent sees the same framework support.

Priority decides matching order

Plugins are prepended ahead of built-ins. Higher priority wins, so a plugin can override the default behavior for a specific framework shape.

The output is still a build plan

A plugin does not bypass the rest of Relay. It still resolves to a build image, run image, service port, and rendered Dockerfile.

Installing plugins

The CLI uploads JSON. The server decides whether mutation is allowed.

A plugin install is an authenticated API write to the agent. In production, leave plugin mutation off unless you are actively curating framework support.

1

Turn on mutation intentionally

Set `RELAY_ENABLE_PLUGIN_MUTATIONS=true` only while administering plugins.

2

Install from a JSON file

Use `relay plugin install <file>` against the agent that should own the plugin.

3

List what is active

Use `relay plugin list` or `GET /api/plugins/buildpacks` to inspect the live set.

4

Turn mutation back off

Once the plugin is installed, the agent still loads it even after you disable further mutations.

Plugin API
GET    /api/plugins/buildpacks
POST   /api/plugins/buildpacks
DELETE /api/plugins/buildpacks/:name
Authoring plugins

Write the plugin around file signals and a concrete build/run plan.

A good plugin is narrow. Match on a specific framework shape, render a Dockerfile that is easy to reason about, and avoid shadowing unrelated repos with broad rules.

name

Unique plugin id used for storage and listing.

priority

Higher numbers match before lower ones.

detect

Files, directories, extensions, or package.json signals that identify the framework.

plan

Kind, images, service port, commands, and the Dockerfile template.

Plugin shape
{
  "name": "astro-static",
  "priority": 900,
  "detect": {
    "files_any": ["astro.config.mjs", "astro.config.ts"],
    "package_deps_any": ["astro"]
  },
  "plan": {
    "kind": "astro-static",
    "service_port": 80,
    "dockerfile_template": "FROM node:22 AS builder\n...\nFROM nginx:alpine\n..."
  }
}