Extending the agent image
The base formae agent image at ghcr.io/platform-engineering-labs/formae ships with the standard plugin set: aws, azure, gcp, oci, ovh, and auth-basic. If you deploy via any of the cloud installers (AWS, Azure, GCP, Helm) to manage one of those clouds, you're done - no extra steps.
To manage anything else (grafana, datadog, k8s, gha, gitlab, compose, databricks, …) build a derived image that layers the plugin on top of the base, then point your cloud deployment at the derived image instead of ghcr.io/.../formae:latest. formae plugin install runs locally on the host that invokes it; for a cloud-deployed agent the derived image is the supported path.
Dockerfile pattern
ARG BASE_VERSION=0.85.2
FROM ghcr.io/platform-engineering-labs/formae:${BASE_VERSION}
USER root
RUN apt-get update && \
apt-get install -y --no-install-recommends jq curl && \
HOME=/home/pel /bin/bash -e -c "$(curl -fsSL https://hub.platform.engineering/get/setup.sh)" -- install --yes <plugin-name> && \
apt-get purge -y --auto-remove jq curl && \
rm -rf /var/lib/apt/lists/* && \
/opt/pel/bin/formae clean --all
RUN chown -R pel:pel /opt/pel
USER pel
WORKDIR /home/pel
Replace <plugin-name> with the plugin you want. Add more plugins to the same install invocation by space-separating them.
The chown -R pel:pel /opt/pel is required. The plugin install runs as root and may leave root-owned files under /opt/pel. The agent runs as pel and refuses to start when its install tree is root-owned. The image has no sudo, so the only way out is to restore ownership at image build time.
Build and verify the image locally
docker build -t formae-extended:test .
docker run --rm formae-extended:test /opt/pel/bin/formae plugin list
The plugin you added should appear in the resulting list alongside the standard set.
Verify the agent actually loads the plugin at startup:
docker run --rm -p 49684:49684 formae-extended:test
# In another shell:
docker logs <container> 2>&1 | grep "Plugin registered"
Look for a Plugin registered: namespace=<UPPERCASE> line for the plugin you added.
Push to your cloud's registry
Each cloud installer pulls the agent image from its own registry. Push the derived image to the registry referenced in your installer's deploy command, then update the deploy command to reference the new image instead of ghcr.io/.../formae:latest.
- AWS ECS Express: push to ECR, swap the
imagefield in theaws ecs create-express-gateway-servicecall. - AWS Standard ECS: push to ECR (or any registry the task execution role can pull from), swap the
imagefield on the task definition. See Build a custom agent image for the pattern, and combine the two patterns in a single Dockerfile if you also need the RDS CA bundle. - Azure Container Instances: push to ACR (or any registry the ACI managed identity can read), swap
--imageon theaz container createcall. - GCP Cloud Run: push to a standard Artifact Registry repository in the same project (separate from the existing
ghcr.ioproxy repo), swap--imageon thegcloud run deploycall. - Helm / Kubernetes: push to any registry the cluster can pull from. Override the chart's image via
--set image.repository=<your-registry>/formae-extended --set image.tag=<your-tag>onhelm install.
Verify the running agent
formae plugin list reads the local /opt/pel tree only; there is no remote API for plugin inspection. To verify a cloud-deployed agent loaded the plugin, exec into the running container or inspect its startup logs.
| Cloud | Verification command |
|---|---|
| AWS ECS Express | aws ecs execute-command --cluster <c> --task <t> --interactive --command "/bin/sh" then formae plugin list (service must have --enable-execute-command) |
| Azure Container Instances | az container exec --resource-group <rg> --name <name> --exec-command "/bin/sh" then formae plugin list |
| GCP Cloud Run | Cloud Run does not provide interactive exec. Use gcloud logging read and look for the Plugin registered: namespace=<UPPERCASE> line at agent startup. |
| Kubernetes | kubectl exec deploy/<release-name> -- formae plugin list |
Known constraints
- The formae CLI refuses to talk to an agent on a different version. Whoever runs the CLI against a derived-image deployment must run the same version the image ships. Update with
sudo formae update. BASE_VERSIONpins the image tag, not the agent binary. A:0.85.0image may ship a0.85.2binary because the base image resolves the version at build time. To pin the binary deterministically, add an explicitsetup.sh install --yes formae@<exact-version>step in your derived Dockerfile before the plugin install.