# Lerd Add Service

> 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.

- Skill: `lerd-env/lerd-add-service` (Agent Skill)
- Install (CLI): `npx skillmds@latest add lerd-env/lerd-add-service`
- Raw SKILL.md: https://api.skillmd.com/api/skills/lerd-env/lerd-add-service/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Productivity
- Author: lerd-env (https://skillmd.com/u/lerd-env)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/lerd-env/lerd-add-service

---


# 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

1. **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`.

2. **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

3. **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.

4. **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.

5. **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.

6. **Update the store README table** in the lerd-env/services `README.md` so the
   new service is listed.

7. **Validate end-to-end** with a real lerd install:
   ```bash
   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`.

