Add a lerd service preset
Services are submitted to the lerd-env/services repo
(https://github.com/lerd-env/services) as services/<name>.yaml,
one file per service. They are data, not Go. lerd ships only the default stack
(mysql, postgres, redis, meilisearch, rustfs, mailpit); everything else is a preset
there and reaches every install within ~24h with no binary release.
The lerd-services/ directory in the lerd repo is a local checkout you can edit
and test against, but the pull request goes to lerd-env/services.
Procedure
Find the closest existing preset and copy it. The existing YAML is the
schema of record — do not invent fields. For a Redis-alike copy valkey.yaml;
for a database copy mariadb.yaml or mongo.yaml; for an admin dashboard
copy phpmyadmin.yaml / pgadmin.yaml.
Fill the core fields (see valkey.yaml for the minimal shape):
name, description, family (family groups alternates + admin UIs)
image (pin a specific tag), ports ("host:container")
data_dir for the persistent volume
env_vars — the host/port/credentials injected into a linked site's .env
connection_url where applicable
Avoid host-port collisions. If the service shares a protocol/port with a
default (e.g. Valkey vs Redis on 6379), publish it on a shifted host port so
both can coexist, and note why in a short comment. lerd also auto-shifts
collisions, but pick a sane default.
Declare dependencies and mounted config if the preset needs them (an admin
dashboard depends on its database family; some presets mount a generated
config file for auto-login). Copy the pattern from the matching existing preset.
For a database engine, also add an introspect.list_databases command so it
appears in the web UI's Databases tab. It runs via sh -c inside the container
and must print one name<TAB>size_bytes row per user database, filtering the
engine's own system databases. Copy the block from mariadb.yaml (MySQL family),
postgres-pgvector.yaml (Postgres), or mongo.yaml (Mongo). lerd passes the
lerd admin password via the exec env, so no inline credentials are needed for
MySQL/Postgres.
Give it its mark and its colour. category places it in a discovery
section and color is its brand tint, a plain hex literal (#00758f) and
nothing else — a colour function or CSS variable is dropped. For the mark,
either name a built-in glyph with icon: or ship the service's own as
services/<name>.svg beside the YAML. That file is monochrome: a single
silhouette of filled paths with no fill, stroke, style or class of its
own, in a bare <svg viewBox="…">, since lerd strips everything but the
geometry on the way in and paints it in the declared colour. Not a full-colour
brand mark; it renders beside the built-in glyphs and has to flip themes.
Update the store README table in the lerd-env/services README.md so the
new service is listed.
Validate end-to-end with a real lerd install:
lerd service search <name>
lerd service preset <name>
Confirm the container starts, the port is reachable, and a linked site's .env
gets the expected vars.
Rules
- The PR goes to lerd-env/services, not the lerd binary repo.
- One service per file. No Go changes. No new mergers.
- Pin image tags; never rely on
latest.
- Keep
description one line; it shows in lerd service search.
1---2name: lerd-add-service3description: Add or edit a lerd service preset (database, cache, search engine, admin dashboard) as YAML in the lerd-services store. Use whenever the task is to add a new service, a new version of a service, or wire a service into projects — never add services in Go.4---56# Add a lerd service preset78Services are submitted to the **lerd-env/services** repo9(https://github.com/lerd-env/services) as `services/<name>.yaml`,10one file per service. They are **data, not Go**. lerd ships only the default stack11(mysql, postgres, redis, meilisearch, rustfs, mailpit); everything else is a preset12there and reaches every install within ~24h with no binary release.1314The `lerd-services/` directory in the lerd repo is a local checkout you can edit15and test against, but the pull request goes to **lerd-env/services**.1617## Procedure18191. **Find the closest existing preset and copy it.** The existing YAML is the20 schema of record — do not invent fields. For a Redis-alike copy `valkey.yaml`;21 for a database copy `mariadb.yaml` or `mongo.yaml`; for an admin dashboard22 copy `phpmyadmin.yaml` / `pgadmin.yaml`.23242. **Fill the core fields** (see `valkey.yaml` for the minimal shape):25 - `name`, `description`, `family` (family groups alternates + admin UIs)26 - `image` (pin a specific tag), `ports` (`"host:container"`)27 - `data_dir` for the persistent volume28 - `env_vars` — the host/port/credentials injected into a linked site's `.env`29 - `connection_url` where applicable30313. **Avoid host-port collisions.** If the service shares a protocol/port with a32 default (e.g. Valkey vs Redis on 6379), publish it on a shifted host port so33 both can coexist, and note why in a short comment. lerd also auto-shifts34 collisions, but pick a sane default.35364. **Declare dependencies and mounted config** if the preset needs them (an admin37 dashboard depends on its database family; some presets mount a generated38 config file for auto-login). Copy the pattern from the matching existing preset.3940 For a **database engine**, also add an `introspect.list_databases` command so it41 appears in the web UI's Databases tab. It runs via `sh -c` inside the container42 and must print one `name<TAB>size_bytes` row per user database, filtering the43 engine's own system databases. Copy the block from `mariadb.yaml` (MySQL family),44 `postgres-pgvector.yaml` (Postgres), or `mongo.yaml` (Mongo). lerd passes the45 `lerd` admin password via the exec env, so no inline credentials are needed for46 MySQL/Postgres.47485. **Give it its mark and its colour.** `category` places it in a discovery49 section and `color` is its brand tint, a plain hex literal (`#00758f`) and50 nothing else — a colour function or CSS variable is dropped. For the mark,51 either name a built-in glyph with `icon:` or ship the service's own as52 `services/<name>.svg` beside the YAML. That file is **monochrome**: a single53 silhouette of filled paths with no `fill`, `stroke`, `style` or `class` of its54 own, in a bare `<svg viewBox="…">`, since lerd strips everything but the55 geometry on the way in and paints it in the declared colour. Not a full-colour56 brand mark; it renders beside the built-in glyphs and has to flip themes.57586. **Update the store README table** in the lerd-env/services `README.md` so the59 new service is listed.60617. **Validate end-to-end** with a real lerd install:62 ```bash63 lerd service search <name>64 lerd service preset <name>65 ```66 Confirm the container starts, the port is reachable, and a linked site's `.env`67 gets the expected vars.6869## Rules7071- The PR goes to **lerd-env/services**, not the lerd binary repo.72- One service per file. No Go changes. No new mergers.73- Pin image tags; never rely on `latest`.74- Keep `description` one line; it shows in `lerd service search`.