Declare a required service¶
Some plugins need a separate process, such as a search server. Declare it in the
plugin's static descriptor instead of asking operators to hand-write it. The composer
validates the declaration, records it in the lock, runs the service next to the
application and wires its address and key into your plugin's configuration.
atlas.search-meilisearch is the reference
(plugins/search-meilisearch/backend/atlas_plugin_search_meilisearch/plugin.py).
A plugin that declares nothing is unaffected: composition, lock and generated inputs are the same as before.
Declare the service¶
Add a RequiredService to PluginDescriptor.required_services:
from atlas_plugin_api import PluginDescriptor, RequiredService
SERVICE = RequiredService(
id="meilisearch",
purpose="Search index for the Meilisearch engine adapter",
image="getmeili/meilisearch:v1.12",
port=7700,
health_check=("curl", "-fsS", "http://localhost:7700/health"),
config_keys={"address": "url", "secret": "key"},
secret_env="MEILI_MASTER_KEY",
data_path="/meili_data",
)
PLUGIN = PluginDescriptor(
...,
config_schema=MyPluginConfig,
required_services=(SERVICE,),
)
| Field | Meaning |
|---|---|
id |
Compose service name and address host. Lowercase letters, digits and dashes. Not postgres, initializer, backend, ingestor or frontend |
purpose |
One line shown in errors and generated comments |
image |
Image pinned by a tag other than latest, or by a digest |
port |
Port the service listens on; the generated address is http://<id>:<port> |
health_check |
Command run inside the container; exit 0 means healthy |
config_keys |
Maps address, and optionally secret, to field names of your config_schema |
secret_env |
Variable the container reads its key from. Set exactly when config_keys has secret |
data_path |
Optional absolute container path to keep on a named volume |
The descriptor is read before django.setup(), so a declaration is metadata only; it
never starts or contacts anything. Invalid values raise ValueError when the module
is imported.
Accept the wired values¶
The fields named in config_keys must exist on the configuration schema. Make the
secret field str | SecretRef | None so the composer's reference validates:
The composer fills url with the generated address and key with
{fromEnv: ATLAS_SERVICE_<ID>_KEY}. A value the operator writes in config: always
wins. Read the resolved value with get_plugin_config, as described in Plugin
configuration.
What the composer does¶
atlas-compose resolverecords each service in the lock under<plugin-id>/<service-id>, with the declaring plugin, pinned image, port, health check, data path and the names of the key variables. The same manifest always yields the same entries.atlas-compose generate backendadds the address and key reference to the plugin's configuration in the generated settings.atlas-compose generate composewrites an override file: the service with a health check and, fordata_path, a named volume<id>-data. It adds the key variable tobackendandingestorand makes them wait for the service to be healthy.atlas-compose validatefails when two selected plugins declare the same service id with different definitions (naming both), when a config key is not a schema field, or when the lock no longer matches the manifest.
If the declaring plugin is not selected or is disabled, nothing is generated.
Secrets¶
The lock and generated files hold the name of the key's environment variable, never
its value. The operator exports ATLAS_SERVICE_<ID>_KEY in the deployment
environment; Compose fails to start with a message naming it when it is missing. Do
not put the secret in the public configuration projection.
Let operators bring their own instance¶
No work is needed on your side. An operator marks the service external on the plugin's manifest entry:
- id: atlas.example
version: 0.1.0
backend:
package: atlas-plugin-example
source: workspace
services:
meilisearch:
external: true
address: http://meilisearch.internal:7700
The composer then generates no container or volume and wires the given address.
external: true without an address, or a service id the plugin does not declare,
fails composition.
Verify¶
- Select the plugin in a development manifest and run
atlas-compose resolve. Check theservices:section of the lock. - Run
atlas-compose generate composeand confirm the service, volume anddepends_onappear. Deselect the plugin and confirm they disappear. - Start the stack and confirm the service is healthy and the plugin connects.
See examples/search-meilisearch/ for a manifest, lock and generated output. For
operators, Run search on Meilisearch
shows the same flow from the other side.