Catalog and recipes¶
The catalog lives in api/internal/catalog/templates.json, embedded in the binary. Each entry is a template: the
defaults Deployer uses to write the compose file, the nginx site and the access suggestion for one app, plus an
optional single sign-on recipe.
Template format¶
{
"id": "linkding",
"name": "linkding",
"category": "Productivity",
"icon": "bookmark",
"website": "https://github.com/sissbruecker/linkding",
"description": "Bookmark manager.",
"image": "sissbruecker/linkding",
"tag": "latest",
"port": 9090,
"auth": "app",
"secrets": { "ADMIN_PASSWORD": "password" },
"env": [
{ "key": "LD_SUPERUSER_NAME", "value": "admin" },
{ "key": "LD_SUPERUSER_PASSWORD", "value": "{{SECRET:ADMIN_PASSWORD}}", "secret": true }
],
"volumes": [ { "name": "data", "target": "/etc/linkding/data" } ],
"notes": "Log in as admin with the generated password (shown in the Secrets panel).",
"aliases": [],
"sso": { "method": "header", "env": [ … ], "remove": [ … ], "notes": "…" }
}
| Field | Meaning |
|---|---|
id, name, category, icon, website, description, tags |
catalog display (icons are lucide names) |
image, tag |
main image; aliases lists other image names of the same app (mirrors, forks) |
port |
container port nginx proxies to |
env |
variables; secret: true puts them in secrets/app.env |
secrets |
generated values, name → generator (password, hex16, hex32), used as {{SECRET:NAME}} |
volumes |
{name, target, readOnly, uid, gid} becomes ./data/<name>:<target>; {hostPath, target} mounts a host path (flagged as risky outside the stack) |
services |
extra services (databases, caches) with their own image, tag, env, volumes, health check |
command, user, health, memLimit, noNewPrivileges |
main service options |
websocket, maxBodyMB, readTimeout, buffering |
nginx defaults |
auth |
suggested access: authentik, app (has its own login) or none (public) |
notes |
shown in the wizard and the stack README |
sso |
single sign-on recipe (below) |
Placeholders in templates: {{URL}}, {{FQDN}}, {{NAME}}, {{TZ}}, {{SECRET:NAME}}.
Sign-in recipe format¶
"sso": {
"method": "oidc",
"env": [
{ "key": "OIDC_AUTH_ENABLED", "value": "true" },
{ "key": "OIDC_CONFIGURATION_URL", "value": "{{OIDC_CONFIG_URL}}" },
{ "key": "OIDC_CLIENT_ID", "value": "{{OIDC_CLIENT_ID}}" },
{ "key": "OIDC_CLIENT_SECRET", "value": "{{OIDC_CLIENT_SECRET}}", "secret": true },
{ "key": "OIDC_GROUPS_CLAIM", "value": "deployer_groups" },
{ "key": "OIDC_ADMIN_GROUP", "value": "admin" }
],
"remove": [],
"adminClaim": true,
"notes": "Mealie signs you in with Authentik; your account is the admin."
}
| Field | Meaning |
|---|---|
method |
oidc, saml, header, none, basic or autologin |
env / remove |
variables added to / removed from the main service while the recipe is on; removed values come back when it is turned off |
steps |
steps to do once in the app (placeholders allowed), shown on the app page |
redirect |
the app's OIDC callback, for display |
notes |
shown under the choice |
adminClaim |
add the deployer_groups claim (["admin"] for the admin account) to the app's OIDC client |
init |
[{service, user, args, done}]: commands run once in the container after it is healthy |
ownDoor |
no forward auth in front; the app's OIDC sign-in is the door |
login |
{adapter: "form" \| "uptime-kuma", path, next} for auto-login |
Sign-in placeholders: {{URL}} {{FQDN}} {{OIDC_ISSUER}} {{OIDC_CONFIG_URL}} {{OIDC_LOGOUT_URL}}
{{OIDC_CLIENT_ID}} {{OIDC_CLIENT_SECRET}} {{GATEWAY}} {{AUTHENTIK_URL}} {{ADMIN_USER}} {{ADMIN_EMAIL}}.
Applying a recipe is idempotent and exactly reversible: Deployer records what it added and what it replaced
(SSOState) and restores it when the account method changes or Authentik is turned off. A test applies and
removes every recipe of the catalog against its template.
Adding an app¶
- Add the template to
templates.json(keep categories and icons consistent). go test ./internal/catalog/(every template must build, every recipe must apply and undo cleanly).- Deploy it in fake mode through the wizard; check the compose file and the lint result.
- If it supports single sign-on, write the recipe and verify it with a real login in the lab (Development → The real-login lab).
- Add the result to the table in Single sign-on.
Knowledge used by detection¶
| File | Content |
|---|---|
api/internal/ssodetect/known.json |
popular apps outside the catalog: names (image names, or owner/name for generic ones), method, how, link, paid |
api/internal/ssodetect/authentik_guides.json |
generated from Authentik's integration guides: slug, name, provider types, guide URL |
Contributions to known.json are the easiest way to help: one entry per app, with a link to the documentation
that proves it.