Skip to content

Using Plugins

Doug edited this page Aug 8, 2026 · 5 revisions

Using Plugins

For operators running a self-hosted GDX instance. How to install, enable, and update third-party modules.

The model: install ≠ enable

  • Install makes a plugin available (its code is present on the box).
  • Enable turns an installed plugin on for the tenant.

You vet what you install — there's no central registry or signing. A plugin runs with backend access, confined to the plugin-host container (not the core app). Treat installing one like adding a dependency.

Installing

The Plugins admin page (owner-only) offers two in-app paths, plus a host-side option:

A) In-app — package name

Enter a pip package name + version (e.g. gdx-plugin-foo 0.1.0). The registration is recorded; the plugin-host pip-installs registered packages into the /plugins volume on its next restart and discovers them.

B) In-app — upload a plugin file

For private plugins that aren't on a package index: Upload plugin file takes a .whl or .tar.gz, stores it in the database, and the plugin-host installs it on restart. Uploaded artifacts are listed (with checksum) and can be removed; the page tells you if you type a filename into the package field by mistake.

Either way, click Restart plugin-host on the same page to apply pending installs/removals — the plugin-host is a separate container, so the core app keeps serving while it cycles. (Equivalent API: POST /api/admin/plugins, POST /api/admin/plugins/upload, POST /api/admin/plugins/restart; GET /api/admin/plugins lists the registry, DELETE /api/admin/plugins/<package> removes an entry.)

C) Host-side (bake into the image)

FROM ghcr.io/freeperro/gdx_dispatch-plugin-host:1.45.0
RUN pip install gdx-plugin-foo gdx-plugin-bar

(Plugins run in the plugin-host image, not the core app image.)

Permissions & consent

A plugin may declare elevated capabilities in its manifest (currently browser — a server-side headless browser the operator can drive, e.g. to log into a site that has no API). Declared permissions show up on the Plugins page with a Review & consent dialog explaining the risk; the capability stays off until an owner consents. Consent records exactly what was declared at the time — if a later plugin version declares more, it needs consent again. Details: ADR-014.

Enabling

Enabling is a per-tenant module grant (owner-only). An installed-but-not-enabled plugin returns 403 until granted. Until the Settings toggle ships, grant via the module-grants mechanism (a company_module_grants row keyed by the plugin's key).

Updating

Plugins are versioned pip packages — update by registering a newer version (in-app) or bumping the version in your Dockerfile (host-side), then restarting plugin-host. Core-app updates are separate; see the project README's Updating section.

Operational notes

  • The /plugins volume must be writable by the plugin-host runtime user, or the in-app pip install fails with a permission error.
  • A plugin crash/leak is contained to plugin-host; the core app is unaffected.

Reference

Clone this wiki locally