---
title: Kubernetes Installation
description: Install on Kubernetes
---

## Install with Helm

There is an [unofficial helm chart](https://github.com/jameswynn/helm-charts/tree/main/charts/homepage) that creates all the necessary manifests, including the service account and RBAC entities necessary for service discovery.

```sh
helm repo add jameswynn https://jameswynn.github.io/helm-charts
helm install homepage jameswynn/homepage -f values.yaml
```

The helm chart allows for all the configurations to be inlined directly in your `values.yaml`:

```yaml
config:
    bookmarks:
        - Developer:
              - Github:
                    - abbr: GH
                      href: https://github.com/
    services:
        - My First Group:
              - My First Service:
                    href: http://localhost/
                    description: Homepage is awesome

        - My Second Group:
              - My Second Service:
                    href: http://localhost/
                    description: Homepage is the best

        - My Third Group:
              - My Third Service:
                    href: http://localhost/
                    description: Homepage is 😎
    widgets:
        # show the kubernetes widget, with the cluster summary and individual nodes
        - kubernetes:
              cluster:
                  show: true
                  cpu: true
                  memory: true
                  showLabel: true
                  label: "cluster"
              nodes:
                  show: true
                  cpu: true
                  memory: true
                  showLabel: true
        - search:
              provider: duckduckgo
              target: _blank
    kubernetes:
        mode: cluster
    settings:

# The service account is necessary to allow discovery of other services
serviceAccount:
    create: true
    name: homepage

# This enables the service account to access the necessary resources
enableRbac: true

ingress:
    main:
        enabled: true
        annotations:
            # Example annotations to add Homepage to your Homepage!
            gethomepage.dev/enabled: "true"
            gethomepage.dev/name: "Homepage"
            gethomepage.dev/description: "Dynamically Detected Homepage"
            gethomepage.dev/group: "Dynamic"
            gethomepage.dev/icon: "homepage.png"
        hosts:
            - host: homepage.example.com
              paths:
                  - path: /
                    pathType: Prefix
```

## Install with Kubernetes Manifests

If you don't want to use the unofficial Helm chart, you can also create your own Kubernetes manifest(s) and apply them with `kubectl apply -f filename.yaml`.

Here's a working example of the resources you need:

#### ServiceAccount

```yaml
apiVersion: v1
kind: ServiceAccount
metadata:
    name: homepage
    namespace: default
    labels:
        app.kubernetes.io/name: homepage
secrets:
    - name: homepage
```

#### Secret

```yaml
apiVersion: v1
kind: Secret
type: kubernetes.io/service-account-token
metadata:
    name: homepage
    namespace: default
    labels:
        app.kubernetes.io/name: homepage
    annotations:
        kubernetes.io/service-account.name: homepage
```

#### ConfigMap

```yaml
apiVersion: v1
kind: ConfigMap
metadata:
    name: homepage
    namespace: default
    labels:
        app.kubernetes.io/name: homepage
data:
    kubernetes.yaml: |
        mode: cluster
    settings.yaml: ""
    #settings.yaml: |
    #  providers:
    #    longhorn:
    #      url: https://longhorn.my.network
    custom.css: ""
    custom.js: ""
    bookmarks.yaml: |
        - Developer:
            - Github:
                - abbr: GH
                  href: https://github.com/
    services.yaml: |
        - My First Group:
            - My First Service:
                href: http://localhost/
                description: Homepage is awesome

        - My Second Group:
            - My Second Service:
                href: http://localhost/
                description: Homepage is the best

        - My Third Group:
            - My Third Service:
                href: http://localhost/
                description: Homepage is 😎
    widgets.yaml: |
        - kubernetes:
            cluster:
              show: true
              cpu: true
              memory: true
              showLabel: true
              label: "cluster"
            nodes:
              show: true
              cpu: true
              memory: true
              showLabel: true
        - resources:
            backend: resources
            expanded: true
            cpu: true
            memory: true
        - search:
            provider: duckduckgo
            target: _blank
    docker.yaml: ""
```

#### ClusterRole and ClusterRoleBinding

```yaml
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.containo.us
      resources:
          - ingressroutes
      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: default
```

#### Service

```yaml
apiVersion: v1
kind: Service
metadata:
    name: homepage
    namespace: default
    labels:
        app.kubernetes.io/name: homepage
    annotations:
spec:
    type: ClusterIP
    ports:
        - port: 3000
          targetPort: http
          protocol: TCP
          name: http
    selector:
        app.kubernetes.io/name: homepage
```

#### Deployment

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
    name: homepage
    namespace: default
    labels:
        app.kubernetes.io/name: homepage
spec:
    revisionHistoryLimit: 3
    replicas: 1
    strategy:
        type: RollingUpdate
    selector:
        matchLabels:
            app.kubernetes.io/name: homepage
    template:
        metadata:
            labels:
                app.kubernetes.io/name: homepage
        spec:
            serviceAccountName: homepage
            automountServiceAccountToken: true
            dnsPolicy: ClusterFirst
            enableServiceLinks: true
            containers:
                - name: homepage
                  image: "ghcr.io/benphelps/homepage:latest"
                  imagePullPolicy: Always
                  ports:
                      - name: http
                        containerPort: 3000
                        protocol: TCP
                  volumeMounts:
                      - name: homepage-config
                        mountPath: /app/config
                      - name: logs
                        mountPath: /app/config/logs
            volumes:
                - name: homepage-config
                  configMap:
                      name: homepage
                - name: logs
                  emptyDir: {}
```

#### Ingress

```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
    name: homepage
    namespace: default
    labels:
        app.kubernetes.io/name: homepage
    annotations:
        gethomepage.dev/description: Dynamically Detected Homepage
        gethomepage.dev/enabled: "true"
        gethomepage.dev/group: Cluster Management
        gethomepage.dev/icon: homepage.png
        gethomepage.dev/name: Homepage
spec:
    rules:
        - host: "homepage.my.network"
          http:
              paths:
                  - path: "/"
                    pathType: Prefix
                    backend:
                        service:
                            name: homepage
                            port:
                                number: 3000
```
