Skip to main content

Installing Plugins

Purpose: For platform engineers, shows how to build and deploy the branding plugin.

Task Summary

This guide covers building the @opencenter/headlamp-plugin-branding plugin and deploying it to a Kubernetes cluster running Headlamp. Two deployment methods are described: ConfigMap mount and init container extraction.

Prerequisites

  • Node.js >= 20.0.0 and pnpm >= 9.0.0 on your build machine
  • kubectl configured with access to the target cluster
  • Headlamp deployed in the headlamp namespace (via FluxCD from openCenter-gitops-base)
  • Clone of the headlamp-branding-plugin repository

Steps

1. Build the Plugin

cd headlamp-branding-plugin
pnpm install
pnpm --filter @opencenter/headlamp-plugin-branding run build

Build output lands in plugins/branding/dist/. Confirm main.js and the assets/ directory exist:

ls plugins/branding/dist/
# Expected: main.js main.js.map package.json assets/

2. Package the Plugin (Optional)

If you need a distributable ZIP for transfer to air-gap environments:

pnpm --filter @opencenter/headlamp-plugin-branding run package
# Output: plugins/branding/opencenter-headlamp-branding-plugin-1.0.0.zip

3a. Deploy via ConfigMap

Create a ConfigMap from the dist/ directory and mount it into the Headlamp pod:

kubectl create configmap opencenter-branding-plugin \
--from-file=plugins/branding/dist/ \
-n headlamp

Patch the Headlamp deployment to mount the ConfigMap:

# headlamp-plugin-patch.yaml
spec:
template:
spec:
containers:
- name: headlamp
volumeMounts:
- name: branding-plugin
mountPath: /headlamp/plugins/branding
volumes:
- name: branding-plugin
configMap:
name: opencenter-branding-plugin
kubectl patch deployment headlamp -n headlamp --patch-file headlamp-plugin-patch.yaml

3b. Deploy via Init Container

This method extracts the plugin ZIP at pod startup. Useful when the plugin is packaged as a single artifact.

kubectl create configmap opencenter-branding-plugin-zip \
--from-file=plugins/branding/opencenter-headlamp-branding-plugin-1.0.0.zip \
-n headlamp

Add an init container to the Headlamp deployment:

spec:
template:
spec:
initContainers:
- name: install-plugins
image: busybox:latest
command: ["sh", "-c", "unzip /plugins-zip/opencenter-headlamp-branding-plugin-1.0.0.zip -d /plugins/branding"]
volumeMounts:
- name: plugins-zip
mountPath: /plugins-zip
- name: plugins
mountPath: /plugins
containers:
- name: headlamp
volumeMounts:
- name: plugins
mountPath: /headlamp/plugins
volumes:
- name: plugins-zip
configMap:
name: opencenter-branding-plugin-zip
- name: plugins
emptyDir: {}

4. Restart Headlamp

kubectl rollout restart deployment/headlamp -n headlamp
kubectl rollout status deployment/headlamp -n headlamp

Verification

  1. Port-forward to the Headlamp service:
    kubectl port-forward -n headlamp svc/headlamp 4466:4466
  2. Open http://localhost:4466 in a browser.
  3. Open the browser console (F12) and confirm: Plugin loaded: @opencenter/headlamp-plugin-branding
  4. Navigate to Settings → Appearance. Two themes should appear: "OpenCenter Cloud Day" and "OpenCenter Abyssal Night".
  5. Select each theme and verify the logo in the sidebar updates (light variant for Cloud Day, dark variant for Abyssal Night).

Updating the Plugin

After rebuilding, update the ConfigMap and restart:

kubectl create configmap opencenter-branding-plugin \
--from-file=plugins/branding/dist/ \
-n headlamp \
--dry-run=client -o yaml | kubectl apply -f -

kubectl rollout restart deployment/headlamp -n headlamp

Troubleshooting

Plugin not loading — Verify the mount path is exactly /headlamp/plugins/branding/ and that main.js exists at that path. Exec into the pod to check:

kubectl exec -n headlamp deploy/headlamp -- ls /headlamp/plugins/branding/

Themes not appearing — Clear browser cache and hard-reload. Check the console for JavaScript errors that might prevent registerAppTheme from executing.

Logo shows broken image — Confirm assets/logo.png and assets/logo_dark.png exist in the plugin directory. Check the browser network tab for 404 responses on those paths.