Plugin Development Setup

This guide explains how to develop an ADL plugin locally and test it against the ADL stack. There are two approaches — pick the one that fits your situation.



Flow B — Plugin mounted into the main ADL stack (integration testing)

When you need to test your plugin alongside other real plugins running in the main ADL deployment — for example, to verify it doesn’t conflict with another plugin or to test against production-like data — you can mount your plugin source directly into the main ADL containers.

This uses plugins.toml with the folder source type and dev = true for editable install.

Prerequisites

  • The main ADL stack is checked out and working (adl/)

  • Your plugin lives in a sibling directory (e.g. adl-plugins/adl-my-plugin/)

Step 1 — Create a docker-compose.override.yml in the adl/ directory

This mounts both the plugins.toml manifest and your plugin source into all three backend containers:

# adl/docker-compose.override.yml
services:
  adl:
    volumes:
      - ./plugins.toml:/adl/plugins.toml:ro
      - ../adl-plugins/adl-my-plugin/plugins/adl_my_plugin:/adl/dev-plugins/adl_my_plugin
  adl_celery_worker:
    volumes:
      - ./plugins.toml:/adl/plugins.toml:ro
      - ../adl-plugins/adl-my-plugin/plugins/adl_my_plugin:/adl/dev-plugins/adl_my_plugin
  adl_celery_beat:
    volumes:
      - ./plugins.toml:/adl/plugins.toml:ro
      - ../adl-plugins/adl-my-plugin/plugins/adl_my_plugin:/adl/dev-plugins/adl_my_plugin

Step 2 — Create plugins.toml in the adl/ directory

# plugins.toml

# Your plugin under development (editable install — source changes are live)
[[plugins]]
name = "My Plugin (dev)"
folder = "/adl/dev-plugins/adl_my_plugin"
dev = true

# Other real plugins running alongside (optional)
[[plugins]]
name = "FTP Plugin"
git = "https://github.com/wmo-raf/adl-ftp-plugin.git"
tag = "0.8.9"

Step 3 — Start the stack

docker compose up

On first startup, ADL reads plugins.toml, installs your plugin with pip install -e (because dev = true), and installs any other plugins listed.

Note

docker-compose.override.yml is automatically loaded by Docker Compose when present alongside docker-compose.yml — no extra flags needed.

How hot-reload works

  • dev = truepip install -e → Python resolves the plugin from the bind-mounted directory, not from site-packages.

  • Edit any .py file in your plugin source on the host.

  • If using the dev stack (make dev-up), Django and the Celery worker reload automatically.

  • If using the production stack (make up), gunicorn does not auto-reload; restart the container after changes:

    docker compose restart adl adl_celery_worker
    

Run migrations for your plugin

docker compose exec adl adl makemigrations adl_my_plugin
docker compose exec adl adl migrate

When to use this approach

  • Integration testing — verifying your plugin works alongside other plugins

  • Testing against the shared ADL database with real data

  • Debugging an issue that only appears in the full stack


Comparison

Flow A (plugin’s own compose)

Flow B (mounted in main ADL)

Setup effort

Low — cp .env.sample .env && docker compose up

Medium — override file + plugins.toml

Hot-reload

✅ Always

✅ With dev = true (dev stack) / manual restart (prod stack)

Other plugins

❌ Isolated

✅ Run alongside real plugins

Database

Fresh, plugin-specific

Shared ADL database

Best for

Day-to-day plugin development

Integration testing


Verifying the editable install

To confirm your plugin is installed in editable mode (pointing to your source):

docker compose exec adl /adl/venv/bin/pip show adl_my_plugin

The Location field should point to the mounted path (e.g. /adl/dev-plugins/adl_my_plugin), not to a site-packages directory.