Skip to content

[Bug]: Docker images ship without data/plugin-previews/manifest.json, silently disabling every baked plugin preview #7018

Description

@jiulongche

What happened?

On a self-hosted Docker deployment, every bundled plugin card in the home gallery renders as a live, scaled iframe. The baked poster + hover-clip path never activates, even though the shipped manifest has bakes for 176 of them.

The cause is that deploy/Dockerfile never copies data/ into the image, so data/plugin-previews/manifest.json — the file CI commits precisely so that deployments can find the bakes — is absent at runtime.

$ docker exec <daemon> ls /app/data/plugin-previews
ls: /app/data/plugin-previews: No such file or directory

The chain from there is short and entirely silent:

  • resolvePluginPreviewsDir() defaults to <projectRoot>/data/plugin-previews;
  • loadManifest() finds no manifest.json and returns {};
  • applyBakedPreviews() early-returns the records untouched, so no record gets an od.bakedPreview;
  • inferPluginPreview(record, { preferBaked: true }) therefore always falls through to the live-HTML branch.

Measured on 0.19.2 with 461 registered plugins: manifest.json in the repo has 176 entries, and 0 records carried od.bakedPreview. After making the directory available, the same daemon reports 176 — deck 79, prototype 79, video 10, scenario 4, image 1, audio 1, template 2.

deploy/Dockerfile copies skills, design-systems, craft, prompt-templates, assets, and plugins/_official; data/ is the one content directory missing from that list, which reads more like an oversight than a decision.

Why this may not be visible upstream

The packaged desktop app gets the repository contents through a different path, so it finds the manifest and uses the bakes. Only Docker/self-hosted deployments are affected — and there the degradation is invisible: the gallery still renders, just via the fallback. Nothing is logged.

That last part looks worth fixing on its own. loadManifest() already carries this comment for the malformed case:

// A malformed/unreadable manifest would otherwise silently disable every baked preview with no trace; surface it so it's diagnosable.

…and warns accordingly. The absent case returns {} with no message, which is the same failure with no trace — exactly what that comment set out to prevent.

Steps to reproduce

  1. Build the image from deploy/Dockerfile (or run any published Docker/self-hosted deployment).
  2. Open the home gallery.
  3. Inspect any bundled deck or prototype card: it is an <iframe class="plugins-home__html-iframe">, never the baked MediaSurface poster + <video>.
  4. Confirm the cause: docker exec <daemon> ls /app/data/plugin-previews → no such directory.
  5. Optional cross-check via the API: every record's manifest.od.bakedPreview is undefined.

Expected behavior

A Docker/self-hosted deployment should find the checked-in data/plugin-previews/manifest.json and serve baked previews for the 176 plugins that have them, the same as the packaged app.

Suggested fix — data/ alongside the other content directories in both stages of deploy/Dockerfile:

COPY data ./data
...
COPY --from=build --chown=open-design:open-design /app/data ./data

Narrowing it to data/plugin-previews would work equally well if data/ holds anything that should stay out of the image.

Separately, and independent of the above: consider a one-line notice when the manifest is absent, so a deployment that silently loses all 176 bakes is diagnosable rather than merely slower.

Impact

  1. Cost. plugin-preview-bakes.ts opens by noting the live path "is GPU-expensive at scale", which is the reason bakes exist. Self-hosted deployments currently pay that for the entire gallery — 461 live iframes where 176 would have been a poster and a small clip.
  2. It routes every card onto a path that is otherwise rarely exercised. Filed separately as the deck thumbnails landing outside their card, which is only reachable this way — deck happens to be the best-baked category (79/80), so with bakes present those tiles never take the buggy branch.

Open Design version

0.19.2

Platform

Linux (Docker, self-hosted)

Additional context

Found while chasing blank thumbnails in the home rail on a self-hosted deployment. Happy to open a PR for the Dockerfile change, the absent-manifest notice, or both.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinggood first issueGood for newcomershelp wantedExtra attention is needed

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions