Replace Homepage Helm chart with kustomize manifests and custom Dockerfile
The third-party Helm chart (jameswynn/homepage v2.1.0) pinned Homepage at v1.2.0, 8 minor versions behind upstream. Replace with plain kustomize manifests and a Dockerfile building from forge mirror at v1.10.1, matching the pattern used by other blumeops services. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
869f6bd20d
commit
0648ae450d
11 changed files with 267 additions and 126 deletions
|
|
@ -1,9 +1,7 @@
|
|||
# Homepage - Service Dashboard / Start Page
|
||||
#
|
||||
# Replaced hajimari with gethomepage for active maintenance and better features.
|
||||
# Auto-discovers k8s services via ingress annotations.
|
||||
#
|
||||
# Helm chart: https://github.com/jameswynn/helm-charts/tree/main/charts/homepage
|
||||
# Custom container built from gethomepage/homepage, kustomize manifests.
|
||||
# Dashboard at go.ops.eblu.me / go.tail8d86e.ts.net
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
|
|
@ -11,25 +9,10 @@ metadata:
|
|||
namespace: argocd
|
||||
spec:
|
||||
project: default
|
||||
sources:
|
||||
# Helm chart
|
||||
- repoURL: https://jameswynn.github.io/helm-charts
|
||||
chart: homepage
|
||||
targetRevision: 2.1.0
|
||||
helm:
|
||||
releaseName: homepage
|
||||
valueFiles:
|
||||
- $values/argocd/manifests/homepage/values.yaml
|
||||
# Values file reference
|
||||
- repoURL: ssh://forgejo@forge.ops.eblu.me:2222/eblume/blumeops.git
|
||||
targetRevision: main
|
||||
ref: values
|
||||
# Extra manifests (ExternalSecrets, etc)
|
||||
- repoURL: ssh://forgejo@forge.ops.eblu.me:2222/eblume/blumeops.git
|
||||
targetRevision: main
|
||||
path: argocd/manifests/homepage
|
||||
directory:
|
||||
exclude: "values.yaml"
|
||||
source:
|
||||
repoURL: ssh://forgejo@forge.ops.eblu.me:2222/eblume/blumeops.git
|
||||
targetRevision: main
|
||||
path: argocd/manifests/homepage
|
||||
destination:
|
||||
server: https://kubernetes.default.svc
|
||||
namespace: homepage
|
||||
|
|
|
|||
23
argocd/manifests/homepage/clusterrole.yaml
Normal file
23
argocd/manifests/homepage/clusterrole.yaml
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: homepage
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["namespaces", "pods", "nodes"]
|
||||
verbs: ["get", "list"]
|
||||
- apiGroups: ["extensions", "networking.k8s.io"]
|
||||
resources: ["ingresses"]
|
||||
verbs: ["get", "list"]
|
||||
- apiGroups: ["traefik.containo.us", "traefik.io"]
|
||||
resources: ["ingressroutes"]
|
||||
verbs: ["get", "list"]
|
||||
- apiGroups: ["gateway.networking.k8s.io"]
|
||||
resources: ["gateways", "httproutes"]
|
||||
verbs: ["get", "list"]
|
||||
- apiGroups: ["metrics.k8s.io"]
|
||||
resources: ["nodes", "pods"]
|
||||
verbs: ["get", "list"]
|
||||
- apiGroups: ["apiextensions.k8s.io"]
|
||||
resources: ["customresourcedefinitions/status"]
|
||||
verbs: ["get"]
|
||||
12
argocd/manifests/homepage/clusterrolebinding.yaml
Normal file
12
argocd/manifests/homepage/clusterrolebinding.yaml
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: homepage
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: homepage
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: homepage
|
||||
namespace: homepage
|
||||
|
|
@ -1,76 +1,30 @@
|
|||
# Homepage values for blumeops
|
||||
# Service dashboard at go.ops.eblu.me
|
||||
# Homepage configuration files
|
||||
# Extracted from former Helm values.yaml
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: homepage-config
|
||||
namespace: homepage
|
||||
data:
|
||||
bookmarks.yaml: |
|
||||
- Admin:
|
||||
- Tailscale Admin:
|
||||
- href: https://login.tailscale.com/admin
|
||||
icon: tailscale
|
||||
- 1Password:
|
||||
- href: https://my.1password.com
|
||||
icon: 1password
|
||||
- Pulumi:
|
||||
- href: https://app.pulumi.com/eblume/blumeops-tailnet
|
||||
icon: si-pulumi
|
||||
- ArgoCD:
|
||||
- href: https://argocd.ops.eblu.me
|
||||
icon: argo-cd
|
||||
- UniFi:
|
||||
- href: https://unifi.ui.com
|
||||
icon: ubiquiti
|
||||
|
||||
# Enable RBAC for Kubernetes service autodiscovery
|
||||
enableRbac: true
|
||||
|
||||
serviceAccount:
|
||||
create: true
|
||||
|
||||
# Tailscale Ingress is managed separately in ingress-tailscale.yaml
|
||||
# (Helm chart template doesn't support tailscale.com/* annotations)
|
||||
ingress:
|
||||
main:
|
||||
enabled: false
|
||||
|
||||
env:
|
||||
- name: HOMEPAGE_ALLOWED_HOSTS
|
||||
value: "go.tail8d86e.ts.net,go.ops.eblu.me"
|
||||
# Weather widget
|
||||
- name: HOMEPAGE_VAR_OPENWEATHERMAP_API_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: homepage-openweathermap
|
||||
key: apikey
|
||||
# Jellyfin widget
|
||||
- name: HOMEPAGE_VAR_JELLYFIN_API_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: homepage-jellyfin
|
||||
key: apikey
|
||||
# Miniflux widget
|
||||
- name: HOMEPAGE_VAR_MINIFLUX_API_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: homepage-miniflux
|
||||
key: apikey
|
||||
# Grafana widget
|
||||
- name: HOMEPAGE_VAR_GRAFANA_USERNAME
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: homepage-grafana
|
||||
key: username
|
||||
- name: HOMEPAGE_VAR_GRAFANA_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: homepage-grafana
|
||||
key: password
|
||||
# Forgejo widget
|
||||
- name: HOMEPAGE_VAR_FORGEJO_API_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: homepage-forgejo
|
||||
key: apikey
|
||||
# Navidrome widget
|
||||
- name: HOMEPAGE_VAR_NAVIDROME_USER
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: homepage-navidrome
|
||||
key: user
|
||||
- name: HOMEPAGE_VAR_NAVIDROME_SALT
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: homepage-navidrome
|
||||
key: salt
|
||||
- name: HOMEPAGE_VAR_NAVIDROME_TOKEN
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: homepage-navidrome
|
||||
key: token
|
||||
|
||||
config:
|
||||
# Host services (non-k8s, on indri or LAN)
|
||||
services:
|
||||
services.yaml: |
|
||||
- Host Services:
|
||||
- Forgejo:
|
||||
href: https://forge.ops.eblu.me
|
||||
|
|
@ -134,8 +88,6 @@ config:
|
|||
# widget:
|
||||
# type: caddy
|
||||
# url: http://indri.tail8d86e.ts.net:2019
|
||||
|
||||
# Services on ringtail k3s (not autodiscovered — different cluster)
|
||||
- Infrastructure:
|
||||
- NVR:
|
||||
href: https://nvr.ops.eblu.me
|
||||
|
|
@ -146,27 +98,7 @@ config:
|
|||
icon: ntfy.png
|
||||
description: Push notifications
|
||||
|
||||
# External bookmarks
|
||||
bookmarks:
|
||||
- Admin:
|
||||
- Tailscale Admin:
|
||||
- href: https://login.tailscale.com/admin
|
||||
icon: tailscale
|
||||
- 1Password:
|
||||
- href: https://my.1password.com
|
||||
icon: 1password
|
||||
- Pulumi:
|
||||
- href: https://app.pulumi.com/eblume/blumeops-tailnet
|
||||
icon: si-pulumi
|
||||
- ArgoCD:
|
||||
- href: https://argocd.ops.eblu.me
|
||||
icon: argo-cd
|
||||
- UniFi:
|
||||
- href: https://unifi.ui.com
|
||||
icon: ubiquiti
|
||||
|
||||
# Widgets on the page (info bar at top)
|
||||
widgets:
|
||||
widgets.yaml: |
|
||||
- greeting:
|
||||
text_size: xl
|
||||
text: Welcome to Blue Mops
|
||||
|
|
@ -194,12 +126,12 @@ config:
|
|||
# url: http://indri.tail8d86e.ts.net:61208
|
||||
# metric: cpu
|
||||
|
||||
# Kubernetes autodiscovery
|
||||
kubernetes:
|
||||
kubernetes.yaml: |
|
||||
mode: cluster
|
||||
|
||||
# Layout and styling
|
||||
settingsString: |
|
||||
docker.yaml: ""
|
||||
|
||||
settings.yaml: |
|
||||
title: BlumeOps
|
||||
headerStyle: boxed
|
||||
quicklaunch:
|
||||
113
argocd/manifests/homepage/deployment.yaml
Normal file
113
argocd/manifests/homepage/deployment.yaml
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: homepage
|
||||
namespace: homepage
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: homepage
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: homepage
|
||||
spec:
|
||||
serviceAccountName: homepage
|
||||
securityContext:
|
||||
runAsUser: 1000
|
||||
runAsGroup: 1000
|
||||
fsGroup: 1000
|
||||
containers:
|
||||
- name: homepage
|
||||
image: registry.ops.eblu.me/blumeops/homepage:v1.10.1
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
allowPrivilegeEscalation: false
|
||||
ports:
|
||||
- containerPort: 3000
|
||||
name: http
|
||||
env:
|
||||
- name: HOMEPAGE_ALLOWED_HOSTS
|
||||
value: "go.tail8d86e.ts.net,go.ops.eblu.me"
|
||||
# Weather widget
|
||||
- name: HOMEPAGE_VAR_OPENWEATHERMAP_API_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: homepage-openweathermap
|
||||
key: apikey
|
||||
# Jellyfin widget
|
||||
- name: HOMEPAGE_VAR_JELLYFIN_API_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: homepage-jellyfin
|
||||
key: apikey
|
||||
# Miniflux widget
|
||||
- name: HOMEPAGE_VAR_MINIFLUX_API_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: homepage-miniflux
|
||||
key: apikey
|
||||
# Grafana widget
|
||||
- name: HOMEPAGE_VAR_GRAFANA_USERNAME
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: homepage-grafana
|
||||
key: username
|
||||
- name: HOMEPAGE_VAR_GRAFANA_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: homepage-grafana
|
||||
key: password
|
||||
# Forgejo widget
|
||||
- name: HOMEPAGE_VAR_FORGEJO_API_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: homepage-forgejo
|
||||
key: apikey
|
||||
# Navidrome widget
|
||||
- name: HOMEPAGE_VAR_NAVIDROME_USER
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: homepage-navidrome
|
||||
key: user
|
||||
- name: HOMEPAGE_VAR_NAVIDROME_SALT
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: homepage-navidrome
|
||||
key: salt
|
||||
- name: HOMEPAGE_VAR_NAVIDROME_TOKEN
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: homepage-navidrome
|
||||
key: token
|
||||
volumeMounts:
|
||||
- name: config
|
||||
mountPath: /app/config
|
||||
- name: logs
|
||||
mountPath: /app/config/logs
|
||||
resources:
|
||||
requests:
|
||||
memory: "128Mi"
|
||||
cpu: "100m"
|
||||
limits:
|
||||
memory: "512Mi"
|
||||
cpu: "500m"
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /api/healthcheck
|
||||
port: 3000
|
||||
initialDelaySeconds: 20
|
||||
periodSeconds: 30
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /api/healthcheck
|
||||
port: 3000
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 10
|
||||
volumes:
|
||||
- name: config
|
||||
configMap:
|
||||
name: homepage-config
|
||||
- name: logs
|
||||
emptyDir: {}
|
||||
17
argocd/manifests/homepage/kustomization.yaml
Normal file
17
argocd/manifests/homepage/kustomization.yaml
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
namespace: homepage
|
||||
resources:
|
||||
- serviceaccount.yaml
|
||||
- clusterrole.yaml
|
||||
- clusterrolebinding.yaml
|
||||
- configmap.yaml
|
||||
- deployment.yaml
|
||||
- service.yaml
|
||||
- ingress-tailscale.yaml
|
||||
- external-secret-openweathermap.yaml
|
||||
- external-secret-jellyfin.yaml
|
||||
- external-secret-forgejo.yaml
|
||||
- external-secret-grafana.yaml
|
||||
- external-secret-miniflux.yaml
|
||||
- external-secret-navidrome.yaml
|
||||
12
argocd/manifests/homepage/service.yaml
Normal file
12
argocd/manifests/homepage/service.yaml
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: homepage
|
||||
namespace: homepage
|
||||
spec:
|
||||
selector:
|
||||
app: homepage
|
||||
ports:
|
||||
- name: http
|
||||
port: 3000
|
||||
targetPort: 3000
|
||||
5
argocd/manifests/homepage/serviceaccount.yaml
Normal file
5
argocd/manifests/homepage/serviceaccount.yaml
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: homepage
|
||||
namespace: homepage
|
||||
43
containers/homepage/Dockerfile
Normal file
43
containers/homepage/Dockerfile
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
# Homepage - self-hosted services dashboard
|
||||
# Two-stage build: Node.js build, Alpine runtime
|
||||
|
||||
ARG HOMEPAGE_VERSION=v1.10.1
|
||||
|
||||
FROM node:22-slim AS builder
|
||||
|
||||
ARG HOMEPAGE_VERSION
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends git \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN git clone --depth 1 --branch ${HOMEPAGE_VERSION} \
|
||||
https://forge.ops.eblu.me/eblume/homepage.git /app
|
||||
|
||||
WORKDIR /app
|
||||
RUN mkdir -p config \
|
||||
&& corepack enable && corepack prepare pnpm@latest --activate \
|
||||
&& pnpm install --frozen-lockfile \
|
||||
&& NEXT_TELEMETRY_DISABLED=1 pnpm run build
|
||||
|
||||
FROM node:22-alpine
|
||||
|
||||
LABEL org.opencontainers.image.title=Homepage
|
||||
LABEL org.opencontainers.image.description="A self-hosted services landing page"
|
||||
LABEL org.opencontainers.image.source=https://github.com/gethomepage/homepage
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY --from=builder --chown=1000:1000 /app/public ./public
|
||||
COPY --from=builder --chown=1000:1000 /app/.next/standalone/ ./
|
||||
COPY --from=builder --chown=1000:1000 /app/.next/static/ ./.next/static
|
||||
|
||||
RUN mkdir -p /app/config && chown 1000:1000 /app/config
|
||||
|
||||
ENV NODE_ENV=production
|
||||
ENV PORT=3000
|
||||
EXPOSE 3000
|
||||
|
||||
HEALTHCHECK --interval=10s --timeout=3s --start-period=20s \
|
||||
CMD wget --no-verbose --tries=1 --spider http://127.0.0.1:3000/api/healthcheck || exit 1
|
||||
|
||||
USER 1000
|
||||
CMD ["node", "server.js"]
|
||||
1
docs/changelog.d/feature-homepage-kustomize.infra.md
Normal file
1
docs/changelog.d/feature-homepage-kustomize.infra.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
Replace Homepage Helm chart (jameswynn/homepage v2.1.0, pinned at app v1.2.0) with plain kustomize manifests and a custom Dockerfile built from upstream v1.10.1. Gives full version control and matches the pattern used by other blumeops services.
|
||||
|
|
@ -45,11 +45,11 @@ services:
|
|||
upstream-source: https://github.com/binwiederhier/ntfy/releases
|
||||
|
||||
- name: homepage
|
||||
type: argocd
|
||||
last-reviewed: null
|
||||
current-version: null
|
||||
type: hybrid
|
||||
last-reviewed: 2026-02-19
|
||||
current-version: "v1.10.1"
|
||||
upstream-source: https://github.com/gethomepage/homepage/releases
|
||||
notes: Deployed via Helm chart
|
||||
notes: Custom container, kustomize manifests
|
||||
|
||||
- name: nvidia-device-plugin
|
||||
type: argocd
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue