diff --git a/argocd-apps/homelab.yaml b/argocd-apps/homelab.yaml index 108a89c..6a0ba50 100644 --- a/argocd-apps/homelab.yaml +++ b/argocd-apps/homelab.yaml @@ -658,3 +658,25 @@ spec: - CreateNamespace=true - PruneLast=true --- +# Homepage +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: homepage + namespace: argocd + finalizers: + - resources-finalizer.argocd.argoproj.io +spec: + project: homelab + source: + repoURL: https://gitea.dooplex.hu/admin/homelab-manifests.git + targetRevision: main + path: homepage-system + destination: + server: https://kubernetes.default.svc + namespace: homepage-system + syncPolicy: + syncOptions: + - CreateNamespace=true + - PruneLast=true +--- diff --git a/homepage-system/homepage.yaml b/homepage-system/homepage.yaml new file mode 100644 index 0000000..0f3d761 --- /dev/null +++ b/homepage-system/homepage.yaml @@ -0,0 +1,509 @@ +# ============================================================================= +# Homepage - Application Dashboard +# Version: v1.8.0 +# Namespace: homepage-system +# Domain: homepage.dooplex.hu +# Authentication: Authentik Proxy (Forward Auth) +# ============================================================================= +# +# PREREQUISITES - Create in Authentik: +# 1. Create Proxy Provider: +# - Name: homepage-proxy +# - Authorization flow: default-provider-authorization-implicit-consent +# - Mode: Forward auth (single application) +# - External host: https://homepage.dooplex.hu +# +# 2. Create Application: +# - Name: Homepage +# - Slug: homepage +# - Provider: (select the proxy provider created above) +# - Launch URL: https://homepage.dooplex.hu +# +# 3. Create Outpost (or add to existing): +# - Name: homepage-outpost (or use existing proxy outpost) +# - Type: Proxy +# - Applications: Add the Homepage application +# +# After deployment, Authentik will auto-create the outpost deployment. +# Update the ingress auth-url annotation with the correct outpost service name. +# +# ============================================================================= +--- +apiVersion: v1 +kind: Namespace +metadata: + name: homepage-system + labels: + app.kubernetes.io/name: homepage + app.kubernetes.io/instance: homepage +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: homepage + namespace: homepage-system + labels: + app.kubernetes.io/name: homepage + app.kubernetes.io/instance: homepage +secrets: + - name: homepage +--- +apiVersion: v1 +kind: Secret +metadata: + name: homepage + namespace: homepage-system + labels: + app.kubernetes.io/name: homepage + app.kubernetes.io/instance: homepage + annotations: + kubernetes.io/service-account.name: homepage +type: kubernetes.io/service-account-token +--- +# ClusterRole for Homepage to discover services and get cluster metrics +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: homepage + labels: + app.kubernetes.io/name: homepage + app.kubernetes.io/instance: homepage +rules: + # Core resources for service discovery + - apiGroups: [""] + resources: + - namespaces + - pods + - nodes + - services + - endpoints + - configmaps + - secrets + verbs: ["get", "list", "watch"] + # Apps resources for pod discovery + - apiGroups: ["apps"] + resources: + - deployments + - replicasets + - statefulsets + - daemonsets + verbs: ["get", "list", "watch"] + # Networking for ingress discovery + - apiGroups: ["networking.k8s.io"] + resources: + - ingresses + verbs: ["get", "list", "watch"] + # Traefik IngressRoute CRD (if used) + - apiGroups: ["traefik.containo.us", "traefik.io"] + resources: + - ingressroutes + verbs: ["get", "list", "watch"] + # Gateway API (if used) + - apiGroups: ["gateway.networking.k8s.io"] + resources: + - httproutes + - gateways + verbs: ["get", "list", "watch"] + # Metrics + - apiGroups: ["metrics.k8s.io"] + resources: + - nodes + - pods + verbs: ["get", "list", "watch"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: homepage + labels: + app.kubernetes.io/name: homepage + app.kubernetes.io/instance: homepage +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: homepage +subjects: + - kind: ServiceAccount + name: homepage + namespace: homepage-system +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: homepage-config + namespace: homepage-system + labels: + app.kubernetes.io/name: homepage + app.kubernetes.io/instance: homepage +data: + # Kubernetes connection configuration + kubernetes.yaml: | + mode: cluster + ingress: true + + # Global settings + settings.yaml: | + title: Dooplex Dashboard + favicon: https://dooplex.hu/favicon.ico + theme: dark + color: slate + headerStyle: clean + layout: + Infrastructure: + style: row + columns: 4 + Media: + style: row + columns: 4 + Productivity: + style: row + columns: 3 + Monitoring: + style: row + columns: 3 + providers: + longhorn: + url: https://longhorn.home + + # Services configuration - customize as needed + services.yaml: | + - Infrastructure: + - ArgoCD: + icon: argocd.png + href: https://argocd.dooplex.hu + description: GitOps Deployment + namespace: argocd + app: argocd-server + - Authentik: + icon: authentik.png + href: https://authentik.dooplex.hu + description: Identity Provider + - Longhorn: + icon: longhorn.png + href: https://longhorn.home + description: Storage Management + - Gitea: + icon: gitea.png + href: https://gitea.dooplex.hu + description: Git Repository + + - Media: + - Plex: + icon: plex.png + href: https://plex.dooplex.hu + description: Media Server + - Sonarr: + icon: sonarr.png + href: https://sonarr.home + description: TV Shows + widget: + type: sonarr + url: http://sonarr.servarr-system.svc.cluster.local:8989 + key: "{{HOMEPAGE_VAR_SONARR_API_KEY}}" + - Radarr: + icon: radarr.png + href: https://radarr.home + description: Movies + widget: + type: radarr + url: http://radarr.servarr-system.svc.cluster.local:7878 + key: "{{HOMEPAGE_VAR_RADARR_API_KEY}}" + - Prowlarr: + icon: prowlarr.png + href: https://prowlarr.home + description: Indexer Manager + + - Productivity: + - Nextcloud: + icon: nextcloud.png + href: https://cloud.dooplex.hu + description: Cloud Storage + - Paperless: + icon: paperless-ngx.png + href: https://paperless.dooplex.hu + description: Document Management + - Vaultwarden: + icon: bitwarden.png + href: https://vaultwarden.dooplex.hu + description: Password Manager + + - Monitoring: + - Grafana: + icon: grafana.png + href: https://grafana.dooplex.hu + description: Dashboards & Metrics + widget: + type: grafana + url: http://grafana.mon-system.svc.cluster.local:3000 + username: "{{HOMEPAGE_VAR_GRAFANA_USER}}" + password: "{{HOMEPAGE_VAR_GRAFANA_PASS}}" + - Prometheus: + icon: prometheus.png + href: https://prometheus.home + description: Metrics Collection + - Uptime Kuma: + icon: uptime-kuma.png + href: https://uptime.dooplex.hu + description: Uptime Monitoring + + # Widgets configuration + widgets.yaml: | + - logo: + icon: https://dooplex.hu/logo.png + - greeting: + text_size: xl + text: "Welcome to Dooplex" + - datetime: + text_size: l + format: + dateStyle: long + timeStyle: short + hour12: false + - kubernetes: + cluster: + show: true + cpu: true + memory: true + showLabel: true + label: "dooplex" + nodes: + show: true + cpu: true + memory: true + showLabel: true + - longhorn: + expanded: true + total: true + labels: true + nodes: false + - search: + provider: duckduckgo + target: _blank + + # Bookmarks + bookmarks.yaml: | + - Developer: + - GitHub: + - abbr: GH + href: https://github.com + icon: github.png + - Gitea: + - abbr: GT + href: https://gitea.dooplex.hu + icon: gitea.png + - Documentation: + - Kubernetes: + - abbr: K8s + href: https://kubernetes.io/docs + icon: kubernetes.png + - ArgoCD: + - abbr: Argo + href: https://argo-cd.readthedocs.io + icon: argocd.png + + # Docker settings (not used in k8s mode) + docker.yaml: "" + + # Custom CSS + custom.css: "" + + # Custom JS + custom.js: "" +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: homepage + namespace: homepage-system + labels: + app.kubernetes.io/name: homepage + app.kubernetes.io/instance: homepage + app.kubernetes.io/version: "v1.8.0" +spec: + replicas: 1 + strategy: + type: RollingUpdate + rollingUpdate: + maxSurge: 1 + maxUnavailable: 0 + selector: + matchLabels: + app.kubernetes.io/name: homepage + app.kubernetes.io/instance: homepage + template: + metadata: + labels: + app.kubernetes.io/name: homepage + app.kubernetes.io/instance: homepage + app.kubernetes.io/version: "v1.8.0" + spec: + serviceAccountName: homepage + automountServiceAccountToken: true + dnsPolicy: ClusterFirst + enableServiceLinks: true + containers: + - name: homepage + image: ghcr.io/gethomepage/homepage:v1.8.0 + imagePullPolicy: IfNotPresent + env: + # Required for external access + - name: HOMEPAGE_ALLOWED_HOSTS + value: "homepage.dooplex.hu,homepage.home" + # Timezone + - name: TZ + value: "Europe/Budapest" + # Optional: Widget API keys (create secret with these if needed) + - name: HOMEPAGE_VAR_SONARR_API_KEY + valueFrom: + secretKeyRef: + name: homepage-secrets + key: sonarr-api-key + - name: HOMEPAGE_VAR_RADARR_API_KEY + valueFrom: + secretKeyRef: + name: homepage-secrets + key: radarr-api-key + - name: HOMEPAGE_VAR_GRAFANA_USER + valueFrom: + secretKeyRef: + name: homepage-secrets + key: grafana-user + - name: HOMEPAGE_VAR_GRAFANA_PASS + valueFrom: + secretKeyRef: + name: homepage-secrets + key: grafana-pass + ports: + - name: http + containerPort: 3000 + protocol: TCP + livenessProbe: + httpGet: + path: /api/healthcheck + port: http + initialDelaySeconds: 30 + periodSeconds: 30 + timeoutSeconds: 10 + failureThreshold: 3 + readinessProbe: + httpGet: + path: /api/healthcheck + port: http + initialDelaySeconds: 10 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 3 + resources: + requests: + cpu: 50m + memory: 128Mi + limits: + cpu: 500m + memory: 512Mi + volumeMounts: + - name: config + mountPath: /app/config/kubernetes.yaml + subPath: kubernetes.yaml + - name: config + mountPath: /app/config/settings.yaml + subPath: settings.yaml + - name: config + mountPath: /app/config/services.yaml + subPath: services.yaml + - name: config + mountPath: /app/config/widgets.yaml + subPath: widgets.yaml + - name: config + mountPath: /app/config/bookmarks.yaml + subPath: bookmarks.yaml + - name: config + mountPath: /app/config/docker.yaml + subPath: docker.yaml + - name: config + mountPath: /app/config/custom.css + subPath: custom.css + - name: config + mountPath: /app/config/custom.js + subPath: custom.js + volumes: + - name: config + configMap: + name: homepage-config +--- +apiVersion: v1 +kind: Service +metadata: + name: homepage + namespace: homepage-system + labels: + app.kubernetes.io/name: homepage + app.kubernetes.io/instance: homepage +spec: + type: ClusterIP + ports: + - name: http + port: 3000 + targetPort: http + protocol: TCP + selector: + app.kubernetes.io/name: homepage + app.kubernetes.io/instance: homepage +--- +# Ingress WITH Authentik proxy authentication +# Update the auth-url annotation with your actual outpost service name after Authentik creates it +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: homepage + namespace: homepage-system + labels: + app.kubernetes.io/name: homepage + app.kubernetes.io/instance: homepage + annotations: + cert-manager.io/cluster-issuer: letsencrypt-prod + external-dns.alpha.kubernetes.io/hostname: homepage.dooplex.hu,homepage.home + nginx.ingress.kubernetes.io/ssl-redirect: "true" + nginx.ingress.kubernetes.io/proxy-buffer-size: "16k" + nginx.ingress.kubernetes.io/proxy-buffers-number: "4" + nginx.ingress.kubernetes.io/proxy-busy-buffers-size: "32k" + # Authentik Forward Auth annotations + # Update 'homepage-outpost' with your actual outpost name + nginx.ingress.kubernetes.io/auth-url: http://ak-outpost-homepage-outpost.auth-system.svc.cluster.local:9000/outpost.goauthentik.io/auth/nginx + nginx.ingress.kubernetes.io/auth-signin: https://homepage.dooplex.hu/outpost.goauthentik.io/start?rd=$escaped_request_uri + nginx.ingress.kubernetes.io/auth-response-headers: Set-Cookie,X-authentik-username,X-authentik-groups,X-authentik-email + nginx.ingress.kubernetes.io/auth-snippet: | + proxy_set_header X-Forwarded-Host $http_host; + # Homepage auto-discovery annotation + gethomepage.dev/enabled: "true" + gethomepage.dev/name: "Homepage" + gethomepage.dev/description: "Application Dashboard" + gethomepage.dev/group: "Infrastructure" + gethomepage.dev/icon: "homepage.png" +spec: + ingressClassName: nginx-internal + rules: + - host: homepage.dooplex.hu + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: homepage + port: + number: 3000 + - host: homepage.home + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: homepage + port: + number: 3000 + tls: + - hosts: + - homepage.dooplex.hu + secretName: homepage-tls +---