Build a derived agent image that layers extra plugins on top of the base formae image, then deploy it wherever you run the agent.
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 through one
of the cloud install guides to manage one of those clouds, you are done, with no
extra steps.To manage anything else (grafana, datadog, k8s, gha, gitlab, compose,
databricks, and so on) build a derived image that layers the plugin on top of
the base, then point your deployment at the derived image. formae plugin install
runs locally on the host that invokes it; for a cloud-deployed agent the derived
image is the supported path.
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 can leave root-owned files under /opt/pel. The agent runs as pel and
refuses to start when its install tree is root-owned, and the image has no sudo,
so restore ownership at build time.
Each install path pulls the agent image from its own registry. Push the derived
image to the registry your deployment reads from, then point the deployment at it
instead of ghcr.io/.../formae:latest.
AWS (Bootstrap): push to ECR, then pass the derived image as --formae-image when you install or upgrade the agent.
Azure Container Instances: push to ACR (or any registry the ACI managed identity can read), then set --image on the Azure deploy.
GCP Cloud Run: push to an Artifact Registry repository in the same project, then set --image on the GCP deploy.
Kubernetes / Helm: push to any registry the cluster can pull from, then override the chart image with --set image.repository=<your-registry>/formae-extended --set image.tag=<your-tag> on the Helm install.
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 read its startup logs.
Deployment
Verification
AWS ECS
aws ecs execute-command --cluster <c> --task <t> --container formae-agent --interactive --command /bin/sh, then formae plugin list (the service needs --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
No interactive exec; use gcloud logging read and look for the Plugin registered line at startup
Kubernetes
kubectl exec deploy/<release-name> -- formae plugin list
The formae CLI talks only to an agent on the same version. Whoever runs the CLI against a derived-image deployment must run the version the image ships. Update the local CLI with formae update <version>.
BASE_VERSION pins the image tag, not the agent binary: a :0.87.1 image can ship a slightly newer binary because the base resolves the version at build time. To pin the binary deterministically, add an explicit setup.sh install --yes formae@<exact-version> step before the plugin install.
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"formae","colors":{"primary":"#ff8201","light":"#ff8201","dark":"#9c4f00"},"logo":{"light":"https://mintcdn.com/platform-engineering-labs/mNa46DBzXSjV0agT/logo/formae-logo-light.png?fit=max\u0026auto=format\u0026n=mNa46DBzXSjV0agT\u0026q=85\u0026s=8563b5284bd2cf259539ff5e7b9d457f","dark":"https://mintcdn.com/platform-engineering-labs/mNa46DBzXSjV0agT/logo/formae-logo-dark.png?fit=max\u0026auto=format\u0026n=mNa46DBzXSjV0agT\u0026q=85\u0026s=12888995934ece68e08ef7c2c8da99b7"},"favicon":"https://mintcdn.com/platform-engineering-labs/CG7M-6iCStm7YFly/logo/favicon.ico?fit=max\u0026auto=format\u0026n=CG7M-6iCStm7YFly\u0026q=85\u0026s=dbfd5946ac35d39a009c90d67740874a","appearance":{"default":"dark"},"background":{"decoration":"grid","color":{"light":"#f4f5fb","dark":"#05051f"}},"fonts":{"heading":{"family":"Saans","weight":700,"source":"fonts/Saans-Bold.woff2","format":"woff2"},"body":{"family":"Saans","weight":400,"source":"fonts/Saans-Regular.woff2","format":"woff2"}},"styling":{"codeblocks":{"languages":{"custom":["/languages/pkl.json"]}},"latex":true},"banner":{"content":"The formae MCP plugin is now **formae**. Uninstall **formae-mcp** and install **formae**. [Migration steps](/documentation/guides/ai-coding-assistants#migrate-from-formae-mcp).","dismissible":true},"navigation":{"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"platform-engineering-labs","hasAudioNarration":false,"actualSubdomain":"platform-engineering-labs","customDomains":["docs.formae.ai"],"gitSource":{"type":"github","owner":"platform-engineering-labs","repo":"formae-docs","deployBranch":"main","contentDirectory":"","isPrivate":true,"mountPath":"","label":""},"chroma":{"collectionId":"5e7fa02b-cbcc-4078-aba0-ba3b5a3518af","liveDeploymentHistoryId":"6ac68da1059039e5661c1ae1","schemaVersion":"v3","latestBuiltDeploymentHistoryId":"6ac68da1059039e5661c1ae1"},"entitlements":{"AI_CHAT":{"status":"DISABLED"}},"buildId":"6ac68da1059039e5661c1ae1","clientVersion":"0.0.3965","searchFilterCounts":[{"language":"default","tag":"Documentation","count":103},{"language":"default","tag":"Reference","count":59},{"language":"default","tag":"Plugin development","count":34},{"language":"default","tag":"Cloud providers","count":33},{"language":"default","tag":"Guides","count":32},{"language":"default","tag":"Concepts","count":24},{"language":"default","tag":"Get started","count":22},{"language":"default","tag":"Common patterns","count":22},{"language":"default","tag":"CLI","count":16},{"language":"default","tag":"Tutorial","count":16}]},"assistantConfig":{"enableAskAiButton":false,"enableStarterQuestions":false,"enableContextualStarterQuestions":false,"enableAskAiSearchBar":true},"hasChatPermissions":false,"hasWebMcpPermissions":false,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-v7-file-tree","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"pause-universal-search-reconcile","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"per-site-search-delta","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-private-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-nav-generations","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"byok-sep-25","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"vite-origin","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-agent-model-picker","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-updated-9-15","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"isAtlas":false,"googleFontsInlined":false},"customCss":[{"filePath":"style.css","content":":root{--brand-navy:#02024b;--brand-orange:#ff8201;--brand-orange-deep:#e07301;--brand-sky:#29abe2;--brand-green:#00c153;--brand-radius:12px;--brand-mono:\"Saans Mono\", ui-monospace, SFMono-Regular, Menlo, monospace;--brand-mono-safe:ui-monospace, \"SF Mono\", SFMono-Regular, Menlo, Consolas, monospace;--brand-ink:#0a0a1f;--brand-ink-soft:#494c66;--brand-ink-faint:rgba(2, 2, 75, 0.62);--brand-rail:rgba(255, 255, 255, 0.55);--brand-card:rgba(255, 255, 255, 0.78);--brand-edge:rgba(2, 2, 75, 0.13);--brand-edge-strong:rgba(2, 2, 75, 0.26)}html.dark{--brand-ground:#05051f;--brand-ink:#ffffff;--brand-ink-soft:#cccccc;--brand-ink-faint:rgba(255, 255, 255, 0.55);--brand-rail:rgba(255, 255, 255, 0.03);--brand-card:rgba(255, 255, 255, 0.045);--brand-edge:rgba(255, 255, 255, 0.12);--brand-edge-strong:rgba(255, 255, 255, 0.22)}@font-face{font-family:\"Saans Mono\";src:url(/fonts/SaansMono-Medium.woff2) format(\"woff2\");font-weight:500;font-style:normal;font-display:swap}code,kbd,samp{font-family:var(--brand-mono)}pre,pre code,pre.shiki,pre.shiki code{font-family:var(--brand-mono-safe)}.nav-logo{height:2.625rem!important}.fa-convo{border:1px solid var(--brand-edge);border-radius:var(--brand-radius);background:var(--brand-card);overflow:hidden;margin:1.1rem 0}.fa-convo-head{display:flex;align-items:center;gap:8px;padding:8px 16px;font-family:var(--brand-mono);font-size:11.5px;letter-spacing:.06em;text-transform:uppercase;color:var(--brand-ink-faint);background:var(--brand-rail);border-bottom:1px solid var(--brand-edge)}.fa-convo-head::before{content:\"\";width:8px;height:8px;border-radius:999px;background:var(--brand-orange)}.fa-turn{display:grid;grid-template-columns:82px 1fr;gap:14px;padding:13px 16px;border-left:3px solid transparent}.fa-turn+.fa-turn{border-top:1px solid var(--brand-edge)}.fa-turn.fa-bot{border-left-color:var(--brand-orange)}.fa-tag{font-family:var(--brand-mono);font-size:11px;letter-spacing:.03em;text-transform:uppercase;font-weight:600;padding-top:2px}.fa-turn.fa-you .fa-tag{color:var(--brand-orange)}.fa-turn.fa-bot .fa-tag{color:var(--brand-ink-faint)}.fa-body{margin:0}@media (max-width:640px){.fa-turn{grid-template-columns:62px 1fr;gap:10px}}.fa-term{border-radius:16px;overflow:hidden;border:1px solid rgba(255,255,255,.1);margin:1.1rem 0;background:#0b0c0e}.fa-term-body{color:#ccc;padding:14px 16px;overflow-x:auto;white-space:nowrap;font-family:var(--brand-mono-safe);font-size:12.5px;line-height:1.1}.fa-term-banner{display:flex;align-items:flex-end;gap:12px;padding:16px 16px 2px}.fa-term-banner img{display:block;width:165px;max-width:55%;height:auto;margin:0!important}.fa-term-ver{font-family:var(--brand-mono-safe);font-size:12.5px;line-height:1;padding-bottom:3.5px;color:rgba(255,255,255,.45)}.fa-term-banner+.fa-term-body{padding-top:6px}.fa-plate img,.fa-plate>div{border-radius:var(--brand-radius)}.fa-plate img{border:1px solid var(--brand-edge)}html.dark .fa-plate img{background:#fff;padding:14px}html:not(.dark) span[style*=\"rgba(255, 130, 1, 0.1)\"]{background:0 0!important}.fa-arch{margin:1.5rem 0}.fa-arch img{width:100%;height:auto}.fa-arch .fa-arch-d,html.dark .fa-arch .fa-arch-l{display:none}.fa-arch img,html.dark .fa-arch .fa-arch-d{display:block}html:not(.dark) .prose a{border-bottom-color:#9c4f00;border-bottom-width:1.5px}html:not(.dark) .prose a:hover{border-bottom-width:2.5px}body,html{overflow-x:clip!important}"}],"page":{"pagePath":"documentation/guides/extend-the-agent-image","slug":"/documentation/guides/extend-the-agent-image","pageMetadata":{"title":"Extend the agent image","description":"Build a derived agent image that layers extra plugins on top of the base formae image, then deploy it wherever you run the agent.","href":"/documentation/guides/extend-the-agent-image"},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsx(_components.p, {\n children: \"Build a derived agent image that layers extra plugins on top of the base formae image, then deploy it wherever you run the agent.\"\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){const _components={a:`a`,code:`code`,li:`li`,p:`p`,pre:`pre`,span:`span`,strong:`strong`,tbody:`tbody`,td:`td`,th:`th`,thead:`thead`,tr:`tr`,ul:`ul`,..._provideComponents(),...props.components},{CodeBlock,Heading,Table,Warning}=_components;if(!CodeBlock)_missingMdxReference(`CodeBlock`,true);if(!Heading)_missingMdxReference(`Heading`,true);if(!Table)_missingMdxReference(`Table`,true);if(!Warning)_missingMdxReference(`Warning`,true);return _jsxs(_Fragment,{children:[_jsxs(_components.p,{children:[`The base formae agent image at\n`,_jsx(_components.code,{children:`ghcr.io/platform-engineering-labs/formae`}),` ships with the standard plugin set:\n`,_jsx(_components.code,{children:`aws`}),`, `,_jsx(_components.code,{children:`azure`}),`, `,_jsx(_components.code,{children:`gcp`}),`, `,_jsx(_components.code,{children:`oci`}),`, `,_jsx(_components.code,{children:`ovh`}),`, and `,_jsx(_components.code,{children:`auth-basic`}),`. If you deploy through one\nof the cloud install guides to manage one of those clouds, you are done, with no\nextra steps.`]}),`\n`,_jsxs(_components.p,{children:[`To manage anything else (`,_jsx(_components.code,{children:`grafana`}),`, `,_jsx(_components.code,{children:`datadog`}),`, `,_jsx(_components.code,{children:`k8s`}),`, `,_jsx(_components.code,{children:`gha`}),`, `,_jsx(_components.code,{children:`gitlab`}),`, `,_jsx(_components.code,{children:`compose`}),`,\n`,_jsx(_components.code,{children:`databricks`}),`, and so on) build a derived image that layers the plugin on top of\nthe base, then point your deployment at the derived image. `,_jsx(_components.code,{children:`formae plugin install`}),`\nruns locally on the host that invokes it; for a cloud-deployed agent the derived\nimage is the supported path.`]}),`\n`,_jsx(Heading,{level:`2`,id:`dockerfile-pattern`,children:`Dockerfile pattern`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`16`,language:`docker`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`docker`,children:_jsxs(_components.code,{language:`docker`,numberOfLines:`16`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`ARG`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` BASE_VERSION=0.87.1`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`FROM`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:\" ghcr.io/platform-engineering-labs/formae:${BASE_VERSION}\"})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`USER`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` root`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`RUN`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` apt-get update \u0026\u0026 \\\\`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` apt-get install -y --no-install-recommends jq curl \u0026\u0026 \\\\`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` HOME=/home/pel /bin/bash -e -c `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"$(curl -fsSL https://hub.platform.engineering/get/setup.sh)\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` -- install --yes \u003cplugin-name> \u0026\u0026 \\\\`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` apt-get purge -y --auto-remove jq curl \u0026\u0026 \\\\`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` rm -rf /var/lib/apt/lists/* \u0026\u0026 \\\\`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` /opt/pel/bin/formae clean --all`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`RUN`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` chown -R pel:pel /opt/pel`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`USER`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` pel`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`WORKDIR`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` /home/pel`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`Replace `,_jsx(_components.code,{children:`\u003cplugin-name>`}),` with the plugin you want. Add more plugins to the same\n`,_jsx(_components.code,{children:`install`}),` invocation by space-separating them.`]}),`\n`,_jsx(Warning,{children:_jsxs(_components.p,{children:[`The `,_jsx(_components.code,{children:`chown -R pel:pel /opt/pel`}),` is required. The plugin install runs as `,_jsx(_components.code,{children:`root`}),`\nand can leave root-owned files under `,_jsx(_components.code,{children:`/opt/pel`}),`. The agent runs as `,_jsx(_components.code,{children:`pel`}),` and\nrefuses to start when its install tree is root-owned, and the image has no `,_jsx(_components.code,{children:`sudo`}),`,\nso restore ownership at build time.`]})}),`\n`,_jsx(Heading,{level:`2`,id:`build-and-verify-locally`,children:`Build and verify locally`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`2`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`2`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`docker`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` build`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -t`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` formae-extended:test`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` .`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`docker`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` run`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --rm`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` formae-extended:test`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` /opt/pel/bin/formae`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` plugin`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` list`})]}),`\n`]})})}),`\n`,_jsx(_components.p,{children:`The plugin you added should appear alongside the standard set. To confirm the\nagent loads it at startup:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`3`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`3`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`docker`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` run`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --rm`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -p`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` 49684:49684`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` formae-extended:test`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`# In another shell:`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`docker`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` logs`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` \u003c`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`containe`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`r`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`>`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` 2>\u00261`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` |`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:` grep`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"Plugin registered\"`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`Look for a `,_jsx(_components.code,{children:`Plugin registered: namespace=\u003cUPPERCASE>`}),` line for the plugin you\nadded.`]}),`\n`,_jsx(Heading,{level:`2`,id:`deploy-the-derived-image`,children:`Deploy the derived image`}),`\n`,_jsxs(_components.p,{children:[`Each install path pulls the agent image from its own registry. Push the derived\nimage to the registry your deployment reads from, then point the deployment at it\ninstead of `,_jsx(_components.code,{children:`ghcr.io/.../formae:latest`}),`.`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`AWS (Bootstrap):`}),` push to ECR, then pass the derived image as `,_jsx(_components.code,{children:`--formae-image`}),` when you `,_jsx(_components.a,{href:`/documentation/guides/install-agent`,children:`install or upgrade the agent`}),`.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Azure Container Instances:`}),` push to ACR (or any registry the ACI managed identity can read), then set `,_jsx(_components.code,{children:`--image`}),` on the `,_jsx(_components.a,{href:`/documentation/guides/install-agent-azure`,children:`Azure deploy`}),`.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`GCP Cloud Run:`}),` push to an Artifact Registry repository in the same project, then set `,_jsx(_components.code,{children:`--image`}),` on the `,_jsx(_components.a,{href:`/documentation/guides/install-agent-gcp`,children:`GCP deploy`}),`.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Kubernetes / Helm:`}),` push to any registry the cluster can pull from, then override the chart image with `,_jsx(_components.code,{children:`--set image.repository=\u003cyour-registry>/formae-extended --set image.tag=\u003cyour-tag>`}),` on the `,_jsx(_components.a,{href:`/documentation/guides/install-agent-helm`,children:`Helm install`}),`.`]}),`\n`]}),`\n`,_jsx(Heading,{level:`2`,id:`verify-the-running-agent`,children:`Verify the running agent`}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`formae plugin list`}),` reads the local `,_jsx(_components.code,{children:`/opt/pel`}),` tree only; there is no remote API\nfor plugin inspection. To verify a cloud-deployed agent loaded the plugin, exec\ninto the running container or read its startup logs.`]}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Deployment`}),_jsx(_components.th,{children:`Verification`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`AWS ECS`}),_jsxs(_components.td,{children:[_jsx(_components.code,{children:`aws ecs execute-command --cluster \u003cc> --task \u003ct> --container formae-agent --interactive --command /bin/sh`}),`, then `,_jsx(_components.code,{children:`formae plugin list`}),` (the service needs `,_jsx(_components.code,{children:`--enable-execute-command`}),`)`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`Azure Container Instances`}),_jsxs(_components.td,{children:[_jsx(_components.code,{children:`az container exec --resource-group \u003crg> --name \u003cname> --exec-command /bin/sh`}),`, then `,_jsx(_components.code,{children:`formae plugin list`})]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`GCP Cloud Run`}),_jsxs(_components.td,{children:[`No interactive exec; use `,_jsx(_components.code,{children:`gcloud logging read`}),` and look for the `,_jsx(_components.code,{children:`Plugin registered`}),` line at startup`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`Kubernetes`}),_jsx(_components.td,{children:_jsx(_components.code,{children:`kubectl exec deploy/\u003crelease-name> -- formae plugin list`})})]})]})]}),`\n`,_jsx(Heading,{level:`2`,id:`known-constraints`,children:`Known constraints`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[`The formae CLI talks only to an agent on the same version. Whoever runs the CLI against a derived-image deployment must run the version the image ships. Update the local CLI with `,_jsx(_components.code,{children:`formae update \u003cversion>`}),`.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`BASE_VERSION`}),` pins the image tag, not the agent binary: a `,_jsx(_components.code,{children:`:0.87.1`}),` image can ship a slightly newer binary because the base resolves the version at build time. To pin the binary deterministically, add an explicit `,_jsx(_components.code,{children:`setup.sh install --yes formae@\u003cexact-version>`}),` step before the plugin install.`]}),`\n`]})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"codeStyling":{"languages":{"custom":["/languages/pkl.json"]}},"config":{},"pageMetadata":{"title":"Extend the agent image","description":"Build a derived agent image that layers extra plugins on top of the base formae image, then deploy it wherever you run the agent.","href":"/documentation/guides/extend-the-agent-image"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[{"title":"Dockerfile pattern","slug":"dockerfile-pattern","depth":2,"children":[]},{"title":"Build and verify locally","slug":"build-and-verify-locally","depth":2,"children":[]},{"title":"Deploy the derived image","slug":"deploy-the-derived-image","depth":2,"children":[]},{"title":"Verify the running agent","slug":"verify-the-running-agent","depth":2,"children":[]},{"title":"Known constraints","slug":"known-constraints","depth":2,"children":[]}],"codeExamples":{}},"jsLinks":["/_mintlify/custom/platform-engineering-labs/4ffdbad5874a08d3/posthog.js"],"subdomain":"platform-engineering-labs","siteName":"formae","title":"Extend the agent image - formae","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-07-19T04:28:26.747Z","originalFileLocation":"documentation/guides/extend-the-agent-image.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"dark\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Build a derived agent image that layers extra plugins on top of the base formae image, then deploy it wherever you run the agent.\">\u003cmeta data-mint-head name=\"application-name\" content=\"formae\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/platform-engineering-labs/ih3MxqvV1WG3EvUf/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/platform-engineering-labs/ih3MxqvV1WG3EvUf/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/platform-engineering-labs/ih3MxqvV1WG3EvUf/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/platform-engineering-labs/ih3MxqvV1WG3EvUf/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/platform-engineering-labs/ih3MxqvV1WG3EvUf/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/platform-engineering-labs/ih3MxqvV1WG3EvUf/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/platform-engineering-labs/ih3MxqvV1WG3EvUf/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/platform-engineering-labs/ih3MxqvV1WG3EvUf/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/platform-engineering-labs/ih3MxqvV1WG3EvUf/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Extend the agent image - formae\">\u003cmeta data-mint-head property=\"og:description\" content=\"Build a derived agent image that layers extra plugins on top of the base formae image, then deploy it wherever you run the agent.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"formae\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.formae.ai/documentation/guides/extend-the-agent-image\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://platform-engineering-labs.mintlify.app/_mintlify/api/og/v2?division=Install+and+run+the+agent\u0026amp;title=Extend+the+agent+image\u0026amp;description=Build+a+derived+agent+image+that+layers+extra+plugins+on+top+of+the+base+formae+image%2C+then+deploy+it+wherever+you+run+the+agent.\u0026amp;theme=07768c424fb26f39d157f55a\u0026amp;signature=7988dd51e0f3d33a57834b8a3065d77b01f4d2b4dff1fb606c09fde7a602985c\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Extend the agent image - formae\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Build a derived agent image that layers extra plugins on top of the base formae image, then deploy it wherever you run the agent.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://platform-engineering-labs.mintlify.app/_mintlify/api/og/v2?division=Install+and+run+the+agent\u0026amp;title=Extend+the+agent+image\u0026amp;description=Build+a+derived+agent+image+that+layers+extra+plugins+on+top+of+the+base+formae+image%2C+then+deploy+it+wherever+you+run+the+agent.\u0026amp;theme=07768c424fb26f39d157f55a\u0026amp;signature=7988dd51e0f3d33a57834b8a3065d77b01f4d2b4dff1fb606c09fde7a602985c\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/platform-engineering-labs/ih3MxqvV1WG3EvUf/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"formae\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#ff8201\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs.formae.ai/documentation/guides/extend-the-agent-image\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/documentation/guides/extend-the-agent-image.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://docs.formae.ai/#organization\",\"name\":\"formae\",\"url\":\"https://docs.formae.ai\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/platform-engineering-labs/mNa46DBzXSjV0agT/logo/formae-logo-light.png?fit=max\u0026auto=format\u0026n=mNa46DBzXSjV0agT\u0026q=85\u0026s=8563b5284bd2cf259539ff5e7b9d457f\"}},{\"@type\":\"WebSite\",\"@id\":\"https://docs.formae.ai#website\",\"name\":\"formae\",\"url\":\"https://docs.formae.ai\",\"publisher\":{\"@id\":\"https://docs.formae.ai/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://docs.formae.ai/documentation/guides/extend-the-agent-image#webpage\",\"url\":\"https://docs.formae.ai/documentation/guides/extend-the-agent-image\",\"name\":\"Extend the agent image\",\"description\":\"Build a derived agent image that layers extra plugins on top of the base formae image, then deploy it wherever you run the agent.\",\"dateModified\":\"2026-07-19T04:28:26.747Z\",\"isPartOf\":{\"@id\":\"https://docs.formae.ai#website\"},\"breadcrumb\":{\"@id\":\"https://docs.formae.ai/documentation/guides/extend-the-agent-image#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs.formae.ai/documentation/guides/extend-the-agent-image#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Guides\",\"item\":\"https://docs.formae.ai/documentation/guides/pkl-ide-support\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Install and run the agent\",\"item\":\"https://docs.formae.ai/documentation/guides/install-agent\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Extend the agent image\",\"item\":\"https://docs.formae.ai/documentation/guides/extend-the-agent-image\"}]},{\"@type\":[\"Article\",\"TechArticle\"],\"@id\":\"https://docs.formae.ai/documentation/guides/extend-the-agent-image#article\",\"headline\":\"Extend the agent image\",\"name\":\"Extend the agent image\",\"description\":\"Build a derived agent image that layers extra plugins on top of the base formae image, then deploy it wherever you run the agent.\",\"url\":\"https://docs.formae.ai/documentation/guides/extend-the-agent-image\",\"mainEntityOfPage\":{\"@id\":\"https://docs.formae.ai/documentation/guides/extend-the-agent-image#webpage\"},\"dateModified\":\"2026-07-19T04:28:26.747Z\",\"publisher\":{\"@id\":\"https://docs.formae.ai/#organization\"},\"isPartOf\":{\"@id\":\"https://docs.formae.ai#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"formae\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"formae","nav":{"global":null,"tabs":[{"tab":"Documentation","groups":[{"group":"Get started","pages":[{"title":"formae documentation","href":"/documentation"},{"title":"Quick start","href":"/documentation/get-started/quickstart"},{"title":"Quick start with formae Cloud","href":"/documentation/get-started/quickstart-cloud"},{"title":"Quick start with an AI assistant","href":"/documentation/get-started/quickstart-ai-assistant"},{"title":"Write your first forma","href":"/documentation/get-started/write-your-first-forma"}]},{"group":"Guides","pages":[{"group":"Set up your tools","pages":[{"title":"Set up Pkl in your editor","href":"/documentation/guides/pkl-ide-support"},{"title":"AI assistants","href":"/documentation/guides/ai-coding-assistants"},{"title":"Read tfvars in a forma","href":"/documentation/guides/tfvars"}]},{"group":"Install and run the agent","pages":[{"title":"Install and run the agent","href":"/documentation/guides/install-agent"},{"title":"Install and run the agent on Azure","href":"/documentation/guides/install-agent-azure"},{"title":"Install and run the agent on GCP","href":"/documentation/guides/install-agent-gcp"},{"title":"Install the agent with Docker","href":"/documentation/guides/install-agent-docker"},{"title":"Install the agent with Helm","description":"Deploy the formae agent to a Kubernetes cluster with the formae Helm chart.","href":"/documentation/guides/install-agent-helm"},{"title":"Extend the agent image","href":"/documentation/guides/extend-the-agent-image"},{"title":"Observe the agent","description":"Export the formae agent's metrics, logs, and traces through OpenTelemetry, or scrape them from a Prometheus endpoint.","href":"/documentation/guides/observe-the-agent"},{"title":"Manage profiles","href":"/documentation/guides/manage-profiles"}]},{"group":"Manage infrastructure","pages":[{"title":"Create a target","href":"/documentation/guides/create-a-target"},{"title":"Explore your infrastructure","href":"/documentation/guides/explore-your-infrastructure"},{"title":"Bring existing resources under management","href":"/documentation/guides/bring-resources-under-management"},{"title":"Everyday changes","href":"/documentation/guides/everyday-changes"},{"title":"Manage stack policies","href":"/documentation/guides/policies"},{"title":"Rename a resource","href":"/documentation/guides/rename-a-resource"},{"title":"Incidents and recovery","href":"/documentation/guides/incidents-and-recovery"},{"title":"Troubleshoot a failed command","href":"/documentation/guides/troubleshoot-a-failed-command"},{"title":"Repair duplicated map keys","href":"/documentation/guides/repair-duplicated-map-keys"},{"title":"Cancel a running command","href":"/documentation/guides/cancel-a-running-command"},{"title":"Deal with out-of-band changes","href":"/documentation/guides/deal-with-out-of-band-changes"},{"title":"Build self-service infrastructure","href":"/documentation/guides/build-self-service-infrastructure"},{"title":"Reuse infrastructure with modules","href":"/documentation/guides/reuse-with-modules"},{"title":"Run formae in CI/CD","href":"/documentation/guides/cicd"}]}]},{"group":"Concepts","pages":[{"group":"Building blocks","pages":[{"title":"Forma","href":"/documentation/concepts/forma"},{"title":"Stack","href":"/documentation/concepts/stack"},{"title":"Target","href":"/documentation/concepts/target"},{"title":"Resources","href":"/documentation/concepts/resources"},{"title":"Label","href":"/documentation/concepts/label"},{"title":"Properties","href":"/documentation/concepts/properties"},{"title":"Resolvable","href":"/documentation/concepts/resolvable"},{"title":"Values","href":"/documentation/concepts/values"},{"title":"Secrets and generated credentials","href":"/documentation/concepts/secrets"},{"group":"Policies","pages":[{"title":"Policy","sidebarTitle":"Overview","href":"/documentation/concepts/policy"},{"title":"TTL policy","sidebarTitle":"TTL","href":"/documentation/concepts/policies/ttl"},{"title":"Auto-reconcile policy","sidebarTitle":"Auto-reconcile","href":"/documentation/concepts/policies/auto-reconcile"}]}]},{"group":"How formae works","pages":[{"title":"Architecture","href":"/documentation/concepts/architecture"},{"title":"Plugins","href":"/documentation/concepts/plugin"},{"title":"Ways to work with formae","href":"/documentation/concepts/ways-to-work"},{"title":"Apply modes","href":"/documentation/concepts/apply-modes"},{"title":"Synchronization","href":"/documentation/concepts/synchronization"},{"title":"Discovery","href":"/documentation/concepts/discovery"}]}]},{"group":"Reference","pages":[{"group":"CLI","pages":[{"title":"CLI reference","href":"/documentation/reference/cli"},{"title":"formae apply","href":"/documentation/reference/cli/apply"},{"title":"formae destroy","href":"/documentation/reference/cli/destroy"},{"title":"formae status","href":"/documentation/reference/cli/status"},{"title":"formae command","href":"/documentation/reference/cli/command"},{"title":"formae cancel","href":"/documentation/reference/cli/cancel"},{"title":"formae connect","href":"/documentation/reference/cli/connect"},{"title":"formae inventory","href":"/documentation/reference/cli/inventory"},{"title":"formae extract","href":"/documentation/reference/cli/extract"},{"title":"formae eval","href":"/documentation/reference/cli/eval"},{"title":"formae project","href":"/documentation/reference/cli/project"},{"title":"formae plugin","href":"/documentation/reference/cli/plugin"},{"title":"formae profile","href":"/documentation/reference/cli/profile"},{"title":"formae agent","href":"/documentation/reference/cli/agent"},{"title":"formae update","href":"/documentation/reference/cli/update"},{"title":"formae clean","href":"/documentation/reference/cli/clean"}]},{"title":"Configuration","href":"/documentation/reference/configuration"},{"title":"CLI themes","href":"/documentation/reference/themes"},{"title":"Security and networking","href":"/documentation/reference/security-and-networking"},{"title":"Pkl cheatsheet","href":"/documentation/reference/pkl-cheatsheet"},{"group":"Cloud providers","pages":[{"group":"AWS","pages":[{"title":"AWS configuration","href":"/documentation/reference/providers/aws/configuration"},{"group":"Common patterns","pages":[{"title":"Static website (S3 + CloudFront)","href":"/documentation/reference/providers/aws/patterns/static-website-s3-cloudfront"},{"title":"Base VPC networking","href":"/documentation/reference/providers/aws/patterns/base-vpc-networking"},{"title":"CloudFront edge","href":"/documentation/reference/providers/aws/patterns/cloudfront-edge"},{"title":"A self-service database","href":"/documentation/reference/providers/aws/patterns/a-self-service-database"},{"title":"ML platform","href":"/documentation/reference/providers/aws/patterns/ml-platform"},{"title":"Deploy a Lambda","href":"/documentation/reference/providers/aws/patterns/deploy-a-lambda"},{"title":"Deploy an ECS service","href":"/documentation/reference/providers/aws/patterns/deploy-an-ecs-service"},{"title":"Bookstore on EKS","href":"/documentation/reference/providers/aws/patterns/bookstore-on-eks"}]},{"title":"AWS supported resources","href":"/documentation/reference/providers/aws/supported-resources"}]},{"group":"Azure","pages":[{"title":"Azure configuration","href":"/documentation/reference/providers/azure/configuration"},{"group":"Common patterns","pages":[{"title":"Lay down base networking","href":"/documentation/reference/providers/azure/patterns/lay-down-base-networking"},{"title":"Run a PostgreSQL database","href":"/documentation/reference/providers/azure/patterns/run-a-postgresql-database"},{"title":"Provision an AKS cluster","href":"/documentation/reference/providers/azure/patterns/provision-an-aks-cluster"},{"title":"Deploy a virtual machine","href":"/documentation/reference/providers/azure/patterns/deploy-a-virtual-machine"},{"title":"Deploy the bookstore on AKS","href":"/documentation/reference/providers/azure/patterns/deploy-the-bookstore-on-aks"}]},{"title":"Azure supported resources","href":"/documentation/reference/providers/azure/supported-resources"}]},{"group":"GCP","pages":[{"title":"GCP configuration","href":"/documentation/reference/providers/gcp/configuration"},{"group":"Common patterns","pages":[{"title":"Deploy base VPC networking","href":"/documentation/reference/providers/gcp/patterns/deploy-base-vpc-networking"},{"title":"Deploy an HTTP(S) load balancer","href":"/documentation/reference/providers/gcp/patterns/deploy-an-https-load-balancer"},{"title":"Deploy the bookstore on GKE","href":"/documentation/reference/providers/gcp/patterns/deploy-the-bookstore-on-gke"}]},{"title":"GCP supported resources","href":"/documentation/reference/providers/gcp/supported-resources"}]},{"group":"OCI","pages":[{"title":"OCI configuration","href":"/documentation/reference/providers/oci/configuration"},{"group":"Common patterns","pages":[{"title":"Deploy base VCN networking","href":"/documentation/reference/providers/oci/patterns/deploy-base-vcn-networking"},{"title":"Deploy an OKE Kubernetes cluster","href":"/documentation/reference/providers/oci/patterns/deploy-an-oke-kubernetes-cluster"}]},{"title":"OCI supported resources","href":"/documentation/reference/providers/oci/supported-resources"}]},{"group":"Kubernetes","pages":[{"title":"Kubernetes configuration","href":"/documentation/reference/providers/kubernetes/configuration"},{"title":"Kubernetes with installation OIDC","href":"/documentation/reference/providers/kubernetes/oidc"},{"group":"Common patterns","pages":[{"title":"Deploy a Helm chart","href":"/documentation/reference/providers/kubernetes/patterns/deploy-a-helm-chart"},{"title":"Deploy the bookstore webapp","href":"/documentation/reference/providers/kubernetes/patterns/deploy-the-bookstore-webapp"},{"title":"Deploy a Crossplane control plane","href":"/documentation/reference/providers/kubernetes/patterns/deploy-a-crossplane-control-plane"},{"title":"Deploy the LGTM observability stack","href":"/documentation/reference/providers/kubernetes/patterns/deploy-the-lgtm-observability-stack"}]},{"title":"Kubernetes supported resources","href":"/documentation/reference/providers/kubernetes/supported-resources"}]}]},{"title":"Plugin catalog","href":"/documentation/reference/plugin-catalog"},{"title":"Release notes","href":"/documentation/reference/release-notes"}]}]},{"tab":"Plugin development","pages":[{"title":"Plugin development","href":"/plugin-development"}]}]},"title":"Extend the agent image - formae","buildId":"dpl_849ArpqvBiCczQiT1Y1stNGpbqHT","deploymentId":"dpl_849ArpqvBiCczQiT1Y1stNGpbqHT","dynamics":["10e4515597"],"chunks":["BannerMarkdown-cfwQA_n9.js","dist-2LoAhjKH.js","lib--scc4DXi.js","lib-B8HbPgcC.js","clsx-DZLdJUrt.js","html-void-elements-mCSPHezU.js","katex-YMM-FMeD.js","marked.esm-CZWythHk.js"]}