Label reference¶
Every label your adapter image carries. These are the only metadata the platform has about your adapter — the installer, the compose generator, the nginx route generator and the public catalog page all read them straight out of the image config blob.
Labels are strings. Booleans are the literal text
"true"/"false"; lists are comma-separated in a single label. Anything else is treated as absent.
Identity — OCI standard¶
| Label | Required | Read by | Notes |
|---|---|---|---|
org.opencontainers.image.title |
yes | installer catalog, public catalog card | Human display name, e.g. Example Vendor CCTV. Falls back to the image name if missing. |
org.opencontainers.image.description |
yes | installer catalog, public catalog card | One or two sentences: what devices, over what protocol, with what capabilities. This is the card body — write it for an integrator, not a developer. |
org.opencontainers.image.vendor |
yes | catalog | Who publishes the image (your company). |
org.opencontainers.image.source |
recommended | humans | URL of the source repository or the registry page. |
org.opencontainers.image.licenses |
recommended | humans | SPDX id or Proprietary. |
Classification¶
| Label | Required | Values | Effect |
|---|---|---|---|
org.protequ.adapter |
yes | "true" |
The switch. Without it the image is classified as unknown, never appears in the installer catalog, and is skipped by the public catalog page. |
org.protequ.id |
yes, when org.protequ.adapter="true" |
a stable per-image GUID | Identity the pqshop catalogue sync joins on. An image without one is skipped by the sync entirely (no product is created or updated for it). Once set, never change it — the sync uses it to recognize "this is still the same adapter" across renames. AdapterLabelDriftTests enforces that every adapter image declares one and that no two images share the same value. |
org.protequ.category |
yes | see below | Groups the adapter in the catalog and picks its icon. May be a comma-separated list (e.g. "intrusion,access") for an adapter sold under more than one category — the installer catalog groups/filters by the first (primary) value; the pqshop catalogue sync creates a product per listed category. Missing → other. |
org.protequ.device_vendor |
yes | free text | Who makes the hardware, e.g. Example Vendor Ltd.. Distinct from image.vendor. |
org.protequ.capabilities |
optional | comma-separated | Capability chips on the catalog card. |
org.protequ.default_enabled |
optional | "true" / "false" |
Whether the adapter's checkbox is pre-ticked in the installer. Default false. Only set true for something every install should have. |
org.protequ.demo |
optional | "true" |
Marks the card with a Demo badge — simulators and sample stubs. |
org.protequ.in_development |
optional | "true" |
Marks the card with an In development badge — not yet a production delivery. |
org.protequ.docs |
recommended | in-image path | Points at the documentation bundle copied into the image, e.g. "/pq/adapter-docs/Pq.Adapter.Acme". Protequ extracts the bundle from there; the path's last segment names the adapter. See Writing and delivering adapter documentation. |
Category¶
| Value | Catalog group |
|---|---|
cctv |
Video Surveillance — NVRs and IP cameras |
intrusion |
Intrusion Detection — alarm panels, partitions, zones |
access |
Access Control — controllers, readers, biometric terminals |
fire |
Fire Detection — fire alarm control panels (EPS), detectors, sounders |
module |
Modules & Services — operational modules and platform services |
security |
Security — general security integrations and software adapters |
Any other value still works, but it lands in an unnamed group at the end of the catalog with a generic icon. Prefer one of the known values above.
Capability chips¶
These values render with a friendly label and an icon; anything else renders as raw text.
timeSync · rtsp · ptz · firmware · partitions · outputs · access · biometric ·
osdp · analytics
Deployment labels¶
These change the compose service the installer generates for your adapter. Use them instead of
asking an operator to hand-edit docker-compose.yml — a hand edit is lost on the next deploy.
| Label | Format | Generated into |
|---|---|---|
org.protequ.ports |
"host:container", comma-separated |
ports: entries |
org.protequ.volumes |
"host:container[:ro]", comma-separated |
volumes: entries |
org.protequ.env.<NAME> |
one label per variable | an environment: entry NAME: "<value>" |
org.protequ.depends |
service names, comma-separated | extra depends_on: entries, condition: service_started |
LABEL org.protequ.ports="9000:9000" \
org.protequ.volumes="./acme-config:/app/config:ro" \
org.protequ.env.ACME__PollSeconds="30" \
org.protequ.depends="go2rtc"
Notes:
depends_on: server (condition: service_healthy)is always added — you do not declare it.dependsentries must name services that exist in the customer's stack. A name that does not exist breaksdocker compose upfor the whole deployment.- Prefer defaults baked into
appsettings.jsonoverorg.protequ.env.*. Use the label only for values that genuinely have to be visible and overridable in compose. - Every published port is a hole in the customer's perimeter. Declare one only if the device must connect inbound to your adapter.
UI labels¶
Only for adapters that serve their own web surface. See Adapters that ship a UI.
| Label | Required | Default | Effect |
|---|---|---|---|
org.protequ.ui |
for UI adapters | — | "true" makes the installer generate an nginx front-door route. |
org.protequ.ui.slug |
for UI adapters | image name minus pq |
URL segment: the UI is served at /adapters/<slug>/. URL-safe characters only. |
org.protequ.ui.port |
optional | 8443 |
Internal HTTPS port nginx proxies to. |
Copy-paste template¶
LABEL org.opencontainers.image.title="<Display Name>" \
org.opencontainers.image.description="<What it integrates, over what protocol, what it can do.>" \
org.opencontainers.image.vendor="<Your company>" \
org.opencontainers.image.source="<repo or registry URL>" \
org.opencontainers.image.licenses="Proprietary" \
org.protequ.adapter="true" \
org.protequ.id="<stable per-image GUID, generate once, never change>" \
org.protequ.category="access" \
org.protequ.device_vendor="<Hardware manufacturer>" \
org.protequ.capabilities="access,outputs" \
org.protequ.default_enabled="false"
How the labels are read¶
Worth knowing when a label change "doesn't take":
- The catalog resolves the
latesttag. If the repository has nolatest(a prerelease-only adapter), it falls back to the newest version tag and flags the entry as a prerelease. - From a multi-arch index it picks the
linux/amd64child manifest, skipping Buildx attestation entries. - It downloads that manifest's config blob and reads
.config.Labels.
So: labels live in the image config, not in the tag or the manifest. Changing a label requires rebuilding and pushing the image — retagging an existing digest changes nothing.