Demo mode
The live sample is exactly this — everything below describes what you are looking at there.
There is a published tag for it, so putting this on a public URL is one command:
docker run -p 8085:8080 -v shiny-demo:/data ghcr.io/shinyorg/shiny-docdb-myadmin:demo:demo is the ordinary image with ShinyDocDbMyAdmin__DemoMode already set — same build, one extra
layer, every other layer shared. The two are interchangeable with the flag: setting
ShinyDocDbMyAdmin__DemoMode=true on :latest behaves identically, and =false on :demo gives you the
ordinary tool back. Pin :demo-<version> alongside :<version> when you want it to hold still.
One flag, not a checklist
Section titled “One flag, not a checklist”On first start the app builds its own SQLite sample from data embedded in the image, publishes it as a
read-only connection, and closes what a public instance should not offer. There is no seeding sidecar to
keep in step with it, and no ReadOnly / DisableAi pair to remember — demo mode forces both.
That is deliberate. A playground assembled out of ReadOnly plus DisableAi plus a seeding sidecar plus
a read-only mount is a playground that is one forgotten setting away from being an open database client on
the public internet.
The sample is written once
Section titled “The sample is written once”If the database file is already there it is left completely alone — not compared, not topped up, not migrated. An image update never discards what someone is looking at, and nothing in the UI offers a rebuild, so a visitor cannot wipe the thing everyone else came to see. Deleting the file on the host is the only way to rebuild it.
What’s closed, what’s open
Section titled “What’s closed, what’s open”| Closed | Still open |
|---|---|
| Editing data — the sample is read-only | Browsing, searching, filtering |
| Adding, editing or removing connections | The query console, plans, index management |
| Importing data | Structure, statistics, full text |
| Importing or exporting settings | History, geometry, blobs, vectors |
| The AI assistant | Exporting data — JSON, NDJSON, envelope JSON, CSV |
| Rebuilding the sample |
Exporting data stays open on purpose. It is most of what someone is at a playground to try, it only reads, and the data is a published sample. Importing does not, because that writes.
It says so, loudly
Section titled “It says so, loudly”A bright band across the top of every page says the instance is a demo, and expands to list exactly what
is switched off — so a visitor knows the missing buttons are policy rather than breakage, and whoever
runs the instance can see at a glance that the flag actually took effect. It also carries the
docker run line for the unrestricted tool.
Closed below the UI
Section titled “Closed below the UI”Each closure is enforced under the surface, not just by hiding a control: saving a connection is refused in the profile store itself, importing is refused in the import service, and the AI services are not registered at all. A deep link to a closed page renders a refusal rather than a half-drawn form.


