PageSourceSearch

https://headlamp.dev/assets/js/f35b59f4.eab0d550.js

js headlamp.dev collected 2026-10-02 06:02:06 UTC 11,075 bytes, 1 lines download raw bytes

1"use strict";(self.webpackChunkheadlamp_website=self.webpackChunkheadlamp_website||[]).push([[3039],{28453:(n,e,i)=>{i.d(e,{R:()=>s,x:()=>p});var l=i(96540);const a={},t=l.createContext(a);function s(n){const e=l.useContext(t);return l.useMemo((function(){return"function"==typeof n?n(e):{...e,...n}}),[e,n])}function p(n){let e;return e=n.disableParentContext?"function"==typeof n.components?n.components(a):n.components||a:s(n.components),l.createElement(t.Provider,{value:e},n.children)}},50290:(n,e,i)=>{i.r(e),i.d(e,{assets:()=>r,contentTitle:()=>s,default:()=>u,frontMatter:()=>t,metadata:()=>p,toc:()=>o});var l=i(74848),a=i(28453);const t={title:"Building and Shipping Plugins",sidebar_label:"Building & Shipping"},s=void 0,p={id:"latest/development/plugins/building",title:"Building and Shipping Plugins",description:"Once you have a plugin ready, you may want to build it for production and",source:"@site/docs/latest/development/plugins/building.md",sourceDirName:"latest/development/plugins",slug:"/latest/development/plugins/building",permalink:"/docs/latest/development/plugins/building",draft:!1,unlisted:!1,editUrl:"https://github.com/kubernetes-sigs/headlamp/edit/main/docs/development/plugins/building.md",tags:[],version:"current",frontMatter:{title:"Building and Shipping Plugins",sidebar_label:"Building & Shipping"},sidebar:"mainSidebar",previous:{title:"i18n",permalink:"/docs/latest/development/plugins/i18n"},next:{title:"Publishing",permalink:"/docs/latest/development/plugins/publishing"}},r={},o=[{value:"Deploying Plugins (General Information)",id:"deploying-plugins-general-information",level:2},{value:"Plugin Directory Structure",id:"plugin-directory-structure",level:3},{value:"Extracting Built Plugins",id:"extracting-built-plugins",level:3},{value:"Plugins in Headlamp Desktop",id:"plugins-in-headlamp-desktop",level:2},{value:"Manual Installation",id:"manual-installation",level:3},{value:"Plugins in Headlamp Deployments",id:"plugins-in-headlamp-deployments",level:2},{value:"Using InitContainer with a Plugin Image",id:"using-initcontainer-with-a-plugin-image",level:3},{value:"Creating a Plugin Image",id:"creating-a-plugin-image",level:2}];function d(n){const e={a:"a",admonition:"admonition",code:"code",h2:"h2",h3:"h3",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,a.R)(),...n.components};return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(e.p,{children:"Once you have a plugin ready, you may want to build it for production and\ndeploy with Headlamp or publish it for other Headlamp users to enjoy."}),"\n",(0,l.jsx)(e.h2,{id:"deploying-plugins-general-information",children:"Deploying Plugins (General Information)"}),"\n",(0,l.jsx)(e.p,{children:"Once your plugin is built and tested, you need to deploy it to your Headlamp instances. This section covers all deployment scenarios."}),"\n",(0,l.jsxs)(e.p,{children:["Let's assume that Headlamp will be run with the ",(0,l.jsx)(e.code,{children:"-plugins-dir"})," option set to\n",(0,l.jsx)(e.code,{children:"/headlamp/plugins"}),", which is the default for in-cluster deployments."]}),"\n",(0,l.jsx)(e.h3,{id:"plugin-directory-structure",children:"Plugin Directory Structure"}),"\n",(0,l.jsx)(e.p,{children:"Headlamp expects plugins to follow a specific directory structure:"}),"\n",(0,l.jsx)(e.pre,{children:(0,l.jsx)(e.code,{children:"my-plugins/                 # Plugin root directory\n\u251c\u2500\u2500 MyPlugin1/\n\u2502   \u251c\u2500\u2500 main.js             # Built plugin file\n\u2502   \u2514\u2500\u2500 package.json        # Plugin metadata\n\u251c\u2500\u2500 MyPlugin2/\n\u2502   \u251c\u2500\u2500 main.js\n\u2502   \u2514\u2500\u2500 package.json\n\u2514\u2500\u2500 MyPlugin3/\n    \u251c\u2500\u2500 main.js\n    \u2514\u2500\u2500 package.json\n"})}),"\n",(0,l.jsx)(e.h3,{id:"extracting-built-plugins",children:"Extracting Built Plugins"}),"\n",(0,l.jsx)(e.p,{children:"To extract a single plugin, you can package it first, then extract the package to the right place:"}),"\n",(0,l.jsx)(e.pre,{children:(0,l.jsx)(e.code,{className:"language-bash",children:"npm install\nnpm run build\nnpm run package\n\n# Extract single plugin\ntar xvzf my-first-plugin-0.1.0.tar.gz -C /headlamp/plugins\n"})}),"\n",(0,l.jsxs)(e.p,{children:["If you prefer to export one or more plugins directly, use the ",(0,l.jsx)(e.code,{children:"headlamp-plugin"})," tool. Run ",(0,l.jsx)(e.code,{children:"npm run build"})," first. Then use the ",(0,l.jsx)(e.code,{children:"extract"})," option on a folder with Headlamp plugins."]}),"\n",(0,l.jsx)(e.p,{children:"For a directory like this:"}),"\n",(0,l.jsx)(e.pre,{children:(0,l.jsx)(e.code,{children:"# Directory structure\nmy-plugins/\n\u251c\u2500\u2500 MyPlugin1/\n\u2502   \u251c\u2500\u2500 dist/\n\u2502   \u2502   \u2514\u2500\u2500 main.js\n\u2502   \u2514\u2500\u2500 package.json\n\u2514\u2500\u2500 MyPlugin2/\n    \u251c\u2500\u2500 dist/\n    \u2502   \u2514\u2500\u2500 main.js\n    \u2514\u2500\u2500 package.json\n"})}),"\n",(0,l.jsx)(e.p,{children:"You can extract the plugins into a target directory like this:"}),"\n",(0,l.jsx)(e.pre,{children:(0,l.jsx)(e.code,{className:"language-bash",children:"npx @kinvolk/headlamp-plugin extract ./my-plugins /headlamp/plugins\n"})}),"\n",(0,l.jsx)(e.h2,{id:"plugins-in-headlamp-desktop",children:"Plugins in Headlamp Desktop"}),"\n",(0,l.jsx)(e.p,{children:"Headlamp Desktop has a Plugin Catalog to install plugins easily. It includes plugins from Headlamp developers and the community."}),"\n",(0,l.jsx)(e.p,{children:"By default, only official plugins in the Plugin Catalog are allowed. The catalog confirms which plugin you want to install. It also shows where the plugin will be downloaded from."}),"\n",(0,l.jsx)(e.admonition,{type:"important",children:(0,l.jsx)(e.p,{children:"The Plugin Catalog allows users to change the default behavior and instead show all\nplugins. It is however extremely important that you only run plugins that you\ntrust, as plugins run in the same JavaScript context as the main application."})}),"\n",(0,l.jsxs)(e.p,{children:["To learn how to publish your plugin to make it available in the Plugin Catalog for other users, see the ",(0,l.jsx)(e.a,{href:"/docs/latest/development/plugins/publishing",children:"Publishing Plugins guide"}),"."]}),"\n",(0,l.jsx)(e.h3,{id:"manual-installation",children:"Manual Installation"}),"\n",(0,l.jsx)(e.p,{children:"First, build and package the plugin in the plugin folder:"}),"\n",(0,l.jsx)(e.pre,{children:(0,l.jsx)(e.code,{className:"language-bash",children:"cd my-plugin/\nnpm install\nnpm run build\nnpm run package\n"})}),"\n",(0,l.jsx)(e.p,{children:"You can install the plugin in the Headlamp desktop app by exp
1orting the plugin\narchive to the plugins directory. E.g.:"}),"\n",(0,l.jsx)(e.p,{children:"On Linux/macOS:"}),"\n",(0,l.jsx)(e.pre,{children:(0,l.jsx)(e.code,{className:"language-bash",children:"mkdir -p ~/.config/Headlamp/plugins/\ntar xvf my-first-plugin-0.1.0.tar.gz -C ~/.config/Headlamp/plugins/\n"})}),"\n",(0,l.jsx)(e.p,{children:"These are the default plugin directory locations for the Headlamp desktop app:"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,l.jsxs)(e.table,{children:[(0,l.jsx)(e.thead,{children:(0,l.jsxs)(e.tr,{children:[(0,l.jsx)(e.th,{children:"Operating System"}),(0,l.jsx)(e.th,{children:"Default Plugin Directory"})]})}),(0,l.jsxs)(e.tbody,{children:[(0,l.jsxs)(e.tr,{children:[(0,l.jsx)(e.td,{children:(0,l.jsx)(e.strong,{children:"MacOS"})}),(0,l.jsx)(e.td,{children:(0,l.jsx)(e.code,{children:"$HOME/.config/Headlamp/plugins"})})]}),(0,l.jsxs)(e.tr,{children:[(0,l.jsx)(e.td,{children:(0,l.jsx)(e.strong,{children:"Linux"})}),(0,l.jsx)(e.td,{children:(0,l.jsx)(e.code,{children:"$HOME/.config/Headlamp/plugins"})})]}),(0,l.jsxs)(e.tr,{children:[(0,l.jsx)(e.td,{children:(0,l.jsx)(e.strong,{children:"Windows"})}),(0,l.jsx)(e.td,{children:(0,l.jsx)(e.code,{children:"%APPDATA%/Headlamp/Config/plugins"})})]})]})]}),"\n",(0,l.jsx)(e.h2,{id:"plugins-in-headlamp-deployments",children:"Plugins in Headlamp Deployments"}),"\n",(0,l.jsx)(e.h3,{id:"using-initcontainer-with-a-plugin-image",children:"Using InitContainer with a Plugin Image"}),"\n",(0,l.jsx)(e.p,{children:"When deploying Headlamp with plugins, it is easier to use a container image with the plugins already installed. Then, use an init container to mount the plugins into the Headlamp container."}),"\n",(0,l.jsxs)(e.p,{children:["Some plugins already have a published container image. For Headlamp's official plugins, see this ",(0,l.jsx)(e.a,{href:"https://github.com/orgs/headlamp-k8s/packages?tab=packages&q=headlamp-plugin",children:"list"}),"."]}),"\n",(0,l.jsxs)(e.p,{children:["You can thus deploy Headlamp with an init container, such as the ",(0,l.jsx)(e.a,{href:"ghcr.io/headlamp-k8s/headlamp-plugin-flux:v0.3.0",children:"Flux UI plugin image"}),":"]}),"\n",(0,l.jsx)(e.pre,{children:(0,l.jsx)(e.code,{className:"language-yaml",children:'apiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: headlamp-with-flux\n  labels:\n    app: headlamp-with-flux\nspec:\n  selector:\n    matchLabels:\n      app: headlamp-with-flux\n  template:\n    metadata:\n      labels:\n        app: headlamp-with-flux\n    spec:\n      initContainers:\n      - name: fetch-plugins\n        image: ghcr.io/headlamp-k8s/headlamp-plugin-flux:latest\n        # Copy the plugins\n        command: ["/bin/sh", "-c"]\n        args: ["cp -r /plugins/* /headlamp/plugins/ && ls -l /headlamp/plugins"]\n        volumeMounts:\n        - name: plugins\n          mountPath: /headlamp/plugins\n      containers:\n      - name: headlamp\n        image: ghcr.io/headlamp-k8s/headlamp:latest\n        args: ["-plugins-dir=/headlamp/plugins"]\n        ports:\n        - containerPort: 4466\n        volumeMounts:\n        - name: plugins\n          mountPath: /headlamp/plugins\n      volumes:\n      - name: plugins\n        emptyDir: {}\n'})}),"\n",(0,l.jsx)(e.h2,{id:"creating-a-plugin-image",children:"Creating a Plugin Image"}),"\n",(0,l.jsxs)(e.p,{children:["The Headlamp official plugins repository has a ",(0,l.jsx)(e.a,{href:"https://github.com/headlamp-k8s/plugins/blob/main/Dockerfile",children:"Dockerfile"})," to generate an image for a plugin. Here is how to use it with the Kompose plugin:"]}),"\n",(0,l.jsx)(e.pre,{children:(0,l.jsx)(e.code,{className:"language-bash",children:"# Get the plugins\ngit clone https://github.com/headlamp-k8s/plugins headlamp-plugins\n\n# Move to the plugins directory\ncd headlamp-plugins\n\n# Build a container image for the kompose plugin\ndocker build --build-arg PLUGIN=kompose -t kompose-plugin:latest -f ./Dockerfile .\n"})}),"\n",(0,l.jsxs)(e.p,{children:["After this step you will have a ",(0,l.jsx)(e.code,{children:"kompose-plugin:latest"})," image that you can use in your deployments, with the actual kompose plugin in its /plugins/kompose directory."]})]})}function u(n={}){const{wrapper:e}={...(0,a.R)(),...n.components};return e?(0,l.jsx)(e,{...n,children:(0,l.jsx)(d,{...n})}):d(n)}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.