Homepage Prerequisites This guide assumes you have the following prerequisites in place:
Homepage A modern, fully static, fast, secure fully proxied, highly customizable application dashboard with integrations for over 100 services and translations into multiple languages. Easily configured via YAML files or through docker label discovery.
Installation Create the following directory structure for Homepage:homepage/
├── secret.yml
├── clusterole.yml
├── cm.yml
├── ingress.yml
├── pvc.yml
├── svc-account.yml
├── svc-account-token.yml
├── svc.yml
└── homepage.yml This secret will contain all api-keys and passwords for the services you want to integrate with Homepage. You can use the following template for your secret-tmp.yml:apiVersion : v1
kind : Secret
metadata :
name : homepage-secrets
namespace : monitoring
type : Opaque
data :
BAZARR_API_KEY : <base64-encoded-api-key>
SONARR_API_KEY : <base64-encoded-password>
# Add more services as needed Encrypt the secret using Sealed Secrets like so:kubeseal -o yaml < secret-tmp.yml > secret.yml && \
rm secret-tmp.yml The clusterole.yml file will define the necessary permissions for Homepage to access the Kubernetes API. You can use the following template:---
apiVersion : rbac.authorization.k8s.io/v1
kind : ClusterRole
metadata :
name : homepage
labels :
app.kubernetes.io/name : homepage
rules :
- apiGroups :
- ""
resources :
- namespaces
- pods
- nodes
verbs :
- get
- list
- apiGroups :
- extensions
- networking.k8s.io
resources :
- ingresses
verbs :
- get
- list
- apiGroups :
- traefik.io
resources :
- ingressroutes
verbs :
- get
- list
- apiGroups :
- gateway.networking.k8s.io
resources :
- httproutes
- gateways
verbs :
- get
- list
- apiGroups :
- metrics.k8s.io
resources :
- nodes
- pods
verbs :
- get
- list
---
apiVersion : rbac.authorization.k8s.io/v1
kind : ClusterRoleBinding
metadata :
name : homepage
labels :
app.kubernetes.io/name : homepage
roleRef :
apiGroup : rbac.authorization.k8s.io
kind : ClusterRole
name : homepage
subjects :
- kind : ServiceAccount
name : homepage
namespace : monitoring The cm.yml file will contain the configuration for Homepage, including the services you want to integrate. This is an example configuration:---
apiVersion : v1
kind : ConfigMap
metadata :
name : homepage
namespace : monitoring
labels :
app.kubernetes.io/name : homepage
data :
docker.yaml : |
""
bookmarks.yaml : |
""
custom.css : |
""
custom.js : |
""
kubernetes.yaml : |
mode: cluster
widgets.yaml : |
- kubernetes:
cluster:
show: true
cpu: true
memory: true
showLabel: true
label: "k3s-cluster"
nodes:
show: true
- longhorn:
expanded: true
total: true
labels: true
nodes: false
settings.yaml : |
providers:
longhorn:
url: http://longhorn-frontend.longhorn-system.svc.cluster.local:80
services.yaml : |
- Apps:
- Sonarr:
href: https://sonarr.example.com
description: series
icon: sonarr.png
namespace: arr-stack
podSelector: app=sonarr
app: sonarr
widget:
type: sonarr
url: http://sonarr-service.arr-stack.svc.cluster.local:8989
key: "${SONARR_API_KEY}"
- Bazarr:
href: https://bazarr.example.com
description: subtitles
icon: bazarr.png
namespace: arr-stack
podSelector: app=bazarr
app: bazarr
widget:
type: bazarr
url: http://bazarr-service.arr-stack.svc.cluster.local:6767
key: "${BAZARR_API_KEY}" Add the following to ingress.yml:---
apiVersion : networking.k8s.io/v1
kind : Ingress
metadata :
name : homepage-ingress
namespace : monitoring
annotations :
cert-manager.io/cluster-issuer : letsencrypt-cloudflare
traefik.ingress.kubernetes.io/router.middlewares : tools-authelia@kubernetescrd
traefik.ingress.kubernetes.io/router.entrypoints : websecure
spec :
ingressClassName : traefik
tls :
- hosts :
- home.example.com
secretName : homepage-tls
rules :
- host : home.example.com
http :
paths :
- path : /
pathType : Prefix
backend :
service :
name : homepage-service
port :
number : 3000 The pvc.yml file will define the persistent volume claim for Homepage images.---
apiVersion : v1
kind : PersistentVolumeClaim
metadata :
name : homepage-longhorn
namespace : monitoring
spec :
accessModes :
- ReadWriteOnce
volumeMode : Filesystem
resources :
requests :
storage : 100Mi
storageClassName : longhorn The svc-account.yml file will create a service account for Homepage:---
apiVersion : v1
kind : ServiceAccount
metadata :
name : homepage
namespace : monitoring
labels :
app.kubernetes.io/name : homepage
secrets :
- name : homepage The svc-account-token.yml file will create a secret for the service account token:---
apiVersion : v1
kind : Secret
type : kubernetes.io/service-account-token
metadata :
name : homepage
namespace : monitoring
labels :
app.kubernetes.io/name : homepage
annotations :
kubernetes.io/service-account.name : homepage Create a svc.yml file to define the service for Homepage:---
apiVersion : v1
kind : Service
metadata :
name : homepage-service
namespace : monitoring
spec :
selector :
app.kubernetes.io/name : homepage
ports :
- port : 3000
targetPort : 3000 Finally, the homepage.yml file will define the deployment for Homepage. This deployment will substitute the api-keys from the secret into the configmap.---
apiVersion : apps/v1
kind : Deployment
metadata :
name : homepage
namespace : monitoring
labels :
app.kubernetes.io/name : homepage
spec :
revisionHistoryLimit : 3
replicas : 1
strategy :
type : Recreate
selector :
matchLabels :
app.kubernetes.io/name : homepage
template :
metadata :
labels :
app.kubernetes.io/name : homepage
spec :
serviceAccountName : homepage
automountServiceAccountToken : true
enableServiceLinks : true
initContainers :
- name : substitute-config
image : alpine
envFrom :
- secretRef :
name : homepage-secrets
command :
- "sh"
- "-c"
- apk add gettext && envsubst < /mnt/init/services.yaml > /mnt/services.yaml
volumeMounts :
- name : homepage-config
mountPath : /mnt/init/services.yaml
subPath : services.yaml
- name : tmp
mountPath : /mnt
subPath : services.yaml
containers :
- name : homepage
image : "ghcr.io/gethomepage/homepage:v1.10.1"
imagePullPolicy : IfNotPresent
env :
- name : HOMEPAGE_ALLOWED_HOSTS
value : "home.example.com"
ports :
- name : http
containerPort : 3000
protocol : TCP
volumeMounts :
- mountPath : /app/config/custom.js
name : homepage-config
subPath : custom.js
- mountPath : /app/config/custom.css
name : homepage-config
subPath : custom.css
- mountPath : /app/config/bookmarks.yaml
name : homepage-config
subPath : bookmarks.yaml
- mountPath : /app/config/docker.yaml
name : homepage-config
subPath : docker.yaml
- mountPath : /app/config/kubernetes.yaml
name : homepage-config
subPath : kubernetes.yaml
- mountPath : /app/config
name : tmp
subPath : services.yaml
- mountPath : /app/config/settings.yaml
name : homepage-config
subPath : settings.yaml
- mountPath : /app/config/widgets.yaml
name : homepage-config
subPath : widgets.yaml
- mountPath : /app/config/logs
name : logs
- mountPath : /app/public/images
name : images
volumes :
- name : homepage-config
configMap :
name : homepage
- name : images
persistentVolumeClaim :
claimName : homepage-longhorn
- name : logs
emptyDir : {}
- name : tmp
emptyDir : {} Commit and push all the files to your repository. Flux will automatically deploy Homepage to your cluster.