diff --git a/kubernetes/lianalabs/apps/labs/homepage/app/resources/services.yaml b/kubernetes/lianalabs/apps/labs/homepage/app/resources/services.yaml index d9fba7e..24ab465 100644 --- a/kubernetes/lianalabs/apps/labs/homepage/app/resources/services.yaml +++ b/kubernetes/lianalabs/apps/labs/homepage/app/resources/services.yaml @@ -1,2 +1,58 @@ --- +- Network: + # - OPNsense: + # href: https://opnsense.${SECRET_OLD_DOMAIN} + # siteMonitor: https://opnsense.${SECRET_OLD_DOMAIN} + # icon: opnsense + # description: RSS feed + # widget: + # type: opnsense + # url: https://opnsense.${SECRET_OLD_DOMAIN} + # key: "{{HOMEPAGE_VAR_OPNSENSE_TOKEN}}" - Services: + - Miniflux: + href: https://rss.${SECRET_INTERNAL_DOMAIN} + siteMonitor: http://miniflux.labs.svc.cluster.local/healthcheck + icon: miniflux + description: RSS feed + widget: + type: miniflux + url: http://miniflux.labs.svc.cluster.local + key: "{{HOMEPAGE_VAR_MINIFLUX_TOKEN}}" +- Media: + - Jellyfin: + href: https://${SECRET_MEDIA_DOMAIN} + siteMonitor: https://${SECRET_MEDIA_DOMAIN} + icon: jellyfin + description: Media streaming + widget: + type: jellyfin + url: https://${SECRET_MEDIA_DOMAIN} + key: "{{HOMEPAGE_VAR_JELLYFIN_TOKEN}}" + - Jellyfin: + href: https://jellyseerr.${SECRET_MEDIA_DOMAIN} + siteMonitor: https://jellyseerr.${SECRET_MEDIA_DOMAIN} + icon: jellyseerr + description: Media requests + widget: + type: jellyseerr + url: https://jellyseerr.${SECRET_MEDIA_DOMAIN} + key: "{{HOMEPAGE_VAR_JELLYSEERR_TOKEN}}" + - Sonarr: + href: https://sonarr.${SECRET_MEDIA_DOMAIN} + siteMonitor: https://sonarr.${SECRET_MEDIA_DOMAIN} + icon: sonarr + description: TV + widget: + type: sonarr + url: https://sonarr.${SECRET_MEDIA_DOMAIN} + key: "{{HOMEPAGE_VAR_SONARR_TOKEN}}" + - Radarr: + href: https://radarr.${SECRET_MEDIA_DOMAIN} + siteMonitor: https://radarr.${SECRET_MEDIA_DOMAIN} + icon: radarr + description: Movies + widget: + type: radarr + url: https://radarr.${SECRET_MEDIA_DOMAIN} + key: "{{HOMEPAGE_VAR_RADARR_TOKEN}}" diff --git a/kubernetes/lianalabs/apps/labs/kustomization.yaml b/kubernetes/lianalabs/apps/labs/kustomization.yaml index 46d4ffe..30fa837 100644 --- a/kubernetes/lianalabs/apps/labs/kustomization.yaml +++ b/kubernetes/lianalabs/apps/labs/kustomization.yaml @@ -12,3 +12,4 @@ resources: - ./it-tools/ks.yaml - ./cyberchef/ks.yaml - ./redlib/ks.yaml + - ./linkding/ks.yaml diff --git a/kubernetes/lianalabs/apps/labs/linkding/app/helmrelease.yaml b/kubernetes/lianalabs/apps/labs/linkding/app/helmrelease.yaml new file mode 100644 index 0000000..2808b6d --- /dev/null +++ b/kubernetes/lianalabs/apps/labs/linkding/app/helmrelease.yaml @@ -0,0 +1,122 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/bjw-s/helm-charts/main/charts/other/app-template/schemas/helmrelease-helm-v2.schema.json +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: &app linkding +spec: + interval: 30m + chart: + spec: + chart: app-template + version: 3.5.1 + interval: 30m + sourceRef: + kind: HelmRepository + name: bjw-s + namespace: flux-system + install: + remediation: + retries: 3 + upgrade: + cleanupOnFail: true + remediation: + strategy: rollback + retries: 3 + values: + controllers: + linkding: + replicas: 1 + strategy: RollingUpdate + annotations: + reloader.stakater.com/auto: "true" + initContainers: + init-db: + image: + repository: ghcr.io/onedr0p/postgres-init + tag: 16 + # https://github.com/onedr0p/containers/blob/main/apps/postgres-init/entrypoint.sh + env: + INIT_POSTGRES_HOST: &dbHost postgres-1-rw.database.svc.cluster.local + INIT_POSTGRES_DBNAME: &dbName linkding + INIT_POSTGRES_USER: + valueFrom: + secretKeyRef: + name: &secret linkding-secret + key: LD_DB_USER + INIT_POSTGRES_PASS: + valueFrom: + secretKeyRef: + name: *secret + key: LD_DB_PASSWORD + INIT_POSTGRES_SUPER_PASS: + valueFrom: + secretKeyRef: + name: cloudnative-pg-secret + key: password + containers: + app: + image: + repository: docker.io/sissbruecker/linkding + tag: 1.36.0-plus-alpine + env: + LD_DB_ENGINE: postgres + LD_DB_DATABASE: *dbName + LD_DB_HOST: *dbHost + LD_DB_PORT: 5432 + envFrom: + - secretRef: + name: *secret + probes: + liveness: &probes + enabled: true + custom: true + spec: + httpGet: + path: /health + port: &port 9090 + initialDelaySeconds: 10 + periodSeconds: 5 + timeoutSeconds: 10 + failureThreshold: 30 + readiness: *probes + resources: + requests: + cpu: 12m + memory: 512M + limits: + # For HTML snapshot spike + memory: 4Gi + service: + app: + controller: linkding + ports: + http: + port: *port + ingress: + app: + className: traefik + annotations: + gethomepage.dev/enabled: "true" + gethomepage.dev/group: Services + gethomepage.dev/name: Linkding + gethomepage.dev/description: Bookmark collection + gethomepage.dev/icon: linkding + hosts: + - host: &host "bookmarks.${SECRET_INTERNAL_DOMAIN}" + paths: + - path: / + service: + identifier: app + port: http + tls: + - secretName: linkding-tls + hosts: [*host] + persistence: + data: + storageClass: local-nvme + accessMode: ReadWriteOnce + size: 2Gi + retain: true + globalMounts: + - path: /data diff --git a/kubernetes/lianalabs/apps/labs/linkding/app/kustomization.yaml b/kubernetes/lianalabs/apps/labs/linkding/app/kustomization.yaml new file mode 100644 index 0000000..957a5ad --- /dev/null +++ b/kubernetes/lianalabs/apps/labs/linkding/app/kustomization.yaml @@ -0,0 +1,8 @@ +--- +# yaml-language-server: $schema=https://json.schemastore.org/kustomization +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - ./secret.sops.yaml + - ../../../database/cloudnative-pg/app/secret.sops.yaml + - ./helmrelease.yaml diff --git a/kubernetes/lianalabs/apps/labs/linkding/app/secret.sops.yaml b/kubernetes/lianalabs/apps/labs/linkding/app/secret.sops.yaml new file mode 100644 index 0000000..5fbd056 --- /dev/null +++ b/kubernetes/lianalabs/apps/labs/linkding/app/secret.sops.yaml @@ -0,0 +1,31 @@ +# yamllint disable +kind: Secret +apiVersion: v1 +type: Opaque +metadata: + name: linkding-secret +stringData: + LD_DB_USER: ENC[AES256_GCM,data:2NR7rpKxCWQ=,iv:Dvr4taqtPgZRcS3myDyoIjpztOcD01EU7CJyCjuFtb8=,tag:rCtEVshvX/9AvfagmUdYeg==,type:str] + LD_DB_PASSWORD: ENC[AES256_GCM,data:P1Z0RjkZ0l5W8RCODfFojVGIkf8z1O05hpfNThbywnYyT9YR0o6t95ED,iv:7zhSIhfPtT/LnofNEPJdxeIjM30loYD2c4gVDLWCm6g=,tag:6CTRcp0zKFJBO/JEZIuRAA==,type:str] + LD_SUPERUSER_NAME: ENC[AES256_GCM,data:RS+Xenw=,iv:TcPjHWBMfMVTBPQVYlEO1wom7m0Md9wtbYIsO2WxZJA=,tag:0vNxW+mwWaUlFC9YT/NsOQ==,type:str] + LD_SUPERUSER_PASSWORD: ENC[AES256_GCM,data:oQmsx+WsRlurukhgTLL6NYMhEysnGINvnFFPGOusHzE=,iv:h1q2L7jKRb5P/XAq4JBG0qwVYn4GoUnJM79ncD3ZofU=,tag:ZAn2Uqay/LatpNGV1v6IBg==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age19nu7uf8dageqlmzk23x7vl24fpn0l7cq20l3l4xxf2sk2xd5h98qss437p + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAyOS9Ga1R0UTZpSjVkUGI4 + Z21NN25BTDJnQWRTYlBCckJJYzhXZjNHNXg4CnY3N0pYK3IxNXVTVTF2L2orMzA0 + Tm5qVlpIWlpRaHdpUmNvSzNKRmdlZ1EKLS0tIE1UdjM1ek9PanUybDk3Mkc5YUFU + VjVueWY3NFJPbE1HTWxyby81ZUIxaWMKvJP9CmnlbuFOXpQboOzPmSvCVuLUFYci + 8bCX0J8TEwSgctQgZIcZXO/vSUdfQwfcyoNG3S2gCyoZK3hErVPI+A== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2024-11-21T23:06:07Z" + mac: ENC[AES256_GCM,data:lRDim8ZhYF32Sqbu9p6XMTilzI9ru9vZFKynu+tg4BgxuHvHdCuAwrEVrRpeJScgZxqon+7SmFexhSZyZAiFvbixjey6ioeA52mwredxUlfQlbaw9kFH5ic+ixB01DS1ESCYHQxUPQff+Zpo1rMgbSk9/gJhdMD9jaOcvzHjBxk=,iv:iKTYPYjLRY8/w9Vk522n8h/zPfBVU1XNW4eYcqalwag=,tag:WT4vngyxA1kcVKWoh2WGuQ==,type:str] + pgp: [] + encrypted_regex: ^(data|stringData)$ + version: 3.9.1 diff --git a/kubernetes/lianalabs/apps/labs/linkding/ks.yaml b/kubernetes/lianalabs/apps/labs/linkding/ks.yaml new file mode 100644 index 0000000..2731695 --- /dev/null +++ b/kubernetes/lianalabs/apps/labs/linkding/ks.yaml @@ -0,0 +1,26 @@ +--- +# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/kustomize.toolkit.fluxcd.io/kustomization_v1.json +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: &app linkding + namespace: flux-system +spec: + targetNamespace: labs + commonMetadata: + labels: + app.kubernetes.io/name: *app + dependsOn: + - name: cloudnative-pg + path: ./kubernetes/lianalabs/apps/labs/linkding/app + prune: true + sourceRef: + kind: GitRepository + name: k8s-gitops + wait: false + interval: 30m + retryInterval: 1m + timeout: 5m + postBuild: + substitute: + APP: *app diff --git a/kubernetes/lianalabs/apps/labs/redlib/app/helmrelease.yaml b/kubernetes/lianalabs/apps/labs/redlib/app/helmrelease.yaml index 12e1d3c..a145e4a 100644 --- a/kubernetes/lianalabs/apps/labs/redlib/app/helmrelease.yaml +++ b/kubernetes/lianalabs/apps/labs/redlib/app/helmrelease.yaml @@ -73,7 +73,7 @@ spec: annotations: cert-manager.io/cluster-issuer: "letsencrypt-production" gethomepage.dev/enabled: "true" - gethomepage.dev/group: Services + gethomepage.dev/group: Tools gethomepage.dev/name: Redlib gethomepage.dev/description: Reddit client with privacy features gethomepage.dev/icon: reddit diff --git a/kubernetes/lianalabs/apps/media/kustomization.yaml b/kubernetes/lianalabs/apps/media/kustomization.yaml index 51fca06..5e6d92a 100644 --- a/kubernetes/lianalabs/apps/media/kustomization.yaml +++ b/kubernetes/lianalabs/apps/media/kustomization.yaml @@ -4,3 +4,4 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - ./namespace.yaml + - ./piped/ks.yaml diff --git a/kubernetes/lianalabs/apps/media/piped/app/helmrelease.yaml b/kubernetes/lianalabs/apps/media/piped/app/helmrelease.yaml new file mode 100644 index 0000000..32088eb --- /dev/null +++ b/kubernetes/lianalabs/apps/media/piped/app/helmrelease.yaml @@ -0,0 +1,111 @@ +--- +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: &app piped + namespace: media +spec: + interval: 30m + chart: + spec: + chart: piped + version: 6.0.4 + sourceRef: + kind: HelmRepository + name: piped + namespace: flux-system + install: + createNamespace: true + remediation: + retries: 3 + upgrade: + cleanupOnFail: true + crds: Skip + remediation: + strategy: rollback + retries: 3 + values: + postgresql: + enabled: false + frontend: + image: + repository: "docker.io/1337kavin/piped-frontend" + tag: "latest" + pullPolicy: Always + env: + BACKEND_HOSTNAME: &api api.yt.${SECRET_INTERNAL_DOMAIN} + TZ: ${TIMEZONE} + + backend: + image: + repository: docker.io/1337kavin/piped + pullPolicy: "Always" + initContainers: + 01-init-db: + image: + repository: ghcr.io/onedr0p/postgres-init + tag: "16" + imagePullPolicy: IfNotPresent + envFrom: + - secretRef: + name: &secret piped-secret + podAnnotations: + configmap.reloader.stakater.com/reload: "piped-backend-config" + env: + TZ: ${TIMEZONE} + config: + PORT: 8080 + HTTP_WORKERS: 4 + PROXY_PART: &proxy https://proxy.yt.${SECRET_INTERNAL_DOMAIN} + # DISABLE_REGISTRATION: false + database: + secret: + name: *secret + connection_url: CONNECTION_URL + username: INIT_POSTGRES_USER + password: INIT_POSTGRES_PASS + ingress: + main: + enabled: true + ingressClassName: traefik + annotations: + cert-manager.io/cluster-issuer: "letsencrypt-production" + gethomepage.dev/enabled: "true" + gethomepage.dev/group: Tools + gethomepage.dev/name: Piped + gethomepage.dev/description: YouTube client + gethomepage.dev/icon: mdi-youtube + hosts: + - host: &host yt.${SECRET_INTERNAL_DOMAIN} + paths: + - path: "/" + tls: + - secretName: piped-frontend-tls + hosts: + - *host + backend: + enabled: true + ingressClassName: traefik + annotations: + hajimari.io/enable: "false" + hosts: + - host: *api + paths: + - path: "/" + tls: + - secretName: piped-api-tls + hosts: + - *api + ytproxy: + enabled: true + ingressClassName: traefik + annotations: + hajimari.io/enable: "false" + hosts: + - host: &proxy proxy.yt.${SECRET_INTERNAL_DOMAIN} + paths: + - path: "/" + tls: + - secretName: piped-proxy-tls + hosts: + - *proxy diff --git a/kubernetes/lianalabs/apps/media/piped/app/kustomization.yaml b/kubernetes/lianalabs/apps/media/piped/app/kustomization.yaml new file mode 100644 index 0000000..5ae7a45 --- /dev/null +++ b/kubernetes/lianalabs/apps/media/piped/app/kustomization.yaml @@ -0,0 +1,8 @@ +--- +# yaml-language-server: $schema=https://json.schemastore.org/kustomization +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - ./secret.sops.yaml + - ./helmrelease.yaml + - ../../../database/cloudnative-pg/app/secret.sops.yaml diff --git a/kubernetes/lianalabs/apps/media/piped/app/secret.sops.yaml b/kubernetes/lianalabs/apps/media/piped/app/secret.sops.yaml new file mode 100644 index 0000000..a89c9c0 --- /dev/null +++ b/kubernetes/lianalabs/apps/media/piped/app/secret.sops.yaml @@ -0,0 +1,31 @@ +# yamllint disable +kind: Secret +apiVersion: v1 +type: Opaque +metadata: + name: piped-secret +stringData: + INIT_POSTGRES_USER: ENC[AES256_GCM,data:PClMpCo=,iv:WswYV4g8v6yC9BBc+mRwqaW7uBlLYpB/IQP0/9Xa8uU=,tag:/4UO3l/iYn2G6tWsd/J7EA==,type:str] + INIT_POSTGRES_PASS: null + DATABASE_URL: ENC[AES256_GCM,data:qubN/jEvkx3VtuYvNJcihullUJWUYmISs2/vlQOSqQLhmq2fTbXLIb1loKFmpt9XK/za17EZRKh/cAHOEePR1nvpXcflULyMf89i8+7P0UxtOtVmEJEHDaCpGw==,iv:V5cfvsj12SVUjwZsNjM4RpMB7pnWUFr3ncfT6vNeDoU=,tag:HXUs60lmP9zanDABDJxRlA==,type:str] + CONNECTION_URL: ENC[AES256_GCM,data:Ml4MIn1tcLLbd9woL0wVPAem/MvGq5ZeUVo4XFeJt7iZsZxZInNk4ZlhP3hNQD7Tp4qoQvXatA6YToe6,iv:bFZSz0cFBnzCU56g12Usx6gfm9NHrxnPikVQPuUEI4A=,tag:Fr3kgiADMHUDDeAILoyUDQ==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age19nu7uf8dageqlmzk23x7vl24fpn0l7cq20l3l4xxf2sk2xd5h98qss437p + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBORHlmdTRudXlhQ0xwb1hv + QVZJMFhPUWJmOU5xZXdwbFhVdWxJTTdxSUdJCjdxYTVZU2ltTFMySkV6cFdqd0hH + VmlYUTRtQmh4L3dUb1gzNDY5Zlk3aG8KLS0tIG83ZVpwQk5pMSswMTRHczk3NTdF + YkI2MTZLamFIOTUyOUx2ZlZOVGw3b3cKzgoAlWBy9DBWFt3SJ6IJa5d1haTNEEmP + bY3ypNKP1yj0MFLDTfqnI3HtE8yRi93z551b2jFy8cViVUXlWzMWtA== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2024-11-19T00:27:03Z" + mac: ENC[AES256_GCM,data:A1H/pyFlWoypT6NA69pUNDTxN3oI/pWuSQjmcvqytfDW/d9B1wbT2JuCa7KZu5P6FUC2cMk7y7gU8rj+g3WF6vPcGQm3bPXJJ0OX2ingztf/041gkZwooxaQTqOpZbsnbpDl3vGI1gnIwQuW18XqFVye34LxgdMmqf/9HsxQYPQ=,iv:KpBhyabXFD67gL33H7xGu0bzrZAkqMmIvMV/GkLbD5g=,tag:toFR3GZiRtZoPR4nPrph6g==,type:str] + pgp: [] + encrypted_regex: ^(data|stringData)$ + version: 3.9.1 diff --git a/kubernetes/lianalabs/apps/media/piped/ks.yaml b/kubernetes/lianalabs/apps/media/piped/ks.yaml new file mode 100644 index 0000000..5cd2035 --- /dev/null +++ b/kubernetes/lianalabs/apps/media/piped/ks.yaml @@ -0,0 +1,26 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: &app piped + namespace: flux-system +spec: + targetNamespace: media + commonMetadata: + labels: + app.kubernetes.io/name: *app + dependsOn: + - name: traefik + path: ./kubernetes/lianalabs/apps/media/piped/app + prune: true + sourceRef: + kind: GitRepository + name: k8s-gitops + wait: false + interval: 30m + retryInterval: 1m + timeout: 5m + postBuild: + substitute: + APP: *app diff --git a/kubernetes/lianalabs/flux/repositories/helm/piped.yaml b/kubernetes/lianalabs/flux/repositories/helm/piped.yaml new file mode 100644 index 0000000..355c832 --- /dev/null +++ b/kubernetes/lianalabs/flux/repositories/helm/piped.yaml @@ -0,0 +1,10 @@ +--- +# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/helmrepository_v1.json +apiVersion: source.toolkit.fluxcd.io/v1 +kind: HelmRepository +metadata: + name: piped + namespace: flux-system +spec: + interval: 1h + url: https://helm.piped.video