1 Commits

Author SHA1 Message Date
0537b70579 Update ghcr.io/immich-app/immich-server Docker tag to v1.135.3
All checks were successful
lint-test-helm / helm-lint (pull_request) Successful in 10s
2025-06-23 22:02:49 +00:00
520 changed files with 28780 additions and 0 deletions

View File

@@ -0,0 +1,67 @@
name: lint-test-docker
on:
push:
branches:
- main
paths:
- 'hosts/**'
- ! 'hosts/archive'
pull_request:
branches:
- main
paths:
- 'hosts/**'
- ! 'hosts/archive'
jobs:
docker-lint:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '22'
- name: Lint Docker Compose
run: |
set -e # Exit immediately if a command exits with a non-zero status.
TARGET_BRANCH="origin/${{ github.base_ref }}"
echo ">> Target branch for diff is: $TARGET_BRANCH"
CHANGED_FILES=$(git diff --name-only "$TARGET_BRANCH" -- 'hosts/**')
echo ">> Found changed files:"
echo "$CHANGED_FILES"
# For each changed file, find its parent chart directory (the one with compose.yaml).
# Then, create a unique list of those directories.
CHANGED_COMPOSE=$(echo "$CHANGED_FILES" | while read -r file; do
dir=$(dirname "$file")
while [[ "$dir" != "." && ! -f "$dir/compose.yaml" ]]; do
dir=$(dirname "$dir")
done
if [[ "$dir" != "." ]]; then
echo "$dir"
fi
done | sort -u)
if [[ -z "$CHANGED_COMPOSE" ]]; then
echo ">> Could not determine changed compose files. This will happen if only files outside a compose file were changed."
exit 0
fi
echo ">> Running dclint on changed compose files:"
echo "$CHANGED_COMPOSE"
echo "$CHANGED_COMPOSE" | while read -r compose; do
echo ">> Linting $compose ..."
npx dclint $compose
done

View File

@@ -0,0 +1,70 @@
name: lint-test-helm
on:
push:
branches:
- main
paths:
- 'clusters/**'
- ! 'clusters/*/archive'
pull_request:
branches:
- main
paths:
- 'clusters/**'
- ! 'clusters/*/archive'
jobs:
helm-lint:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Helm
uses: azure/setup-helm@v4
with:
token: ${{ secrets.GITEA_TOKEN }}
version: latest
- name: Lint Helm Chart
run: |
set -e # Exit immediately if a command exits with a non-zero status.
TARGET_BRANCH="origin/${{ github.base_ref }}"
echo ">> Target branch for diff is: $TARGET_BRANCH"
CHANGED_FILES=$(git diff --name-only "$TARGET_BRANCH" -- 'clusters/**')
echo ">> Found changed files:"
echo "$CHANGED_FILES"
# For each changed file, find its parent chart directory (the one with Chart.yaml).
# Then, create a unique list of those directories.
CHANGED_CHARTS=$(echo "$CHANGED_FILES" | while read -r file; do
dir=$(dirname "$file")
while [[ "$dir" != "." && ! -f "$dir/Chart.yaml" ]]; do
dir=$(dirname "$dir")
done
if [[ "$dir" != "." ]]; then
echo "$dir"
fi
done | sort -u)
if [[ -z "$CHANGED_CHARTS" ]]; then
echo ">> Could not determine changed charts. This could happen if only files outside a chart were changed."
exit 0
fi
echo ">> Running helm lint on changed charts:"
echo "$CHANGED_CHARTS"
echo "$CHANGED_CHARTS" | while read -r chart; do
echo ">> Building dependency for "$chart" ..."
helm dependency build "$chart"
echo ">> Linting $chart..."
helm lint "$chart"
done

View File

@@ -0,0 +1,35 @@
name: process-issues
on:
schedule:
- cron: '@daily'
jobs:
process-issues:
runs-on: ubuntu-latest
steps:
- name: Checkout Python Script
uses: actions/checkout@v4
with:
repository: alexlebens/workflow-scripts
ref: main
token: ${{ secrets.BOT_TOKEN }}
path: scripts
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.13'
- name: Install dependencies
run: pip install requests
- name: Run Script
env:
INSTANCE_URL: ${{ vars.INSTANCE_URL }}
REPOSITORY: ${{ gitea.repository }}
TOKEN: ${{ secrets.BOT_TOKEN }}
STALE_DAYS: 3
STALE_TAG: 'stale'
EXCLUDE_TAG: 'renovate'
run: python ./scripts/scripts/process-issues.py

View File

@@ -0,0 +1,35 @@
name: process-pull-requests
on:
schedule:
- cron: '@daily'
jobs:
process-pull-requests:
runs-on: ubuntu-latest
steps:
- name: Checkout Python Script
uses: actions/checkout@v4
with:
repository: alexlebens/workflow-scripts
ref: main
token: ${{ secrets.BOT_TOKEN }}
path: scripts
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.13'
- name: Install dependencies
run: pip install requests
- name: Run Script
env:
INSTANCE_URL: ${{ vars.INSTANCE_URL }}
REPOSITORY: ${{ gitea.repository }}
TOKEN: ${{ secrets.BOT_TOKEN }}
STALE_DAYS: 3
STALE_TAG: 'stale'
REQUIRED_TAG: 'automerge'
run: python ./scripts/scripts/process-pull-requests.py

View File

@@ -0,0 +1,32 @@
name: renovate
on:
schedule:
- cron: "@hourly"
push:
branches:
- main
workflow_dispatch:
jobs:
renovate:
runs-on: ubuntu-latest
container: ghcr.io/renovatebot/renovate:41
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Renovate
run: renovate
env:
RENOVATE_PLATFORM: gitea
RENOVATE_ENDPOINT: ${{ vars.INSTANCE_URL }}
RENOVATE_REPOSITORIES: alexlebens/infrastructure
RENOVATE_GIT_AUTHOR: Renovate Bot <renovate-bot@alexlebens.net>
LOG_LEVEL: info
RENOVATE_TOKEN: ${{ secrets.RENOVATE_TOKEN }}
RENOVATE_GIT_PRIVATE_KEY: ${{ secrets.RENOVATE_GIT_PRIVATE_KEY }}
RENOVATE_GITHUB_COM_TOKEN: ${{ secrets.RENOVATE_GITHUB_COM_TOKEN }}
RENOVATE_REDIS_URL: ${{ vars.RENOVATE_REDIS_URL }}

15
.pre-commit-config.yaml Normal file
View File

@@ -0,0 +1,15 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v2.3.0
hooks:
- id: end-of-file-fixer
- id: trailing-whitespace
- id: check-added-large-files
- id: check-yaml
exclude: '^.*\/templates\/.*$'
args:
- --multi
- repo: https://github.com/IamTheFij/docker-pre-commit
rev: v2.0.0
hooks:
- id: docker-compose-check

201
LICENSE Normal file
View File

@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

7
README.md Normal file
View File

@@ -0,0 +1,7 @@
# alexlebens.net
GitOps definied infrastrucutre for the alexlebens.net domain.
## License
This project is licensed under the terms of the Apache 2.0 License license.

View File

@@ -0,0 +1,21 @@
apiVersion: v2
name: actual
version: 1.0.0
description: Actual
keywords:
- actual
- budget
home: https://wiki.alexlebens.dev/s/86192f45-94b7-45de-872c-6ef3fec7df5e
sources:
- https://github.com/actualbudget/actual
- https://github.com/actualbudget/actual/pkgs/container/actual
- https://github.com/bjw-s-labs/helm-charts/tree/main/charts/other/app-template
maintainers:
- name: alexlebens
dependencies:
- name: app-template
alias: actual
repository: https://bjw-s-labs.github.io/helm-charts/
version: 4.1.1
icon: https://cdn.jsdelivr.net/gh/selfhst/icons/png/actual-budget.png
appVersion: v25.5.0

View File

@@ -0,0 +1,55 @@
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: actual-data-backup-secret
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: actual-data-backup-secret
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
target:
template:
mergePolicy: Merge
engineVersion: v2
data:
RESTIC_REPOSITORY: "{{ `{{ .BUCKET_ENDPOINT }}` }}/actual/actual-data"
data:
- secretKey: BUCKET_ENDPOINT
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/volsync/restic/config
metadataPolicy: None
property: S3_BUCKET_ENDPOINT
- secretKey: RESTIC_PASSWORD
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/volsync/restic/config
metadataPolicy: None
property: RESTIC_PASSWORD
- secretKey: AWS_DEFAULT_REGION
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/volsync/restic/config
metadataPolicy: None
property: AWS_DEFAULT_REGION
- secretKey: AWS_ACCESS_KEY_ID
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /digital-ocean/home-infra/volsync-backups
metadataPolicy: None
property: access_key
- secretKey: AWS_SECRET_ACCESS_KEY
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /digital-ocean/home-infra/volsync-backups
metadataPolicy: None
property: secret_key

View File

@@ -0,0 +1,28 @@
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: http-route-actual
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: http-route-actual
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: traefik-gateway
namespace: traefik
hostnames:
- actual.alexlebens.net
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- group: ''
kind: Service
name: actual
port: 80
weight: 100

View File

@@ -0,0 +1,25 @@
apiVersion: volsync.backube/v1alpha1
kind: ReplicationSource
metadata:
name: actual-data-backup-source
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: actual-data-backup-source
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
sourcePVC: actual-data
trigger:
schedule: 0 4 * * *
restic:
pruneIntervalDays: 7
repository: actual-data-backup-secret
retain:
hourly: 1
daily: 3
weekly: 2
monthly: 2
yearly: 4
copyMethod: Snapshot
storageClassName: ceph-block
volumeSnapshotClassName: ceph-blockpool-snapshot

View File

@@ -0,0 +1,56 @@
actual:
controllers:
main:
type: deployment
replicas: 1
strategy: Recreate
revisionHistoryLimit: 3
containers:
main:
image:
repository: ghcr.io/actualbudget/actual
tag: 25.6.1
pullPolicy: IfNotPresent
env:
- name: TZ
value: US/Central
resources:
requests:
cpu: 10m
memory: 128Mi
probes:
liveness:
enabled: true
custom: true
spec:
exec:
command:
- /usr/bin/env
- bash
- -c
- node src/scripts/health-check.js
failureThreshold: 5
initialDelaySeconds: 60
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 10
service:
main:
controller: main
ports:
http:
port: 80
targetPort: 5006
protocol: HTTP
persistence:
data:
forceRename: actual-data
storageClass: ceph-block
accessMode: ReadWriteOnce
size: 2Gi
retain: true
advancedMounts:
main:
main:
- path: /data
readOnly: false

View File

@@ -0,0 +1,23 @@
apiVersion: v2
name: audiobookshelf
version: 1.0.0
description: Audiobookshelf
keywords:
- audiobookshelf
- books
- podcasts
- audiobooks
home: https://wiki.alexlebens.dev/s/d4d6719f-cd1c-4b6e-b78e-2d2d7a5097d7
sources:
- https://github.com/advplyr/audiobookshelf
- https://github.com/advplyr/audiobookshelf/pkgs/container/audiobookshelf
- https://github.com/bjw-s-labs/helm-charts/tree/main/charts/other/app-template
maintainers:
- name: alexlebens
dependencies:
- name: app-template
alias: audiobookshelf
repository: https://bjw-s-labs.github.io/helm-charts/
version: 4.1.1
icon: https://cdn.jsdelivr.net/gh/selfhst/icons/png/audiobookshelf.png
appVersion: 2.21.0

View File

@@ -0,0 +1,135 @@
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: audiobookshelf-apprise-config
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: audiobookshelf-apprise-config
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
data:
- secretKey: ntfy-url
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/audiobookshelf/apprise
metadataPolicy: None
property: ntfy-url
---
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: audiobookshelf-config-backup-secret
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: audiobookshelf-config-backup-secret
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
target:
template:
mergePolicy: Merge
engineVersion: v2
data:
RESTIC_REPOSITORY: "{{ `{{ .BUCKET_ENDPOINT }}` }}/audiobookshelf/audiobookshelf-config"
data:
- secretKey: BUCKET_ENDPOINT
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/volsync/restic/config
metadataPolicy: None
property: S3_BUCKET_ENDPOINT
- secretKey: RESTIC_PASSWORD
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/volsync/restic/config
metadataPolicy: None
property: RESTIC_PASSWORD
- secretKey: AWS_DEFAULT_REGION
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/volsync/restic/config
metadataPolicy: None
property: AWS_DEFAULT_REGION
- secretKey: AWS_ACCESS_KEY_ID
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /digital-ocean/home-infra/volsync-backups
metadataPolicy: None
property: access_key
- secretKey: AWS_SECRET_ACCESS_KEY
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /digital-ocean/home-infra/volsync-backups
metadataPolicy: None
property: secret_key
---
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: audiobookshelf-metadata-backup-secret
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: audiobookshelf-metadata-backup-secret
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
target:
template:
mergePolicy: Merge
engineVersion: v2
data:
RESTIC_REPOSITORY: "{{ `{{ .BUCKET_ENDPOINT }}` }}/audiobookshelf/audiobookshelf-metadata"
data:
- secretKey: BUCKET_ENDPOINT
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/volsync/restic/config
metadataPolicy: None
property: S3_BUCKET_ENDPOINT
- secretKey: RESTIC_PASSWORD
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/volsync/restic/config
metadataPolicy: None
property: RESTIC_PASSWORD
- secretKey: AWS_DEFAULT_REGION
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/volsync/restic/config
metadataPolicy: None
property: AWS_DEFAULT_REGION
- secretKey: AWS_ACCESS_KEY_ID
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /digital-ocean/home-infra/volsync-backups
metadataPolicy: None
property: access_key
- secretKey: AWS_SECRET_ACCESS_KEY
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /digital-ocean/home-infra/volsync-backups
metadataPolicy: None
property: secret_key

View File

@@ -0,0 +1,28 @@
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: http-route-audiobookshelf
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: http-route-audiobookshelf
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: traefik-gateway
namespace: traefik
hostnames:
- audiobookshelf.alexlebens.net
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- group: ''
kind: Service
name: audiobookshelf
port: 80
weight: 100

View File

@@ -0,0 +1,36 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: audiobookshelf-nfs-storage-backup
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: audiobookshelf-nfs-storage-backup
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
volumeMode: Filesystem
storageClassName: nfs-client
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: audiobookshelf-nfs-storage
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: audiobookshelf-nfs-storage
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
volumeName: audiobookshelf-nfs-storage
storageClassName: nfs-client
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi

View File

@@ -0,0 +1,23 @@
apiVersion: v1
kind: PersistentVolume
metadata:
name: audiobookshelf-nfs-storage
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: audiobookshelf-nfs-storage
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
persistentVolumeReclaimPolicy: Retain
storageClassName: nfs-client
capacity:
storage: 1Gi
accessModes:
- ReadWriteMany
nfs:
path: /volume2/Storage
server: synologybond.alexlebens.net
mountOptions:
- vers=4
- minorversion=1
- noac

View File

@@ -0,0 +1,52 @@
apiVersion: volsync.backube/v1alpha1
kind: ReplicationSource
metadata:
name: audiobookshelf-config-backup-source
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: audiobookshelf-config-backup-source
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
sourcePVC: audiobookshelf-config
trigger:
schedule: 0 4 * * *
restic:
pruneIntervalDays: 7
repository: audiobookshelf-config-backup-secret
retain:
hourly: 1
daily: 3
weekly: 2
monthly: 2
yearly: 4
copyMethod: Snapshot
storageClassName: ceph-block
volumeSnapshotClassName: ceph-blockpool-snapshot
---
apiVersion: volsync.backube/v1alpha1
kind: ReplicationSource
metadata:
name: audiobookshelf-metadata-backup-source
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: audiobookshelf-metadata-backup-source
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
sourcePVC: audiobookshelf-metadata
trigger:
schedule: 0 4 * * *
restic:
pruneIntervalDays: 7
repository: audiobookshelf-metadata-backup-secret
retain:
hourly: 1
daily: 3
weekly: 2
monthly: 2
yearly: 4
copyMethod: Snapshot
storageClassName: ceph-block
volumeSnapshotClassName: ceph-blockpool-snapshot

View File

@@ -0,0 +1,19 @@
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: audiobookshelf-apprise
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: audiobookshelf-apprise
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
endpoints:
- port: apprise
interval: 30s
scrapeTimeout: 15s
path: /metrics
selector:
matchLabels:
app.kubernetes.io/name: audiobookshelf
app.kubernetes.io/instance: {{ .Release.Name }}

View File

@@ -0,0 +1,90 @@
audiobookshelf:
controllers:
main:
type: deployment
replicas: 1
strategy: Recreate
revisionHistoryLimit: 3
containers:
main:
image:
repository: ghcr.io/advplyr/audiobookshelf
tag: 2.25.1
pullPolicy: IfNotPresent
env:
- name: TZ
value: US/Central
resources:
requests:
cpu: 10m
memory: 128Mi
apprise-api:
image:
repository: caronc/apprise
tag: 1.2.0
pullPolicy: IfNotPresent
env:
- name: TZ
value: US/Central
- name: APPRISE_STORAGE_MODE
value: memory
- name: APPRISE_STATEFUL_MODE
value: disabled
- name: APPRISE_WORKER_COUNT
value: 1
- name: APPRISE_STATELESS_URLS
valueFrom:
secretKeyRef:
name: audiobookshelf-apprise-config
key: ntfy-url
resources:
requests:
cpu: 10m
memory: 128Mi
service:
main:
controller: main
ports:
http:
port: 80
targetPort: 80
protocol: HTTP
apprise:
port: 8000
targetPort: 8000
protocol: HTTP
persistence:
config:
storageClass: ceph-block
accessMode: ReadWriteOnce
size: 2Gi
retain: true
advancedMounts:
main:
main:
- path: /config
readOnly: false
metadata:
storageClass: ceph-block
accessMode: ReadWriteOnce
size: 10Gi
retain: true
advancedMounts:
main:
main:
- path: /metadata
readOnly: false
backup:
existingClaim: audiobookshelf-nfs-storage-backup
advancedMounts:
main:
main:
- path: /metadata/backups
readOnly: false
audiobooks:
existingClaim: audiobookshelf-nfs-storage
advancedMounts:
main:
main:
- path: /mnt/store/
readOnly: false

View File

@@ -0,0 +1,23 @@
apiVersion: v2
name: bazarr
version: 1.0.0
description: Bazarr
keywords:
- bazarr
- servarr
- subtitles
home: https://wiki.alexlebens.dev/s/92784d53-1d43-42fd-b509-f42c73454226
sources:
- https://github.com/morpheus65535/bazarr
- https://github.com/linuxserver/docker-bazarr
- https://github.com/linuxserver/docker-bazarr/pkgs/container/bazarr
- https://github.com/bjw-s-labs/helm-charts/tree/main/charts/other/app-template
maintainers:
- name: alexlebens
dependencies:
- name: app-template
alias: bazarr
repository: https://bjw-s-labs.github.io/helm-charts/
version: 4.1.1
icon: https://cdn.jsdelivr.net/gh/selfhst/icons/png/bazarr.png
appVersion: 1.5.2

View File

@@ -0,0 +1,55 @@
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: bazarr-config-backup-secret
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: bazarr-config-backup-secret
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
target:
template:
mergePolicy: Merge
engineVersion: v2
data:
RESTIC_REPOSITORY: "{{ `{{ .BUCKET_ENDPOINT }}` }}/bazarr/bazarr-config"
data:
- secretKey: BUCKET_ENDPOINT
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/volsync/restic/config
metadataPolicy: None
property: S3_BUCKET_ENDPOINT
- secretKey: RESTIC_PASSWORD
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/volsync/restic/config
metadataPolicy: None
property: RESTIC_PASSWORD
- secretKey: AWS_DEFAULT_REGION
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/volsync/restic/config
metadataPolicy: None
property: AWS_DEFAULT_REGION
- secretKey: AWS_ACCESS_KEY_ID
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /digital-ocean/home-infra/volsync-backups
metadataPolicy: None
property: access_key
- secretKey: AWS_SECRET_ACCESS_KEY
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /digital-ocean/home-infra/volsync-backups
metadataPolicy: None
property: secret_key

View File

@@ -0,0 +1,28 @@
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: http-route-bazarr
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: http-route-bazarr
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: traefik-gateway
namespace: traefik
hostnames:
- bazarr.alexlebens.net
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- group: ''
kind: Service
name: bazarr
port: 80
weight: 100

View File

@@ -0,0 +1,17 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: bazarr-nfs-storage
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: bazarr-nfs-storage
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
volumeName: bazarr-nfs-storage
storageClassName: nfs-client
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi

View File

@@ -0,0 +1,23 @@
apiVersion: v1
kind: PersistentVolume
metadata:
name: bazarr-nfs-storage
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: bazarr-nfs-storage
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
persistentVolumeReclaimPolicy: Retain
storageClassName: nfs-client
capacity:
storage: 1Gi
accessModes:
- ReadWriteMany
nfs:
path: /volume2/Storage
server: synologybond.alexlebens.net
mountOptions:
- vers=4
- minorversion=1
- noac

View File

@@ -0,0 +1,30 @@
apiVersion: volsync.backube/v1alpha1
kind: ReplicationSource
metadata:
name: bazarr-config-backup-source
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: bazarr-config-backup-source
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
sourcePVC: bazarr-config
trigger:
schedule: 0 4 * * *
restic:
pruneIntervalDays: 7
repository: bazarr-config-backup-secret
retain:
hourly: 1
daily: 3
weekly: 2
monthly: 2
yearly: 4
moverSecurityContext:
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
fsGroupChangePolicy: OnRootMismatch
copyMethod: Snapshot
storageClassName: ceph-block
volumeSnapshotClassName: ceph-blockpool-snapshot

View File

@@ -0,0 +1,57 @@
bazarr:
controllers:
main:
type: deployment
replicas: 1
strategy: Recreate
revisionHistoryLimit: 3
pod:
securityContext:
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
fsGroupChangePolicy: OnRootMismatch
containers:
main:
image:
repository: ghcr.io/linuxserver/bazarr
tag: 1.5.2@sha256:a92ba81b9405942d0b5c01e2707ba8fb99ab059dd800d1dc0e8f52f62ddf74dd
pullPolicy: IfNotPresent
env:
- name: TZ
value: US/Central
- name: PUID
value: 1000
- name: PGID
value: 1000
resources:
requests:
cpu: 10m
memory: 256Mi
service:
main:
controller: main
ports:
http:
port: 80
targetPort: 6767
protocol: HTTP
persistence:
config:
forceRename: bazarr-config
storageClass: ceph-block
accessMode: ReadWriteOnce
size: 5Gi
retain: true
advancedMounts:
main:
main:
- path: /config
readOnly: false
media:
existingClaim: bazarr-nfs-storage
advancedMounts:
main:
main:
- path: /mnt/store
readOnly: false

View File

@@ -0,0 +1,21 @@
apiVersion: v2
name: calibre-web-automated
version: 1.0.0
description: Calibre Web Automated
keywords:
- calibre-web-automated
- books
home: https://wiki.alexlebens.dev/s/fdcfdb7e-8f73-438e-b59c-3c2de2081885
sources:
- https://github.com/crocodilestick/Calibre-Web-Automator
- https://hub.docker.com/r/crocodilestick/calibre-web-automated
- https://github.com/bjw-s-labs/helm-charts/tree/main/charts/other/app-template
maintainers:
- name: alexlebens
dependencies:
- name: app-template
alias: calibre-web-automated
repository: https://bjw-s-labs.github.io/helm-charts/
version: 4.1.1
icon: https://cdn.jsdelivr.net/gh/selfhst/icons/png/calibre-web.png
appVersion: V3.0.4

View File

@@ -0,0 +1,78 @@
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: calibre-web-automated-gmail-config
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: calibre-web-automated-gmail-config
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
data:
- secretKey: gmail.json
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/calibre-web/gmail
metadataPolicy: None
property: gmail.json
---
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: calibre-web-automated-config-backup-secret
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: calibre-web-automated-config-backup-secret
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
target:
template:
mergePolicy: Merge
engineVersion: v2
data:
RESTIC_REPOSITORY: "{{ `{{ .BUCKET_ENDPOINT }}` }}/calibre-web-automated/calibre-web-automated-config"
data:
- secretKey: BUCKET_ENDPOINT
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/volsync/restic/config
metadataPolicy: None
property: S3_BUCKET_ENDPOINT
- secretKey: RESTIC_PASSWORD
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/volsync/restic/config
metadataPolicy: None
property: RESTIC_PASSWORD
- secretKey: AWS_DEFAULT_REGION
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/volsync/restic/config
metadataPolicy: None
property: AWS_DEFAULT_REGION
- secretKey: AWS_ACCESS_KEY_ID
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /digital-ocean/home-infra/volsync-backups
metadataPolicy: None
property: access_key
- secretKey: AWS_SECRET_ACCESS_KEY
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /digital-ocean/home-infra/volsync-backups
metadataPolicy: None
property: secret_key

View File

@@ -0,0 +1,58 @@
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: http-route-calibre
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: http-route-calibre
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: traefik-gateway
namespace: traefik
hostnames:
- calibre.alexlebens.net
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- group: ''
kind: Service
name: calibre-web-automated-main
port: 8083
weight: 100
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: http-route-calibre-downloader
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: http-route-calibre-downloader
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: traefik-gateway
namespace: traefik
hostnames:
- calibre-downloader.alexlebens.net
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- group: ''
kind: Service
name: calibre-web-automated-downloader
port: 8084
weight: 100

View File

@@ -0,0 +1,36 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: calibre-web-automated-nfs-storage
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: calibre-web-automated-nfs-storage
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
volumeName: calibre-web-automated-nfs-storage
storageClassName: nfs-client
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: calibre-web-automated-ingest-nfs-storage
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: calibre-web-automated-ingest-nfs-storage
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
volumeName: calibre-web-automated-ingest-nfs-storage
storageClassName: nfs-client
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi

View File

@@ -0,0 +1,48 @@
apiVersion: v1
kind: PersistentVolume
metadata:
name: calibre-web-automated-nfs-storage
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: calibre-web-automated-nfs-storage
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
persistentVolumeReclaimPolicy: Retain
storageClassName: nfs-client
capacity:
storage: 1Gi
accessModes:
- ReadWriteMany
nfs:
path: /volume2/Storage/Calibre
server: synologybond.alexlebens.net
mountOptions:
- vers=4
- minorversion=1
- noac
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: calibre-web-automated-ingest-nfs-storage
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: calibre-web-automated-ingest-nfs-storage
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
persistentVolumeReclaimPolicy: Retain
storageClassName: nfs-client
capacity:
storage: 1Gi
accessModes:
- ReadWriteMany
nfs:
path: /volume2/Storage/Calibre Import
server: synologybond.alexlebens.net
mountOptions:
- vers=4
- minorversion=1
- noac

View File

@@ -0,0 +1,28 @@
apiVersion: volsync.backube/v1alpha1
kind: ReplicationSource
metadata:
name: calibre-web-automated-config-backup-source
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: calibre-web-automated-config-backup-source
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
sourcePVC: calibre-web-automated-config
trigger:
schedule: 0 4 * * *
restic:
pruneIntervalDays: 7
repository: calibre-web-automated-config-backup-secret
retain:
hourly: 1
daily: 3
weekly: 2
monthly: 2
yearly: 4
moverSecurityContext:
runAsUser: 1000
runAsGroup: 100
copyMethod: Snapshot
storageClassName: ceph-block
volumeSnapshotClassName: ceph-blockpool-snapshot

View File

@@ -0,0 +1,119 @@
calibre-web-automated:
controllers:
main:
type: deployment
replicas: 1
strategy: Recreate
revisionHistoryLimit: 3
containers:
main:
image:
repository: crocodilestick/calibre-web-automated
tag: V3.0.4
pullPolicy: IfNotPresent
env:
- name: TZ
value: US/Central
- name: PUID
value: 1000
- name: PGID
value: 100
resources:
requests:
cpu: 10m
memory: 256Mi
downloader:
type: deployment
replicas: 1
strategy: Recreate
revisionHistoryLimit: 3
containers:
main:
image:
repository: ghcr.io/calibrain/calibre-web-automated-book-downloader
tag: latest@sha256:914a9e80b1c5b81b0e17a7d82ad1d1e22b0050164a739131203831123c60baf7
pullPolicy: IfNotPresent
env:
- name: FLASK_PORT
value: 8084
- name: UID
value: 1000
- name: GID
value: 100
- name: USE_CF_BYPASS
value: true
- name: CLOUDFLARE_PROXY_URL
value: http://localhost:8000
- name: INGEST_DIR
value: /cwa-book-ingest
- name: BOOK_LANGUAGE
value: end
resources:
requests:
cpu: 10m
memory: 256Mi
bypass:
image:
repository: ghcr.io/sarperavci/cloudflarebypassforscraping
tag: latest@sha256:bd326a3c6ae0b7ed3e405bbaa230e43e252f444c98f57d179f7a1d78f273748b
pullPolicy: IfNotPresent
resources:
requests:
cpu: 10m
memory: 128Mi
service:
main:
controller: main
ports:
http:
port: 8083
targetPort: 8083
protocol: HTTP
downloader:
controller: downloader
ports:
http:
port: 8084
targetPort: 8084
protocol: HTTP
persistence:
config:
forceRename: calibre-web-automated-config
storageClass: ceph-block
accessMode: ReadWriteOnce
size: 5Gi
retain: true
advancedMounts:
main:
main:
- path: /config
readOnly: false
gmail:
enabled: true
type: secret
name: calibre-web-automated-gmail-config
advancedMounts:
main:
main:
- path: /app/calibre-web/gmail.json
readOnly: true
mountPropagation: None
subPath: gmail.json
books:
existingClaim: calibre-web-automated-nfs-storage
advancedMounts:
main:
main:
- path: /calibre-library
readOnly: false
ingest:
existingClaim: calibre-web-automated-ingest-nfs-storage
advancedMounts:
main:
main:
- path: /cwa-book-ingest
readOnly: false
downloader:
main:
- path: /cwa-book-ingest
readOnly: false

View File

@@ -0,0 +1,28 @@
apiVersion: v2
name: code-server
version: 1.0.0
description: Code Server
keywords:
- code-server
- code
- ide
home: https://wiki.alexlebens.dev/s/233f96bb-db70-47e4-8b22-a8efcbb0f93d
sources:
- https://github.com/coder/code-server
- https://github.com/cloudflare/cloudflared
- https://hub.docker.com/r/linuxserver/code-server
- https://github.com/bjw-s-labs/helm-charts/tree/main/charts/other/app-template
- https://gitea.alexlebens.dev/alexlebens/helm-charts/src/branch/main/charts/cloudflared
maintainers:
- name: alexlebens
dependencies:
- name: app-template
alias: code-server
repository: https://bjw-s-labs.github.io/helm-charts/
version: 4.1.1
- name: cloudflared
alias: cloudflared
repository: oci://harbor.alexlebens.net/helm-charts
version: 1.17.2
icon: https://cdn.jsdelivr.net/gh/selfhst/icons/png/visual-studio-code.png
appVersion: 4.100.2

View File

@@ -0,0 +1,51 @@
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: codeserver-password-secret
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: codeserver-password-secret
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
data:
- secretKey: PASSWORD
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/code-server/auth
metadataPolicy: None
property: PASSWORD
- secretKey: SUDO_PASSWORD
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/code-server/auth
metadataPolicy: None
property: SUDO_PASSWORD
---
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: code-server-cloudflared-secret
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: code-server-cloudflared-secret
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
data:
- secretKey: cf-tunnel-token
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cloudflare/tunnels/codeserver
metadataPolicy: None
property: token

View File

@@ -0,0 +1,28 @@
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: http-route-code-server
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: http-route-code-server
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: traefik-gateway
namespace: traefik
hostnames:
- code-server.alexlebens.net
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- group: ''
kind: Service
name: code-server
port: 8443
weight: 100

View File

@@ -0,0 +1,17 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: code-server-nfs-storage
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: code-server-nfs-storage
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
volumeMode: Filesystem
storageClassName: nfs-client
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi

View File

@@ -0,0 +1,47 @@
code-server:
controllers:
main:
type: deployment
replicas: 1
strategy: Recreate
revisionHistoryLimit: 3
containers:
main:
image:
repository: ghcr.io/linuxserver/code-server
tag: 4.101.1@sha256:68559204a1328d36ebb3814586dc85af487a04c786b49150b060c4b6c63e1852
pullPolicy: IfNotPresent
env:
- name: TZ
value: US/Central
- name: PUID
value: 1000
- name: PGID
value: 1000
- name: DEFAULT_WORKSPACE
value: /config
envFrom:
- secretRef:
name: codeserver-password-secret
resources:
requests:
cpu: 10m
memory: 128Mi
service:
main:
controller: main
ports:
http:
port: 8443
targetPort: 8443
protocol: HTTP
persistence:
config:
existingClaim: code-server-nfs-storage
advancedMounts:
main:
main:
- path: /config
readOnly: false
cloudflared:
existingSecretName: code-server-cloudflared-secret

View File

@@ -0,0 +1,38 @@
apiVersion: v2
name: directus
version: 1.0.0
description: Directus
keywords:
- directus
- cms
home: https://wiki.alexlebens.dev/s/c2d242de-dcaa-4801-86a2-c4761dc8bf9b
sources:
- https://github.com/directus/directus
- https://github.com/valkey-io/valkey
- https://github.com/cloudflare/cloudflared
- https://github.com/cloudnative-pg/cloudnative-pg
- https://hub.docker.com/r/directus/directus
- https://github.com/bjw-s-labs/helm-charts/tree/main/charts/other/app-template
- https://github.com/bitnami/charts/tree/main/bitnami/valkey
- https://gitea.alexlebens.dev/alexlebens/helm-charts/src/branch/main/charts/cloudflared
- https://gitea.alexlebens.dev/alexlebens/helm-charts/src/branch/main/charts/postgres-cluster
maintainers:
- name: alexlebens
dependencies:
- name: app-template
alias: directus
repository: https://bjw-s-labs.github.io/helm-charts/
version: 4.1.1
- name: valkey
version: 3.0.15
repository: oci://harbor.alexlebens.net/proxy-registry-1.docker.io/bitnamicharts
- name: cloudflared
alias: cloudflared-directus
repository: oci://harbor.alexlebens.net/helm-charts
version: 1.17.2
- name: postgres-cluster
alias: postgres-17-cluster
version: 5.1.0
repository: oci://harbor.alexlebens.net/helm-charts
icon: https://cdn.jsdelivr.net/gh/selfhst/icons/png/directus.png
appVersion: 11.7.2

View File

@@ -0,0 +1,178 @@
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: directus-config
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: directus-config
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
data:
- secretKey: admin-email
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/directus/config
metadataPolicy: None
property: admin-email
- secretKey: admin-password
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/directus/config
metadataPolicy: None
property: admin-password
- secretKey: secret
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/directus/config
metadataPolicy: None
property: secret
- secretKey: key
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/directus/config
metadataPolicy: None
property: key
---
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: directus-metric-token
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: directus-metric-token
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
data:
- secretKey: metric-token
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/directus/metrics
metadataPolicy: None
property: metric-token
---
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: directus-valkey-config
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: directus-valkey-config
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
data:
- secretKey: user
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/directus/valkey
metadataPolicy: None
property: user
- secretKey: password
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/directus/valkey
metadataPolicy: None
property: password
---
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: directus-oidc-secret
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: directus-oidc-secret
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
data:
- secretKey: OIDC_CLIENT_ID
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /authentik/oidc/directus
metadataPolicy: None
property: client
- secretKey: OIDC_CLIENT_SECRET
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /authentik/oidc/directus
metadataPolicy: None
property: secret
---
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: directus-cloudflared-secret
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: directus-cloudflared-secret
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
data:
- secretKey: cf-tunnel-token
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cloudflare/tunnels/directus
metadataPolicy: None
property: token
---
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: directus-postgresql-17-cluster-backup-secret
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: directus-postgresql-17-cluster-backup-secret
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
data:
- secretKey: ACCESS_KEY_ID
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /digital-ocean/home-infra/postgres-backups
metadataPolicy: None
property: access
- secretKey: ACCESS_SECRET_KEY
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /digital-ocean/home-infra/postgres-backups
metadataPolicy: None
property: secret

View File

@@ -0,0 +1,11 @@
apiVersion: objectbucket.io/v1alpha1
kind: ObjectBucketClaim
metadata:
name: ceph-bucket-directus
labels:
app.kubernetes.io/name: ceph-bucket-directus
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
generateBucketName: bucket-directus
storageClassName: ceph-bucket

View File

@@ -0,0 +1,22 @@
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: directus
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: directus
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
selector:
matchLabels:
app.kubernetes.io/name: directus
app.kubernetes.io/instance: {{ .Release.Name }}
endpoints:
- port: http
interval: 30s
scrapeTimeout: 15s
path: /metrics
bearerTokenSecret:
name: directus-metric-token
key: metric-token

View File

@@ -0,0 +1,202 @@
directus:
controllers:
main:
type: deployment
replicas: 1
strategy: Recreate
revisionHistoryLimit: 3
containers:
main:
image:
repository: directus/directus
tag: 11.8.0
pullPolicy: IfNotPresent
env:
- name: PUBLIC_URL
value: https://directus.alexlebens.dev
- name: WEBSOCKETS_ENABLED
value: true
- name: ADMIN_EMAIL
valueFrom:
secretKeyRef:
name: directus-config
key: admin-email
- name: ADMIN_PASSWORD
valueFrom:
secretKeyRef:
name: directus-config
key: admin-password
- name: SECRET
valueFrom:
secretKeyRef:
name: directus-config
key: secret
- name: KEY
valueFrom:
secretKeyRef:
name: directus-config
key: key
- name: DB_CLIENT
value: postgres
- name: DB_HOST
valueFrom:
secretKeyRef:
name: directus-postgresql-17-cluster-app
key: host
- name: DB_DATABASE
valueFrom:
secretKeyRef:
name: directus-postgresql-17-cluster-app
key: dbname
- name: DB_PORT
valueFrom:
secretKeyRef:
name: directus-postgresql-17-cluster-app
key: port
- name: DB_USER
valueFrom:
secretKeyRef:
name: directus-postgresql-17-cluster-app
key: user
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: directus-postgresql-17-cluster-app
key: password
- name: REDIS_ENABLED
value: true
- name: REDIS_HOST
value: directus-valkey-primary
- name: REDIS_PORT
value: 6379
- name: REDIS_USERNAME
valueFrom:
secretKeyRef:
name: directus-valkey-config
key: user
- name: REDIS_PASSWORD
valueFrom:
secretKeyRef:
name: directus-valkey-config
key: password
- name: STORAGE_LOCATIONS
value: s3
- name: STORAGE_S3_DRIVER
value: s3
- name: STORAGE_S3_KEY
valueFrom:
secretKeyRef:
name: ceph-bucket-directus
key: AWS_ACCESS_KEY_ID
- name: STORAGE_S3_SECRET
valueFrom:
secretKeyRef:
name: ceph-bucket-directus
key: AWS_SECRET_ACCESS_KEY
- name: STORAGE_S3_BUCKET
valueFrom:
configMapKeyRef:
name: ceph-bucket-directus
key: BUCKET_NAME
- name: STORAGE_S3_REGION
value: us-east-1
- name: STORAGE_S3_ENDPOINT
value: http://rook-ceph-rgw-ceph-objectstore.rook-ceph.svc:80
- name: STORAGE_S3_FORCE_PATH_STYLE
value: true
- name: AUTH_PROVIDERS
value: AUTHENTIK
- name: AUTH_AUTHENTIK_DRIVER
value: openid
- name: AUTH_AUTHENTIK_CLIENT_ID
valueFrom:
secretKeyRef:
name: directus-oidc-secret
key: OIDC_CLIENT_ID
- name: AUTH_AUTHENTIK_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: directus-oidc-secret
key: OIDC_CLIENT_SECRET
- name: AUTH_AUTHENTIK_SCOPE
value: openid profile email
- name: AUTH_AUTHENTIK_ISSUER_URL
value: https://auth.alexlebens.dev/application/o/directus/.well-known/openid-configuration
- name: AUTH_AUTHENTIK_IDENTIFIER_KEY
value: email
- name: AUTH_AUTHENTIK_ALLOW_PUBLIC_REGISTRATION
value: true
- name: AUTH_AUTHENTIK_LABEL
value: Authentik
- name: TELEMETRY
value: false
- name: METRICS_ENABLED
value: true
- name: METRICS_TOKENS
valueFrom:
secretKeyRef:
name: directus-metric-token
key: metric-token
resources:
requests:
cpu: 10m
memory: 256Mi
service:
main:
controller: main
ports:
http:
port: 80
targetPort: 8055
protocol: TCP
valkey:
architecture: replication
auth:
enabled: true
existingSecret: directus-valkey-config
existingSecretPasswordKey: password
usePasswordFiles: false
primary:
resources:
requests:
cpu: 100m
memory: 64Mi
persistence:
enabled: true
size: 1Gi
replica:
replicaCount: 1
resources:
requests:
cpu: 100m
memory: 64Mi
persistence:
enabled: true
size: 1Gi
cloudflared-directus:
name: cloudflared-directus
existingSecretName: directus-cloudflared-secret
postgres-17-cluster:
mode: standalone
cluster:
storage:
storageClass: local-path
walStorage:
storageClass: local-path
monitoring:
enabled: true
prometheusRule:
enabled: true
recovery:
method: objectStore
objectStore:
endpointURL: https://nyc3.digitaloceanspaces.com
destinationPath: s3://postgres-backups-ce540ddf106d186bbddca68a/cl01tl/directus/directus-postgresql-17-cluster
endpointCredentials: directus-postgresql-17-cluster-backup-secret
recoveryIndex: 2
backup:
enabled: true
endpointURL: https://nyc3.digitaloceanspaces.com
destinationPath: s3://postgres-backups-ce540ddf106d186bbddca68a/cl01tl/directus/directus-postgresql-17-cluster
endpointCredentials: directus-postgresql-17-cluster-backup-secret
backupIndex: 2

View File

@@ -0,0 +1,21 @@
apiVersion: v2
name: eigenfocus
version: 1.0.0
description: Eigenfocus
keywords:
- eigenfocus
- projects
home: https://wiki.alexlebens.dev/s/82548c75-cefe-4ad2-b60c-0b101127c31b
sources:
- https://github.com/Eigenfocus/eigenfocus
- https://hub.docker.com/r/eigenfocus/eigenfocus
- https://github.com/bjw-s-labs/helm-charts/tree/main/charts/other/app-template
maintainers:
- name: alexlebens
dependencies:
- name: app-template
alias: eigenfocus
repository: https://bjw-s-labs.github.io/helm-charts/
version: 4.1.1
icon: https://cdn.jsdelivr.net/gh/selfhst/icons/png/eigenfocus.png
appVersion: 1.1.0

View File

@@ -0,0 +1,55 @@
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: eigenfocus-data-backup-secret
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: eigenfocus-data-backup-secret
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
target:
template:
mergePolicy: Merge
engineVersion: v2
data:
RESTIC_REPOSITORY: "{{ `{{ .BUCKET_ENDPOINT }}` }}/eigenfocus/eigenfocus-data"
data:
- secretKey: BUCKET_ENDPOINT
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/volsync/restic/config
metadataPolicy: None
property: S3_BUCKET_ENDPOINT
- secretKey: RESTIC_PASSWORD
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/volsync/restic/config
metadataPolicy: None
property: RESTIC_PASSWORD
- secretKey: AWS_DEFAULT_REGION
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/volsync/restic/config
metadataPolicy: None
property: AWS_DEFAULT_REGION
- secretKey: AWS_ACCESS_KEY_ID
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /digital-ocean/home-infra/volsync-backups
metadataPolicy: None
property: access_key
- secretKey: AWS_SECRET_ACCESS_KEY
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /digital-ocean/home-infra/volsync-backups
metadataPolicy: None
property: secret_key

View File

@@ -0,0 +1,28 @@
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: http-route-eigenfocus
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: http-route-eigenfocus
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: traefik-gateway
namespace: traefik
hostnames:
- eigenfocus.alexlebens.net
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- group: ''
kind: Service
name: eigenfocus
port: 80
weight: 100

View File

@@ -0,0 +1,25 @@
apiVersion: volsync.backube/v1alpha1
kind: ReplicationSource
metadata:
name: eigenfocus-data-backup-source
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: eigenfocus-data-backup-source
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
sourcePVC: eigenfocus-data
trigger:
schedule: 0 4 * * *
restic:
pruneIntervalDays: 7
repository: eigenfocus-data-backup-secret
retain:
hourly: 1
daily: 3
weekly: 2
monthly: 2
yearly: 4
copyMethod: Snapshot
storageClassName: ceph-block
volumeSnapshotClassName: ceph-blockpool-snapshot

View File

@@ -0,0 +1,40 @@
eigenfocus:
controllers:
main:
type: deployment
replicas: 1
strategy: Recreate
revisionHistoryLimit: 3
containers:
main:
image:
repository: eigenfocus/eigenfocus
tag: 1.2.0-free
pullPolicy: IfNotPresent
env:
- name: DEFAULT_HOST_URL
value: https://eigenfocus.alexlebens.net
resources:
requests:
cpu: 10m
memory: 128Mi
service:
main:
controller: main
ports:
http:
port: 80
targetPort: 3000
protocol: HTTP
persistence:
data:
forceRename: eigenfocus-data
storageClass: ceph-block
accessMode: ReadWriteOnce
size: 2Gi
retain: true
advancedMounts:
main:
main:
- path: /eigenfocus-app/app-data
readOnly: false

View File

@@ -0,0 +1,27 @@
apiVersion: v2
name: element-web
version: 1.0.0
description: Element Web
keywords:
- element-web
- chat
- matrix
home: https://wiki.alexlebens.dev/s/e3b03481-1a1d-4b56-8cd9-e75a8dcc0f6c
sources:
- https://github.com/element-hq/element-web
- https://github.com/cloudflare/cloudflared
- https://hub.docker.com/r/vectorim/element-web
- https://gitlab.com/ananace/charts/-/tree/master/charts/element-web
- https://gitea.alexlebens.dev/alexlebens/helm-charts/src/branch/main/charts/cloudflared
maintainers:
- name: alexlebens
dependencies:
- name: element-web
version: 1.4.14
repository: https://ananace.gitlab.io/charts
- name: cloudflared
alias: cloudflared
repository: oci://harbor.alexlebens.net/helm-charts
version: 1.17.2
icon: https://cdn.jsdelivr.net/gh/selfhst/icons/png/element.png
appVersion: v1.11.100

View File

@@ -0,0 +1,21 @@
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: element-web-cloudflared-secret
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: element-web-cloudflared-secret
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
data:
- secretKey: cf-tunnel-token
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cloudflare/tunnels/element
metadataPolicy: None
property: token

View File

@@ -0,0 +1,28 @@
element-web:
replicaCount: 1
image:
repository: vectorim/element-web
tag: v1.11.104
pullPolicy: IfNotPresent
defaultServer:
url: https://matrix.alexlebens.dev
name: alexlebens.dev
identity_url: https://alexlebens.dev
config:
disable_3pid_login: true
brand: "Alex Lebens"
branding:
welcome_background_url: https://web-assets-3bfcb5585cbd63dc365d32a3.nyc3.cdn.digitaloceanspaces.com/alexlebens-net/background-4.jpg
auth_header_logo_url: https://web-assets-3bfcb5585cbd63dc365d32a3.nyc3.cdn.digitaloceanspaces.com/alexlebens-net/icon_white.png
sso_redirect_options:
immediate: true
default_theme: dark
default_country_code: US
ingress:
enabled: false
resources:
requests:
cpu: 10m
memory: 128Mi
cloudflared:
existingSecretName: element-web-cloudflared-secret

View File

@@ -0,0 +1,33 @@
apiVersion: v2
name: freshrss
version: 1.0.0
description: FreshRSS
keywords:
- freshrss
- rss
home: https://wiki.alexlebens.dev/s/251cb7cb-2797-4bbb-8597-32757aa96391
sources:
- https://github.com/FreshRSS/FreshRSS
- https://github.com/cloudflare/cloudflared
- https://github.com/cloudnative-pg/cloudnative-pg
- https://hub.docker.com/r/freshrss/freshrss
- https://github.com/bjw-s-labs/helm-charts/tree/main/charts/other/app-template
- https://gitea.alexlebens.dev/alexlebens/helm-charts/src/branch/main/charts/cloudflared
- https://gitea.alexlebens.dev/alexlebens/helm-charts/src/branch/main/charts/postgres-cluster
maintainers:
- name: alexlebens
dependencies:
- name: app-template
alias: freshrss
repository: https://bjw-s-labs.github.io/helm-charts/
version: 4.1.1
- name: cloudflared
alias: cloudflared
repository: oci://harbor.alexlebens.net/helm-charts
version: 1.17.2
- name: postgres-cluster
alias: postgres-17-cluster
version: 5.1.0
repository: oci://harbor.alexlebens.net/helm-charts
icon: https://cdn.jsdelivr.net/gh/selfhst/icons/png/freshrss.png
appVersion: 1.26.2

View File

@@ -0,0 +1,182 @@
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: freshrss-install-secret
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: freshrss-install-secret
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
data:
- secretKey: ADMIN_EMAIL
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/freshrss/config
metadataPolicy: None
property: ADMIN_EMAIL
- secretKey: ADMIN_PASSWORD
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/freshrss/config
metadataPolicy: None
property: ADMIN_PASSWORD
- secretKey: ADMIN_API_PASSWORD
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/freshrss/config
metadataPolicy: None
property: ADMIN_API_PASSWORD
---
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: freshrss-oidc-secret
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: freshrss-oidc-secret
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
data:
- secretKey: OIDC_CLIENT_ID
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /authentik/oidc/freshrss
metadataPolicy: None
property: client
- secretKey: OIDC_CLIENT_SECRET
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /authentik/oidc/freshrss
metadataPolicy: None
property: secret
- secretKey: OIDC_CLIENT_CRYPTO_KEY
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /authentik/oidc/freshrss
metadataPolicy: None
property: crypto-key
---
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: freshrss-cloudflared-secret
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: freshrss-cloudflared-secret
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
data:
- secretKey: cf-tunnel-token
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cloudflare/tunnels/freshrss
metadataPolicy: None
property: token
---
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: freshrss-data-backup-secret
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: freshrss-data-backup-secret
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
target:
template:
mergePolicy: Merge
engineVersion: v2
data:
RESTIC_REPOSITORY: "{{ `{{ .BUCKET_ENDPOINT }}` }}/freshrss/freshrss-data"
data:
- secretKey: BUCKET_ENDPOINT
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/volsync/restic/config
metadataPolicy: None
property: S3_BUCKET_ENDPOINT
- secretKey: RESTIC_PASSWORD
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/volsync/restic/config
metadataPolicy: None
property: RESTIC_PASSWORD
- secretKey: AWS_DEFAULT_REGION
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/volsync/restic/config
metadataPolicy: None
property: AWS_DEFAULT_REGION
- secretKey: AWS_ACCESS_KEY_ID
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /digital-ocean/home-infra/volsync-backups
metadataPolicy: None
property: access_key
- secretKey: AWS_SECRET_ACCESS_KEY
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /digital-ocean/home-infra/volsync-backups
metadataPolicy: None
property: secret_key
---
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: freshrss-postgresql-17-cluster-backup-secret
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: freshrss-postgresql-17-cluster-backup-secret
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
data:
- secretKey: ACCESS_KEY_ID
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /digital-ocean/home-infra/postgres-backups
metadataPolicy: None
property: access
- secretKey: ACCESS_SECRET_KEY
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /digital-ocean/home-infra/postgres-backups
metadataPolicy: None
property: secret

View File

@@ -0,0 +1,35 @@
apiVersion: volsync.backube/v1alpha1
kind: ReplicationSource
metadata:
name: freshrss-data-backup-source
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: freshrss-data-backup-source
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
sourcePVC: freshrss-data
trigger:
schedule: 0 4 * * *
restic:
pruneIntervalDays: 7
repository: freshrss-data-backup-secret
retain:
hourly: 1
daily: 3
weekly: 2
monthly: 2
yearly: 4
moverSecurityContext:
runAsUser: 568
runAsGroup: 568
fsGroup: 568
fsGroupChangePolicy: OnRootMismatch
supplementalGroups:
- 44
- 100
- 109
- 65539
copyMethod: Snapshot
storageClassName: ceph-block
volumeSnapshotClassName: ceph-blockpool-snapshot

View File

@@ -0,0 +1,194 @@
freshrss:
controllers:
main:
type: deployment
replicas: 1
strategy: Recreate
revisionHistoryLimit: 3
initContainers:
init-download-extension-1:
securityContext:
runAsUser: 0
image:
repository: alpine
tag: 3.22.0
pullPolicy: IfNotPresent
command:
- /bin/sh
- -ec
- |
apk add --no-cache git;
cd /tmp;
git clone -n --depth=1 --filter=tree:0 https://github.com/cn-tools/cntools_FreshRssExtensions.git;
cd cntools_FreshRssExtensions;
git sparse-checkout set --no-cone /xExtension-YouTubeChannel2RssFeed;
git checkout;
rm -rf /var/www/FreshRSS/extensions/xExtension-YouTubeChannel2RssFeed
cp -r xExtension-YouTubeChannel2RssFeed /var/www/FreshRSS/extensions
chown -R 568:568 /var/www/FreshRSS/extensions/xExtension-YouTubeChannel2RssFeed
resources:
requests:
cpu: 10m
memory: 128Mi
init-download-extension-2:
securityContext:
runAsUser: 0
image:
repository: alpine
tag: 3.22.0
pullPolicy: IfNotPresent
command:
- /bin/sh
- -ec
- |
apk add --no-cache git;
cd /tmp;
git clone -n --depth=1 --filter=tree:0 https://github.com/FreshRSS/Extensions.git;
cd Extensions;
git sparse-checkout set --no-cone /xExtension-ImageProxy;
git checkout;
rm -rf /var/www/FreshRSS/extensions/xExtension-ImageProxy
cp -r xExtension-ImageProxy /var/www/FreshRSS/extensions
chown -R 568:568 /var/www/FreshRSS/extensions/xExtension-YouTubeChannel2RssFeed
resources:
requests:
cpu: 10m
memory: 128Mi
containers:
main:
image:
repository: freshrss/freshrss
tag: 1.26.3
pullPolicy: IfNotPresent
env:
- name: PGID
value: "568"
- name: PUID
value: "568"
- name: TZ
value: US/Central
- name: FRESHRSS_ENV
value: production
- name: CRON_MIN
value: 13,43
- name: BASE_URL
value: https://rss.alexlebens.dev
- name: DB_HOST
valueFrom:
secretKeyRef:
name: freshrss-postgresql-17-cluster-app
key: host
- name: DB_BASE
valueFrom:
secretKeyRef:
name: freshrss-postgresql-17-cluster-app
key: dbname
- name: DB_USER
valueFrom:
secretKeyRef:
name: freshrss-postgresql-17-cluster-app
key: user
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: freshrss-postgresql-17-cluster-app
key: password
- name: FRESHRSS_INSTALL
value: |
--api-enabled
--base-url $(BASE_URL)
--db-base $(DB_BASE)
--db-host $(DB_HOST)
--db-password $(DB_PASSWORD)
--db-type pgsql
--db-user $(DB_USER)
--auth-type http_auth
--default-user admin
--language en
- name: FRESHRSS_USER
value: |
--api-password $(ADMIN_API_PASSWORD)
--email $(ADMIN_EMAIL)
--language en
--password $(ADMIN_PASSWORD)
--user admin
- name: OIDC_ENABLED
value: 1
- name: OIDC_PROVIDER_METADATA_URL
value: https://auth.alexlebens.dev/application/o/freshrss/.well-known/openid-configuration
- name: OIDC_X_FORWARDED_HEADERS
value: X-Forwarded-Port X-Forwarded-Proto X-Forwarded-Host
- name: OIDC_SCOPES
value: openid email profile
- name: OIDC_REMOTE_USER_CLAIM
value: preferred_username
envFrom:
- secretRef:
name: freshrss-oidc-secret
- secretRef:
name: freshrss-install-secret
resources:
requests:
cpu: 10m
memory: 128Mi
service:
main:
controller: main
ports:
http:
port: 80
targetPort: 80
protocol: HTTP
persistence:
data:
storageClass: ceph-block
accessMode: ReadWriteOnce
size: 5Gi
retain: true
advancedMounts:
main:
main:
- path: /var/www/FreshRSS/data
readOnly: false
extensions:
storageClass: ceph-block
accessMode: ReadWriteOnce
size: 1Gi
retain: true
advancedMounts:
main:
init-download-extension-1:
- path: /var/www/FreshRSS/extensions
readOnly: false
init-download-extension-2:
- path: /var/www/FreshRSS/extensions
readOnly: false
main:
- path: /var/www/FreshRSS/extensions
readOnly: false
cloudflared:
existingSecretName: freshrss-cloudflared-secret
postgres-17-cluster:
mode: standalone
cluster:
storage:
storageClass: local-path
walStorage:
storageClass: local-path
monitoring:
enabled: true
prometheusRule:
enabled: true
recovery:
method: objectStore
objectStore:
endpointURL: https://nyc3.digitaloceanspaces.com
destinationPath: s3://postgres-backups-ce540ddf106d186bbddca68a/cl01tl/freshrss/freshrss-postgresql-17-cluster
endpointCredentials: freshrss-postgresql-17-cluster-backup-secret
recoveryIndex: 3
backup:
enabled: true
endpointURL: https://nyc3.digitaloceanspaces.com
destinationPath: s3://postgres-backups-ce540ddf106d186bbddca68a/cl01tl/freshrss/freshrss-postgresql-17-cluster
endpointCredentials: freshrss-postgresql-17-cluster-backup-secret
backupIndex: 3

View File

@@ -0,0 +1,33 @@
apiVersion: v2
name: hoarder
version: 1.0.0
description: Karakeep
keywords:
- hoarder
- karakeep
- bookmarks
home: https://wiki.alexlebens.dev/s/f8177591-8253-4e21-82d5-a556f0aeafad
sources:
- https://github.com/karakeep-app/karakeep
- https://github.com/cloudflare/cloudflared
- https://github.com/meilisearch/meilisearch
- https://github.com/karakeep-app/karakeep/pkgs/container/karakeep
- https://github.com/bjw-s-labs/helm-charts/tree/main/charts/other/app-template
- https://github.com/meilisearch/meilisearch-kubernetes/tree/main/charts/meilisearch
- https://gitea.alexlebens.dev/alexlebens/helm-charts/src/branch/main/charts/cloudflared
maintainers:
- name: alexlebens
dependencies:
- name: app-template
alias: hoarder
repository: https://bjw-s-labs.github.io/helm-charts/
version: 4.1.1
- name: meilisearch
version: 0.14.0
repository: https://meilisearch.github.io/meilisearch-kubernetes
- name: cloudflared
alias: cloudflared
repository: oci://harbor.alexlebens.net/helm-charts
version: 1.17.2
icon: https://cdn.jsdelivr.net/gh/selfhst/icons/webp/karakeep.webp
appVersion: 0.24.1

View File

@@ -0,0 +1,154 @@
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: karakeep-key-secret
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: karakeep-key-secret
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
data:
- secretKey: key
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/karakeep/key
metadataPolicy: None
property: key
---
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: karakeep-oidc-secret
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: karakeep-oidc-secret
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
data:
- secretKey: AUTHENTIK_CLIENT_ID
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /authentik/oidc/karakeep
metadataPolicy: None
property: client
- secretKey: AUTHENTIK_CLIENT_SECRET
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /authentik/oidc/karakeep
metadataPolicy: None
property: secret
---
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: karakeep-meilisearch-master-key-secret
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: karakeep-meilisearch-master-key-secret
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
data:
- secretKey: MEILI_MASTER_KEY
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/karakeep/meilisearch
metadataPolicy: None
property: MEILI_MASTER_KEY
---
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: karakeep-cloudflared-secret
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: karakeep-cloudflared-secret
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
data:
- secretKey: cf-tunnel-token
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cloudflare/tunnels/karakeep
metadataPolicy: None
property: token
---
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: hoarder-data-backup-secret
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: hoarder-data-backup-secret
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
target:
template:
mergePolicy: Merge
engineVersion: v2
data:
RESTIC_REPOSITORY: "{{ `{{ .BUCKET_ENDPOINT }}` }}/hoarder/hoarder-data"
data:
- secretKey: BUCKET_ENDPOINT
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/volsync/restic/config
metadataPolicy: None
property: S3_BUCKET_ENDPOINT
- secretKey: RESTIC_PASSWORD
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/volsync/restic/config
metadataPolicy: None
property: RESTIC_PASSWORD
- secretKey: AWS_DEFAULT_REGION
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/volsync/restic/config
metadataPolicy: None
property: AWS_DEFAULT_REGION
- secretKey: AWS_ACCESS_KEY_ID
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /digital-ocean/home-infra/volsync-backups
metadataPolicy: None
property: access_key
- secretKey: AWS_SECRET_ACCESS_KEY
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /digital-ocean/home-infra/volsync-backups
metadataPolicy: None
property: secret_key

View File

@@ -0,0 +1,25 @@
apiVersion: volsync.backube/v1alpha1
kind: ReplicationSource
metadata:
name: hoarder-data-backup-source
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: hoarder-data-backup-source
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
sourcePVC: hoarder-data
trigger:
schedule: 0 4 * * *
restic:
pruneIntervalDays: 7
repository: hoarder-data-backup-secret
retain:
hourly: 1
daily: 3
weekly: 2
monthly: 2
yearly: 4
copyMethod: Snapshot
storageClassName: ceph-block
volumeSnapshotClassName: ceph-blockpool-snapshot

View File

@@ -0,0 +1,128 @@
hoarder:
controllers:
main:
type: deployment
replicas: 1
strategy: Recreate
revisionHistoryLimit: 3
containers:
main:
image:
repository: ghcr.io/karakeep-app/karakeep
tag: 0.25.0
pullPolicy: IfNotPresent
env:
- name: DATA_DIR
value: /data
- name: NEXTAUTH_URL
value: https://karakeep.alexlebens.dev/
- name: NEXTAUTH_SECRET
valueFrom:
secretKeyRef:
name: karakeep-key-secret
key: key
- name: MEILI_ADDR
value: http://hoarder-meilisearch.hoarder:7700
- name: MEILI_MASTER_KEY
valueFrom:
secretKeyRef:
name: karakeep-meilisearch-master-key-secret
key: MEILI_MASTER_KEY
- name: BROWSER_WEB_URL
value: http://hoarder.hoarder:9222
- name: DISABLE_SIGNUPS
value: false
- name: OAUTH_PROVIDER_NAME
value: "Authentik"
- name: OAUTH_WELLKNOWN_URL
value: https://auth.alexlebens.dev/application/o/karakeep/.well-known/openid-configuration
- name: OAUTH_SCOPE
value: "openid email profile"
- name: OAUTH_CLIENT_ID
valueFrom:
secretKeyRef:
name: karakeep-oidc-secret
key: AUTHENTIK_CLIENT_ID
- name: OAUTH_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: karakeep-oidc-secret
key: AUTHENTIK_CLIENT_SECRET
- name: OLLAMA_BASE_URL
value: http://ollama-server-1.ollama:11434
- name: OLLAMA_KEEP_ALIVE
value: 5m
- name: INFERENCE_TEXT_MODEL
value: llama3.1:8b
- name: INFERENCE_IMAGE_MODEL
value: llama3.2-vision:11b
- name: EMBEDDING_TEXT_MODEL
value: mxbai-embed-large
- name: INFERENCE_JOB_TIMEOUT_SEC
value: 720
resources:
requests:
cpu: 10m
memory: 256Mi
chrome:
image:
repository: gcr.io/zenika-hub/alpine-chrome
tag: 124
pullPolicy: IfNotPresent
args:
- --no-sandbox
- --disable-gpu
- --disable-dev-shm-usage
- --remote-debugging-address=0.0.0.0
- --remote-debugging-port=9222
- --hide-scrollbars
resources:
requests:
cpu: 10m
memory: 128Mi
service:
main:
controller: main
ports:
http:
port: 3000
targetPort: 3000
protocol: HTTP
chrome:
port: 9222
targetPort: 9222
protocol: HTTP
persistence:
data:
forceRename: hoarder-data
storageClass: ceph-block
accessMode: ReadWriteOnce
size: 10Gi
retain: true
advancedMounts:
main:
main:
- path: /data
readOnly: false
meilisearch:
environment:
MEILI_NO_ANALYTICS: true
MEILI_ENV: production
MEILI_EXPERIMENTAL_DUMPLESS_UPGRADE: true
auth:
existingMasterKeySecret: karakeep-meilisearch-master-key-secret
service:
type: ClusterIP
port: 7700
persistence:
enabled: true
storageClass: ceph-block
size: 10Gi
resources:
requests:
cpu: 10m
memory: 128Mi
serviceMonitor:
enabled: true
cloudflared:
existingSecretName: karakeep-cloudflared-secret

View File

@@ -0,0 +1,23 @@
apiVersion: v2
name: home-assistant
version: 1.0.0
description: Home Assistant
keywords:
- home-assistant
- home
- automation
home: https://wiki.alexlebens.dev/s/5462c17e-cd39-4082-ad01-94545a2fa3ca
sources:
- https://www.home-assistant.io/
- https://github.com/home-assistant/core
- https://github.com/home-assistant/core/pkgs/container/home-assistant
- https://github.com/bjw-s-labs/helm-charts/tree/main/charts/other/app-template
maintainers:
- name: alexlebens
dependencies:
- name: app-template
alias: home-assistant
repository: https://bjw-s-labs.github.io/helm-charts/
version: 4.1.1
icon: https://cdn.jsdelivr.net/gh/selfhst/icons/png/home-assistant.png
appVersion: 2025.5.2

View File

@@ -0,0 +1,51 @@
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: home-assistant-code-server-password-secret
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: home-assistant-code-server-password-secret
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
data:
- secretKey: PASSWORD
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/home-assistant/code-server/auth
metadataPolicy: None
property: PASSWORD
- secretKey: SUDO_PASSWORD
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/home-assistant/code-server/auth
metadataPolicy: None
property: SUDO_PASSWORD
---
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: home-assistant-token-secret
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: home-assistant-token-secret
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
data:
- secretKey: bearer-token
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/home-assistant/auth
metadataPolicy: None
property: bearer-token

View File

@@ -0,0 +1,58 @@
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: http-route-home-assistant
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: http-route-home-assistant
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: traefik-gateway
namespace: traefik
hostnames:
- home-assistant.alexlebens.net
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- group: ''
kind: Service
name: home-assistant-main
port: 80
weight: 100
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: http-route-home-assistant-code-server
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: http-route-home-assistant-code-server
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: traefik-gateway
namespace: traefik
hostnames:
- home-assistant-code-server.alexlebens.net
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- group: ''
kind: Service
name: home-assistant-code-server
port: 8443
weight: 100

View File

@@ -0,0 +1,23 @@
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: home-assistant
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: home-assistant
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
selector:
matchLabels:
app.kubernetes.io/name: home-assistant
app.kubernetes.io/service: home-assistant-main
app.kubernetes.io/instance: {{ .Release.Name }}
endpoints:
- port: http
interval: 3m
scrapeTimeout: 1m
path: /api/prometheus
bearerTokenSecret:
name: home-assistant-token-secret
key: bearer-token

View File

@@ -0,0 +1,70 @@
home-assistant:
controllers:
main:
type: deployment
replicas: 1
strategy: Recreate
revisionHistoryLimit: 3
containers:
main:
image:
repository: ghcr.io/home-assistant/home-assistant
tag: 2025.6.2
pullPolicy: IfNotPresent
env:
- name: TZ
value: US/Central
resources:
requests:
cpu: 50m
memory: 512Mi
code-server:
image:
repository: ghcr.io/linuxserver/code-server
tag: 4.101.1@sha256:68559204a1328d36ebb3814586dc85af487a04c786b49150b060c4b6c63e1852
pullPolicy: IfNotPresent
env:
- name: TZ
value: US/Central
- name: PUID
value: 1000
- name: PGID
value: 1000
- name: DEFAULT_WORKSPACE
value: /config
envFrom:
- secretRef:
name: home-assistant-code-server-password-secret
resources:
requests:
cpu: 10m
memory: 128Mi
service:
main:
controller: main
ports:
http:
port: 80
targetPort: 8123
protocol: TCP
code-server:
controller: main
ports:
http:
port: 8443
targetPort: 8443
protocol: HTTP
persistence:
config:
forceRename: home-assistant-config
storageClass: ceph-block
accessMode: ReadWriteOnce
size: 5Gi
advancedMounts:
main:
main:
- path: /config
readOnly: false
code-server:
- path: /config/home-assistant
readOnly: false

View File

@@ -0,0 +1,27 @@
apiVersion: v2
name: homepage
version: 1.0.0
description: Homepage
keywords:
- homepage
- dashboard
home: https://wiki.alexlebens.dev/s/a5fabd91-3d89-4e2b-9417-06111aedaeaa
sources:
- https://github.com/gethomepage/homepage
- https://github.com/cloudflare/cloudflared
- https://github.com/gethomepage/homepage/pkgs/container/homepage
- https://github.com/bjw-s-labs/helm-charts/tree/main/charts/other/app-template
- https://gitea.alexlebens.dev/alexlebens/helm-charts/src/branch/main/charts/cloudflared
maintainers:
- name: alexlebens
dependencies:
- name: app-template
alias: homepage
repository: https://bjw-s-labs.github.io/helm-charts/
version: 4.1.1
- name: cloudflared
alias: cloudflared
repository: oci://harbor.alexlebens.net/helm-charts
version: 1.17.2
icon: https://cdn.jsdelivr.net/gh/selfhst/icons/png/homepage.png
appVersion: v1.2.0

View File

@@ -0,0 +1,21 @@
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: homepage-dev-cloudflared-secret
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: homepage-dev-cloudflared-secret
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
data:
- secretKey: cf-tunnel-token
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cloudflare/tunnels/homepage-dev
metadataPolicy: None
property: token

View File

@@ -0,0 +1,167 @@
homepage:
global:
nameOverride: homepage
controllers:
main:
type: deployment
annotations:
reloader.stakater.com/auto: "true"
strategy: Recreate
containers:
main:
image:
repository: ghcr.io/gethomepage/homepage
tag: v1.3.2
pullPolicy: IfNotPresent
env:
- name: HOMEPAGE_ALLOWED_HOSTS
value: home.alexlebens.dev
resources:
requests:
cpu: 10m
memory: 128Mi
configMaps:
config:
enabled: true
data:
docker.yaml: ""
kubernetes.yaml: ""
settings.yaml: |
favicon: https://web-assets-3bfcb5585cbd63dc365d32a3.nyc3.cdn.digitaloceanspaces.com/alexlebens-net/icon_white.png
headerStyle: clean
hideVersion: true
color: zinc
background:
image: https://web-assets-3bfcb5585cbd63dc365d32a3.nyc3.cdn.digitaloceanspaces.com/alexlebens-net/background-4.jpg
brightness: 50
theme: dark
disableCollapse: true
widgets.yaml: |
- logo:
icon: https://web-assets-3bfcb5585cbd63dc365d32a3.nyc3.cdn.digitaloceanspaces.com/alexlebens-net/icon_white.png
- datetime:
text_size: xl
format:
dateStyle: long
timeStyle: short
hour12: false
- openmeteo:
label: St. Paul
latitude: 44.954445
longitude: -93.091301
timezone: America/Chicago
units: metric
cache: 5
format:
maximumFractionDigits: 0
services.yaml: |
- Applications:
- Auth:
icon: sh-authentik.webp
description: Authentik
href: https://auth.alexlebens.dev
siteMonitor: https://auth.alexlebens.dev
statusStyle: dot
- Gitea:
icon: sh-gitea.webp
description: Gitea
href: https://gitea.alexlebens.dev
siteMonitor: https://gitea.alexlebens.dev
statusStyle: dot
- Code:
icon: sh-visual-studio-code.webp
description: VS Code
href: https://codeserver.alexlebens.dev
siteMonitor: https://codeserver.alexlebens.dev
statusStyle: dot
- Site:
icon: https://web-assets-3bfcb5585cbd63dc365d32a3.nyc3.cdn.digitaloceanspaces.com/alexlebens-net/icon_white.png
description: Profile Website
href: https://www.alexlebens.dev
siteMonitor: https://www.alexlebens.dev
statusStyle: dot
- Content Management:
icon: directus.png
description: Directus
href: https://directus.alexlebens.dev
siteMonitor: https://directus.alexlebens.dev
statusStyle: dot
- Social Media Management:
icon: sh-postiz.webp
description: Postiz
href: https://postiz.alexlebens.dev
siteMonitor: https://postiz.alexlebens.dev
statusStyle: dot
- Chat:
icon: sh-element.webp
description: Matrix
href: https://chat.alexlebens.dev
siteMonitor: https://chat.alexlebens.dev
statusStyle: dot
- Wiki:
icon: sh-outline.webp
description: Outline
href: https://wiki.alexlebens.dev
siteMonitor: https://wiki.alexlebens.dev
statusStyle: dot
- Passwords:
icon: sh-vaultwarden-light.webp
description: Vaultwarden
href: https://passwords.alexlebens.dev
siteMonitor: https://passwords.alexlebens.dev
statusStyle: dot
- Bookmarks:
icon: sh-karakeep-light.webp
description: Karakeep
href: https://karakeep.alexlebens.dev
siteMonitor: https://karakeep.alexlebens.dev
statusStyle: dot
- RSS:
icon: sh-freshrss.webp
description: FreshRSS
href: https://rss.alexlebens.dev
siteMonitor: https://rss.alexlebens.dev
statusStyle: dot
bookmarks.yaml: ""
service:
http:
controller: main
ports:
http:
port: 80
targetPort: 3000
protocol: HTTP
persistence:
config:
enabled: true
type: configMap
name: homepage-dev
advancedMounts:
main:
main:
- path: /app/config/bookmarks.yaml
readOnly: true
mountPropagation: None
subPath: bookmarks.yaml
- path: /app/config/docker.yaml
readOnly: true
mountPropagation: None
subPath: docker.yaml
- path: /app/config/kubernetes.yaml
readOnly: true
mountPropagation: None
subPath: kubernetes.yaml
- path: /app/config/services.yaml
readOnly: true
mountPropagation: None
subPath: services.yaml
- path: /app/config/settings.yaml
readOnly: true
mountPropagation: None
subPath: settings.yaml
- path: /app/config/widgets.yaml
readOnly: true
mountPropagation: None
subPath: widgets.yaml
cloudflared:
existingSecretName: homepage-dev-cloudflared-secret

View File

@@ -0,0 +1,21 @@
apiVersion: v2
name: homepage
version: 1.0.0
description: Homepage
keywords:
- homepage
- dashboard
home: https://wiki.alexlebens.dev/s/a5fabd91-3d89-4e2b-9417-06111aedaeaa
sources:
- https://github.com/gethomepage/homepage
- https://github.com/gethomepage/homepage/pkgs/container/homepage
- https://github.com/bjw-s-labs/helm-charts/tree/main/charts/other/app-template
maintainers:
- name: alexlebens
dependencies:
- name: app-template
alias: homepage
repository: https://bjw-s-labs.github.io/helm-charts/
version: 4.1.1
icon: https://cdn.jsdelivr.net/gh/selfhst/icons/png/homepage.png
appVersion: v1.2.0

View File

@@ -0,0 +1,17 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: homepage
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: homepage
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: homepage
subjects:
- kind: ServiceAccount
name: homepage
namespace: {{ .Release.Namespace }}

View File

@@ -0,0 +1,50 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: homepage
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: homepage
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
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

View File

@@ -0,0 +1,105 @@
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: homepage-keys-secret
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: homepage-keys-secret
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
data:
- secretKey: HOMEPAGE_VAR_SYNOLOGY_USER
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /synology/auth/cl01tl
metadataPolicy: None
property: user
- secretKey: HOMEPAGE_VAR_SYNOLOGY_PASSWORD
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /synology/auth/cl01tl
metadataPolicy: None
property: password
- secretKey: HOMEPAGE_VAR_UNIFI_USER
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /unifi/auth/cl01tl
metadataPolicy: None
property: user
- secretKey: HOMEPAGE_VAR_UNIFI_PASSWORD
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /unifi/auth/cl01tl
metadataPolicy: None
property: password
- secretKey: HOMEPAGE_VAR_SONARR_KEY
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/sonarr4/key
metadataPolicy: None
property: key
- secretKey: HOMEPAGE_VAR_SONARR4K_KEY
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/sonarr4-4k/key
metadataPolicy: None
property: key
- secretKey: HOMEPAGE_VAR_SONARRANIME_KEY
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/sonarr4-anime/key
metadataPolicy: None
property: key
- secretKey: HOMEPAGE_VAR_RADARR_KEY
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/radarr5/key
metadataPolicy: None
property: key
- secretKey: HOMEPAGE_VAR_RADARR4K_KEY
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/radarr5-4k/key
metadataPolicy: None
property: key
- secretKey: HOMEPAGE_VAR_RADARRANIME_KEY
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/radarr5-anime/key
metadataPolicy: None
property: key
- secretKey: HOMEPAGE_VAR_RADARRSTANDUP_KEY
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/radarr5-standup/key
metadataPolicy: None
property: key
- secretKey: HOMEPAGE_VAR_LIDARR_KEY
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/lidarr2/key
metadataPolicy: None
property: key
- secretKey: HOMEPAGE_VAR_PROWLARR_KEY
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/prowlarr/key
metadataPolicy: None
property: key

View File

@@ -0,0 +1,28 @@
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: http-route-homepage
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: http-route-homepage
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: traefik-gateway
namespace: traefik
hostnames:
- home.alexlebens.net
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- group: ''
kind: Service
name: homepage
port: 80
weight: 100

View File

@@ -0,0 +1,30 @@
apiVersion: v1
kind: Service
metadata:
name: gitea-ps10rp
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: gitea-ps10rp
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
annotations:
tailscale.com/tailnet-fqdn: gitea-ps10rp.boreal-beaufort.ts.net
spec:
externalName: placeholder
type: ExternalName
---
apiVersion: v1
kind: Service
metadata:
name: home-ps10rp
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: home-ps10rp
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
annotations:
tailscale.com/tailnet-fqdn: home-ps10rp.boreal-beaufort.ts.net
spec:
externalName: placeholder
type: ExternalName

View File

@@ -0,0 +1,773 @@
homepage:
global:
nameOverride: homepage
controllers:
main:
type: deployment
annotations:
reloader.stakater.com/auto: "true"
strategy: Recreate
serviceAccount:
name: homepage
pod:
automountServiceAccountToken: true
containers:
main:
image:
repository: ghcr.io/gethomepage/homepage
tag: v1.3.2
pullPolicy: IfNotPresent
env:
- name: HOMEPAGE_ALLOWED_HOSTS
value: home.alexlebens.net
envFrom:
- secretRef:
name: homepage-keys-secret
resources:
requests:
cpu: 10m
memory: 256Mi
serviceAccount:
homepage:
enabled: true
staticToken: true
configMaps:
config:
enabled: true
data:
docker.yaml: ""
kubernetes.yaml: |
mode: cluster
settings.yaml: |
favicon: https://web-assets-3bfcb5585cbd63dc365d32a3.nyc3.cdn.digitaloceanspaces.com/alexlebens-net/icon_white.png
headerStyle: clean
hideVersion: true
color: zinc
background:
image: https://web-assets-3bfcb5585cbd63dc365d32a3.nyc3.cdn.digitaloceanspaces.com/alexlebens-net/background-4.jpg
brightness: 50
theme: dark
disableCollapse: true
layout:
- Media:
tab: Applications
icon: mdi-multimedia-#ffffff
- Public:
tab: Applications
icon: mdi-earth-#ffffff
- Internal:
tab: Applications
icon: mdi-security-network-#ffffff
- Code:
tab: Tools
icon: mdi-code-block-braces-#ffffff
- Automation:
tab: Tools
icon: mdi-wrench-#ffffff
- Monitoring:
tab: Tools
icon: mdi-chart-line-#ffffff
- Services:
tab: Services
icon: mdi-toolbox-outline-#ffffff
- Hardware:
tab: Services
icon: mdi-server-network-#ffffff
- Storage:
tab: Services
icon: mdi-database-#ffffff
- TV Shows:
tab: Servarr
icon: mdi-television-#ffffff
- Movies:
tab: Servarr
icon: mdi-filmstrip-#ffffff
- Music:
tab: Servarr
icon: mdi-music-box-multiple-#ffffff
- Services (Servarr):
tab: Servarr
icon: mdi-radar-#ffffff
- External Services:
tab: Bookmarks
icon: mdi-cloud-#ffffff
- Other Homes:
tab: Bookmarks
icon: mdi-cloud-#ffffff
- Trackers:
tab: Bookmarks
icon: mdi-cloud-#ffffff
widgets.yaml: |
- logo:
icon: https://web-assets-3bfcb5585cbd63dc365d32a3.nyc3.cdn.digitaloceanspaces.com/alexlebens-net/icon_white.png
- kubernetes:
cluster:
show: true
cpu: true
memory: true
showLabel: false
label: "Cluster"
nodes:
show: false
- datetime:
text_size: xl
format:
dateStyle: long
timeStyle: short
hour12: false
- openmeteo:
label: St. Paul
latitude: 44.954445
longitude: -93.091301
timezone: America/Chicago
units: metric
cache: 5
format:
maximumFractionDigits: 0
services.yaml: |
- Media:
- Plex:
icon: sh-plex.webp
description: Media server
href: https://plex.alexlebens.net
siteMonitor: http://plex.plex:32400
statusStyle: dot
- Media Requests:
icon: sh-overseerr.webp
description: Overseer
href: https://overseerr.alexlebens.net
siteMonitor: http://overseerr.overseerr:80
statusStyle: dot
- Jellyfin:
icon: sh-jellyfin.webp
description: Media server
href: https://jellyfin.alexlebens.net
siteMonitor: http://jellyfin.jellyfin:80
statusStyle: dot
- Yamtrack:
icon: sh-yamtrack.webp
description: Watched Media Tracking
href: https://yamtrack.alexlebens.net
siteMonitor: http://yamtrack.yamtrack:80
statusStyle: dot
- Youtube Archive:
icon: sh-tube-archivist-light.webp
description: TubeAchivist
href: https://tubearchivist.alexlebens.net/login
siteMonitor: http://tubearchivist.tubearchivist:80
statusStyle: dot
- Photos:
icon: sh-immich.webp
description: Immich
href: https://immich.alexlebens.net
siteMonitor: http://immich-main.immich:2283
statusStyle: dot
- Pictures:
icon: sh-photoview.webp
description: Photoview
href: https://photoview.alexlebens.net
siteMonitor: http://photoview.photoview:80
statusStyle: dot
- Podcasts and Audiobooks:
icon: sh-audiobookshelf.webp
description: Audiobookshelf
href: https://audiobookshelf.alexlebens.net
siteMonitor: http://audiobookshelf.audiobookshelf:80
statusStyle: dot
- Books:
icon: sh-calibre-web.webp
description: Calibre Web Automated
href: https://calibre.alexlebens.net
siteMonitor: http://calibre-web-automated-main.calibre-web-automated:8083
statusStyle: dot
- Public:
- Site:
icon: https://web-assets-3bfcb5585cbd63dc365d32a3.nyc3.cdn.digitaloceanspaces.com/alexlebens-net/icon_white.png
description: Profile Website
href: https://www.alexlebens.dev
siteMonitor: https://www.alexlebens.dev
statusStyle: dot
- Content Management:
icon: directus.png
description: Directus
href: https://directus.alexlebens.dev
siteMonitor: https://directus.alexlebens.dev
statusStyle: dot
- Social Media Management:
icon: sh-postiz.webp
description: Postiz
href: https://postiz.alexlebens.dev
siteMonitor: https://postiz.alexlebens.dev
statusStyle: dot
- Chat:
icon: sh-element.webp
description: Matrix
href: https://chat.alexlebens.dev
siteMonitor: https://chat.alexlebens.dev
statusStyle: dot
- Wiki:
icon: sh-outline.webp
description: Outline
href: https://wiki.alexlebens.dev
siteMonitor: https://wiki.alexlebens.dev
statusStyle: dot
- Passwords:
icon: sh-vaultwarden-light.webp
description: Vaultwarden
href: https://passwords.alexlebens.dev
siteMonitor: https://passwords.alexlebens.dev
statusStyle: dot
- Bookmarks:
icon: sh-karakeep-light.webp
description: Karakeep
href: https://karakeep.alexlebens.dev
siteMonitor: https://karakeep.alexlebens.dev
statusStyle: dot
- RSS:
icon: sh-freshrss.webp
description: FreshRSS
href: https://rss.alexlebens.dev
siteMonitor: https://rss.alexlebens.dev
statusStyle: dot
- Internal:
- Home Automation:
icon: sh-home-assistant.webp
description: Home Assistant
href: https://home-assistant.alexlebens.net
siteMonitor: http://home-assistant-main.home-assistant:80
statusStyle: dot
- Budgeting:
icon: sh-actual-budget.webp
description: Actual
href: https://actual.alexlebens.net
siteMonitor: http://actual.actual:80
statusStyle: dot
- Project Management:
icon: sh-eigenfocus.webp
description: Eigenfocus
href: https://eigenfocus.alexlebens.net
siteMonitor: http://eigenfocus.eigenfocus:80
statusStyle: dot
- AI:
icon: sh-ollama.webp
description: Ollama
href: https://ollama.alexlebens.net
siteMonitor: http://ollama-web.ollama:80
statusStyle: dot
- AI Image:
icon: https://user-images.githubusercontent.com/36368048/196280761-1535f413-a91e-4b6a-af6a-b890f8ae204c.png
description: Stable Diffusion
href: https://stable-diffusion-pd05wd.boreal-beaufort.ts.net
siteMonitor: https://stable-diffusion-pd05wd.boreal-beaufort.ts.net
statusStyle: dot
- Search:
icon: sh-searxng.webp
description: Searxng
href: https://searxng.alexlebens.net/
siteMonitor: http://searxng-browser.searxng:80
statusStyle: dot
- Email:
icon: sh-roundcube.webp
description: Roundcube
href: https://mail.alexlebens.net
siteMonitor: http://roundcube.roundcube:80
statusStyle: dot
- Wiki:
icon: sh-kiwix-light.webp
description: Kiwix
href: https://kiwix.alexlebens.net
siteMonitor: http://kiwix.kiwix:80
statusStyle: dot
- Code:
- Code (Public):
icon: sh-gitea.webp
description: Gitea
href: https://gitea.alexlebens.dev
siteMonitor: https://gitea.alexlebens.dev
statusStyle: dot
- Code (Local):
icon: sh-gitea.webp
description: Gitea
href: https://gitea.alexlebens.net
siteMonitor: https://gitea.alexlebens.net
statusStyle: dot
- Code (ps10rp):
icon: sh-gitea.webp
description: Gitea
href: https://gitea.lebens-home.net
siteMonitor: https://gitea.lebens-home.net
statusStyle: dot
- IDE (Public):
icon: sh-visual-studio-code.webp
description: VS Code
href: https://codeserver.alexlebens.dev
siteMonitor: https://codeserver.alexlebens.dev
statusStyle: dot
- IDE (Home Assistant):
icon: sh-visual-studio-code.webp
description: Edit config for Home Assistant
href: https://home-assistant-code-server.alexlebens.net
siteMonitor: http://home-assistant-code-server.home-assistant:8443
statusStyle: dot
- Continuous Deployment:
icon: sh-argo-cd.webp
description: ArgoCD
href: https://argocd.alexlebens.net
siteMonitor: http://argocd-server.argocd:80
statusStyle: dot
- Docker Deployment:
icon: sh-komodo-light.webp
description: Komodo
href: https://komodo.alexlebens.net
siteMonitor: http://komodo.komodo:80
statusStyle: dot
- Automation:
- Deployment Workflows:
icon: sh-argo-cd.webp
description: Argo Workflows
href: https://argo-workflows.alexlebens.net
siteMonitor: http://argo-workflows-server.argo-workflows:2746
statusStyle: dot
- API Workflows:
icon: sh-n8n.webp
description: n8n
href: https://n8n.alexlebens.net
siteMonitor: http://n8n-main.n8n:80
statusStyle: dot
- Jobs:
icon: https://raw.githubusercontent.com/mshade/kronic/main/static/android-chrome-192x192.png
description: Kronic
href: https://kronic.alexlebens.net
siteMonitor: http://kronic.kronic:80
statusStyle: dot
- Uptime:
icon: sh-gatus.webp
description: Gatus
href: https://gatus.alexlebens.net
siteMonitor: http://gatus.gatus:80
statusStyle: dot
- Tools:
icon: sh-omnitools.webp
description: OmniTools
href: https://omni-tools.alexlebens.net
siteMonitor: http://omni-tools.omni-tools:80
statusStyle: dot
- Monitoring:
- Kubernetes:
icon: sh-headlamp.webp
description: Headlamp
href: https://headlamp.alexlebens.net
siteMonitor: http://headlamp.headlamp:80
statusStyle: dot
- Network Monitoring:
icon: sh-cilium.webp
description: Hubble for Cilium
href: https://hubble.alexlebens.net
siteMonitor: http://hubble-ui.kube-system:80
statusStyle: dot
- Dashboard:
icon: sh-grafana.webp
description: Grafana
href: https://grafana.alexlebens.net
siteMonitor: http://grafana-main-service.grafana-operator:3000/api/health
statusStyle: dot
- Metrics:
icon: sh-prometheus.webp
description: Prometheus
href: https://prometheus.alexlebens.net
siteMonitor: http://kube-prometheus-stack-prometheus.kube-prometheus-stack:9090
statusStyle: dot
widget:
type: prometheus
url: http://kube-prometheus-stack-prometheus.kube-prometheus-stack:9090
- Alerting:
icon: sh-prometheus-light.webp
description: Alertmanager
href: https://alertmanager.alexlebens.net
siteMonitor: http://kube-prometheus-stack-alertmanager.kube-prometheus-stack:9093
statusStyle: dot
widget:
type: prometheusmetric
url: http://kube-prometheus-stack-prometheus.kube-prometheus-stack:9090
refreshInterval: 120s
metrics:
- label: Alerts Active
query: alertmanager_alerts{state="active"}
- label: Metric Database Size
query: prometheus_tsdb_storage_blocks_bytes
format:
type: bytes
- Tautulli:
icon: sh-tautulli.webp
description: Plex Monitoring
href: https://tautulli.alexlebens.net
siteMonitor: http://tautulli.tautulli:80
statusStyle: dot
- Jellystat:
icon: sh-jellystat.webp
description: Jellyfin Monitoring
href: https://jellystat.alexlebens.net
siteMonitor: http://jellystat.jellystat:80
statusStyle: dot
- Services:
- Auth (Public):
icon: sh-authentik.webp
description: Authentik
href: https://auth.alexlebens.dev
siteMonitor: https://auth.alexlebens.dev
statusStyle: dot
- Auth (Local):
icon: sh-authentik.webp
description: Authentik
href: https://authentik.alexlebens.net
siteMonitor: http://authentik-server.authentik:80
statusStyle: dot
- Email:
icon: sh-stalwart.webp
description: Stalwart
href: https://stalwart.alexlebens.net
siteMonitor: http://stalwart.stalwart:80
statusStyle: dot
- Notifications:
icon: sh-ntfy.webp
description: ntfy
href: https://ntfy.alexlebens.net
siteMonitor: http://ntfy.ntfy:80
statusStyle: dot
- Reverse Proxy:
icon: sh-traefik.webp
description: Traefik
href: https://traefik-cl01tl.alexlebens.net/dashboard/#/
siteMonitor: https://traefik-cl01tl.alexlebens.net/dashboard/#/
statusStyle: dot
widget:
type: traefik
url: https://traefik-cl01tl.alexlebens.net
- Image Cache:
icon: sh-harbor.webp
description: Harbor
href: https://harbor.alexlebens.net
siteMonitor: http://harbor-portal.harbor:80
statusStyle: dot
- Hardware:
- Network Management (alexlebens.net):
icon: sh-ubiquiti-unifi.webp
description: Unifi
href: https://unifi.alexlebens.net
siteMonitor: https://unifi.alexlebens.net
statusStyle: dot
- Network Attached Storage:
icon: sh-synology-light.webp
description: Synology
href: https://synology.alexlebens.net
siteMonitor: https://synology.alexlebens.net
statusStyle: dot
widget:
type: diskstation
url: https://synology.alexlebens.net
username: {{ "{{HOMEPAGE_VAR_SYNOLOGY_USER}}" }}
password: {{ "{{HOMEPAGE_VAR_SYNOLOGY_PASSWORD}}" }}
volume: volume_2
- TV Tuner:
icon: sh-hdhomerun.webp
description: HD Homerun
href: http://hdhr.alexlebens.net
siteMonitor: http://hdhr.alexlebens.net
statusStyle: dot
widget:
type: hdhomerun
url: http://hdhr.alexlebens.net
tuner: 0
fields: ["channels", "hd"]
- KVM:
icon: sh-pikvm-light.webp
description: Pi KVM
href: https://pikvm.alexlebens.net
siteMonitor: https://pikvm.alexlebens.net
statusStyle: dot
- Server Plug:
icon: sh-shelly.webp
description: Shelly
href: http://it05sp.alexlebens.net
siteMonitor: http://it05sp.alexlebens.net
statusStyle: dot
- Storage:
- Cluster Storage:
icon: sh-ceph.webp
description: Ceph
href: https://ceph.alexlebens.net
siteMonitor: http://rook-ceph-mgr-dashboard.rook-ceph:7000
statusStyle: dot
- Database:
icon: sh-pgadmin-light.webp
description: PGAdmin
href: https://pgadmin.alexlebens.net
siteMonitor: http://pgadmin.pgadmin:80
statusStyle: dot
- Database:
icon: sh-whodb.webp
description: WhoDB
href: https://whodb.alexlebens.net
siteMonitor: http://whodb.whodb:80
statusStyle: dot
- Secrets:
icon: sh-hashicorp-vault.webp
description: Vault
href: https://vault.alexlebens.net
siteMonitor: http://vault.vault:8200
statusStyle: dot
- TV Shows:
- Sonarr:
icon: sh-sonarr.webp
description: TV Shows
href: https://sonarr.alexlebens.net
siteMonitor: http://sonarr.sonarr:80
statusStyle: dot
widget:
type: sonarr
url: http://sonarr.sonarr:80
key: {{ "{{HOMEPAGE_VAR_SONARR_KEY}}" }}
fields: ["wanted", "queued", "series"]
enableQueue: false
- Sonarr 4K:
icon: sh-sonarr.webp
description: TV Shows 4K
href: https://sonarr-4k.alexlebens.net
siteMonitor: http://sonarr-4k.sonarr-4k:80
statusStyle: dot
widget:
type: sonarr
url: http://sonarr-4k.sonarr-4k:80
key: {{ "{{HOMEPAGE_VAR_SONARR4K_KEY}}" }}
fields: ["wanted", "queued", "series"]
enableQueue: false
- Sonarr Anime:
icon: sh-sonarr.webp
description: Anime Shows
href: https://sonarr-anime.alexlebens.net
siteMonitor: http://sonarr-anime.sonarr-anime:80
statusStyle: dot
widget:
type: sonarr
url: http://sonarr-anime.sonarr-anime:80
key: {{ "{{HOMEPAGE_VAR_SONARRANIME_KEY}}" }}
fields: ["wanted", "queued", "series"]
enableQueue: false
- Movies:
- Radarr:
icon: sh-radarr.webp
description: Movies
href: https://radarr.alexlebens.net
siteMonitor: http://radarr.radarr:80
statusStyle: dot
widget:
type: radarr
url: http://radarr.radarr:80
key: {{ "{{HOMEPAGE_VAR_RADARR_KEY}}" }}
fields: ["wanted", "queued", "movies"]
enableQueue: false
- Radarr 4K:
icon: sh-radarr-4k.webp
description: Movies 4K
href: https://radarr-4k.alexlebens.net
siteMonitor: http://radarr-4k.radarr-4k:80
statusStyle: dot
widget:
type: radarr
url: http://radarr-4k.radarr-4k:80
key: {{ "{{HOMEPAGE_VAR_RADARR4K_KEY}}" }}
fields: ["wanted", "queued", "movies"]
enableQueue: false
- Radarr Anime:
icon: sh-radarr-anime.webp
description: Anime Movies
href: https://radarr-anime.alexlebens.net
siteMonitor: http://radarr-anime.radarr-anime:80
statusStyle: dot
widget:
type: radarr
url: http://radarr-anime.radarr-anime:80
key: {{ "{{HOMEPAGE_VAR_RADARRANIME_KEY}}" }}
fields: ["wanted", "queued", "movies"]
enableQueue: false
- Radarr Stand Up:
icon: sh-radarr-light-hybrid.webp
description: Stand Up
href: https://radarr-standup.alexlebens.net
siteMonitor: http://radarr-standup.radarr-standup:80
statusStyle: dot
widget:
type: radarr
url: http://radarr-standup.radarr-standup:80
key: {{ "{{HOMEPAGE_VAR_RADARRSTANDUP_KEY}}" }}
fields: ["wanted", "queued", "movies"]
enableQueue: false
- Music:
- Lidarr:
icon: sh-lidarr.webp
description: Music
href: https://lidarr.alexlebens.net
siteMonitor: http://lidarr.lidarr:80
statusStyle: dot
widget:
type: lidarr
url: http://lidarr.lidarr:80
key: {{ "{{HOMEPAGE_VAR_LIDARR_KEY}}" }}
fields: ["wanted", "queued", "artists"]
- LidaTube:
icon: sh-lidatube.webp
description: Searches for Music
href: https://lidatube.alexlebens.net
siteMonitor: http://lidatube.lidatube:80
statusStyle: dot
- Soulseek:
icon: sh-slskd.webp
description: slskd
href: https://slskd.alexlebens.net
siteMonitor: http://slskd.slskd:5030
statusStyle: dot
- Services (Servarr):
- qBittorrent:
icon: sh-qbittorrent.webp
description: P2P Downloads
href: https://qbittorrent.alexlebens.net
siteMonitor: http://qbittorrent.qbittorrent:8080
statusStyle: dot
widget:
type: qbittorrent
url: http://qbittorrent.qbittorrent:8080
enableLeechProgress: true
- Prowlarr:
icon: sh-prowlarr.webp
description: Indexers
href: https://prowlarr.alexlebens.net
siteMonitor: http://prowlarr.prowlarr:80
statusStyle: dot
- Bazarr:
icon: sh-bazarr.webp
description: Indexers
href: https://bazarr.alexlebens.net
siteMonitor: http://bazarr.bazarr:80
statusStyle: dot
- Huntarr:
icon: https://raw.githubusercontent.com/plexguide/Huntarr.io/main/frontend/static/logo/128.png
description: Indexers
href: https://huntarr.alexlebens.net
siteMonitor: http://huntarr.huntarr:80
statusStyle: dot
- CWA Downloader:
icon: sh-calibre.webp
description: Calibre Web Automated Book Downloader
href: https://calibre-downloader.alexlebens.net
siteMonitor: http://calibre-web-automated-downloader.calibre-web-automated:8084
statusStyle: dot
- Tdarr:
icon: sh-tdarr.webp
description: Media transcoding and health checks
href: https://tdarr.alexlebens.net
siteMonitor: http://tdarr-web.tdarr:8265
statusStyle: dot
widget:
type: tdarr
url: http://tdarr-web.tdarr:8265
- Other Homes:
- Dev:
icon: sh-homepage.webp
description: Public Homepage
href: https://home.alexlebens.dev
siteMonitor: https://home.alexlebens.dev
statusStyle: dot
- Lebens Home:
icon: sh-homepage.webp
description: Lebens Homepage
href: https://home-ps10rp.boreal-beaufort.ts.net
siteMonitor: https://home-ps10rp.boreal-beaufort.ts.net
statusStyle: dot
bookmarks.yaml: |
- External Services:
- Github:
- abbr: GH
href: https://github.com/alexlebens
- Digital Ocean:
- abbr: DO
href: https://www.digitalocean.com/
- AWS:
- abbr: AW
href: https://aws.amazon.com/console/
- Cloudflare:
- abbr: CF
href: https://dash.cloudflare.com/b76e303258b84076ee01fd0f515c0768
- Tailscale:
- abbr: TS
href: https://login.tailscale.com/admin/machines
- ProtonVPN:
- abbr: PV
href: https://account.protonvpn.com/
- Unifi:
- abbr: UF
href: https://unifi.ui.com/
- Pushover:
- abbr: PO
href: https://pushover.net
- ReCaptcha:
- abbr: RC
href: https://www.google.com/recaptcha/admin/site/698983587
- Trackers:
- Torrentleech:
- abbr: TL
href: https://www.torrentleech.org
- Avistaz:
- abbr: AV
href: https://avistaz.to
- Cinemaz:
- abbr: CM
href: https://cinemaz.to
- Cathode Ray Tube:
- abbr: CRT
href: https://www.cathode-ray.tube
- Alpha Ratio:
- abbr: AL
href: https://alpharatio.cc/
- MV Group:
- abbr: MV
href: https://forums.mvgroup.org
service:
http:
controller: main
ports:
http:
port: 80
targetPort: 3000
protocol: HTTP
persistence:
config:
enabled: true
type: configMap
name: homepage
advancedMounts:
main:
main:
- path: /app/config/bookmarks.yaml
readOnly: true
mountPropagation: None
subPath: bookmarks.yaml
- path: /app/config/docker.yaml
readOnly: true
mountPropagation: None
subPath: docker.yaml
- path: /app/config/kubernetes.yaml
readOnly: true
mountPropagation: None
subPath: kubernetes.yaml
- path: /app/config/services.yaml
readOnly: true
mountPropagation: None
subPath: services.yaml
- path: /app/config/settings.yaml
readOnly: true
mountPropagation: None
subPath: settings.yaml
- path: /app/config/widgets.yaml
readOnly: true
mountPropagation: None
subPath: widgets.yaml

View File

@@ -0,0 +1,21 @@
apiVersion: v2
name: huntarr
version: 1.0.0
description: Huntarr
keywords:
- huntarr
- servarr
home: https://wiki.alexlebens.dev/s/831ca16e-d308-4d7b-9213-f841834c1181
sources:
- https://github.com/plexguide/Huntarr.io
- https://hub.docker.com/r/huntarr/huntarr
- https://github.com/bjw-s-labs/helm-charts/tree/main/charts/other/app-template
maintainers:
- name: alexlebens
dependencies:
- name: app-template
alias: huntarr
repository: https://bjw-s-labs.github.io/helm-charts/
version: 4.1.1
icon: https://cdn.jsdelivr.net/gh/selfhst/icons/png/huntarr.png
appVersion: 7.0.0

View File

@@ -0,0 +1,28 @@
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: http-route-huntarr
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: http-route-huntarr
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: traefik-gateway
namespace: traefik
hostnames:
- huntarr.alexlebens.net
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- group: ''
kind: Service
name: huntarr
port: 80
weight: 100

View File

@@ -0,0 +1,39 @@
huntarr:
controllers:
main:
type: deployment
replicas: 1
strategy: Recreate
revisionHistoryLimit: 3
containers:
main:
image:
repository: ghcr.io/plexguide/huntarr
tag: 7.8.2
pullPolicy: IfNotPresent
env:
- name: TZ
value: US/Central
resources:
requests:
cpu: 100m
memory: 256Mi
service:
main:
controller: main
ports:
http:
port: 80
targetPort: 9705
protocol: HTTP
persistence:
config:
forceRename: huntarr-config
storageClass: ceph-block
accessMode: ReadWriteOnce
size: 1Gi
advancedMounts:
main:
main:
- path: /config
readOnly: false

View File

@@ -0,0 +1,31 @@
apiVersion: v2
name: immich
version: 1.0.0
description: Immich
keywords:
- immich
- photos
home: https://wiki.alexlebens.dev/s/9377ae08-2041-4b6d-bc2b-61a4f5e8faae
sources:
- https://github.com/immich-app/immich
- https://github.com/valkey-io/valkey
- https://github.com/cloudnative-pg/cloudnative-pg
- https://github.com/bjw-s-labs/helm-charts/tree/main/charts/other/app-template
- https://github.com/bitnami/charts/tree/main/bitnami/valkey
- https://gitea.alexlebens.dev/alexlebens/helm-charts/src/branch/main/charts/postgres-cluster
maintainers:
- name: alexlebens
dependencies:
- name: app-template
alias: immich
repository: https://bjw-s-labs.github.io/helm-charts/
version: 4.1.1
- name: valkey
version: 3.0.15
repository: oci://harbor.alexlebens.net/proxy-registry-1.docker.io/bitnamicharts
- name: postgres-cluster
alias: postgres-16-cluster
version: 5.1.0
repository: oci://harbor.alexlebens.net/helm-charts
icon: https://cdn.jsdelivr.net/gh/selfhst/icons/png/immich.png
appVersion: v1.132.3

View File

@@ -0,0 +1,51 @@
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: immich-config-secret
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: immich-config-secret
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
data:
- secretKey: immich.json
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/immich/config
metadataPolicy: None
property: immich.json
---
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: immich-postgresql-16-cluster-backup-secret
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: immich-postgresql-16-cluster-backup-secret
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
data:
- secretKey: ACCESS_KEY_ID
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /digital-ocean/home-infra/postgres-backups
metadataPolicy: None
property: access
- secretKey: ACCESS_SECRET_KEY
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /digital-ocean/home-infra/postgres-backups
metadataPolicy: None
property: secret

View File

@@ -0,0 +1,28 @@
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: http-route-immich
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: http-route-immich
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: traefik-gateway
namespace: traefik
hostnames:
- immich.alexlebens.net
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- group: ''
kind: Service
name: immich-main
port: 2283
weight: 100

View File

@@ -0,0 +1,17 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: immich-nfs-storage
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: immich-nfs-storage
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
volumeName: immich-nfs-storage
storageClassName: nfs-client
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi

View File

@@ -0,0 +1,23 @@
apiVersion: v1
kind: PersistentVolume
metadata:
name: immich-nfs-storage
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: immich-nfs-storage
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
persistentVolumeReclaimPolicy: Retain
storageClassName: nfs-client
capacity:
storage: 1Gi
accessModes:
- ReadWriteMany
nfs:
path: /volume2/Storage/Immich
server: synologybond.alexlebens.net
mountOptions:
- vers=4
- minorversion=1
- noac

View File

@@ -0,0 +1,23 @@
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: immich
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: immich
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
selector:
matchLabels:
app.kubernetes.io/name: immich
app.kubernetes.io/instance: {{ .Release.Name }}
endpoints:
- port: metrics-api
interval: 3m
scrapeTimeout: 1m
path: /metrics
- port: metrics-ms
interval: 3m
scrapeTimeout: 1m
path: /metrics

View File

@@ -0,0 +1,252 @@
immich:
controllers:
main:
type: deployment
replicas: 1
strategy: Recreate
revisionHistoryLimit: 3
containers:
main:
image:
repository: ghcr.io/immich-app/immich-server
tag: v1.135.3
pullPolicy: IfNotPresent
env:
- name: TZ
value: US/Central
- name: IMMICH_TELEMETRY_INCLUDE
value: all
- name: IMMICH_CONFIG_FILE
value: /config/immich.json
- name: IMMICH_MACHINE_LEARNING_URL
value: http://immich-machine-learning.immich:3003
- name: REDIS_HOSTNAME
value: immich-valkey-primary
- name: DB_VECTOR_EXTENSION
value: pgvecto.rs
- name: DB_HOSTNAME
valueFrom:
secretKeyRef:
name: immich-postgresql-16-cluster-app
key: host
- name: DB_DATABASE_NAME
valueFrom:
secretKeyRef:
name: immich-postgresql-16-cluster-app
key: dbname
- name: DB_PORT
valueFrom:
secretKeyRef:
name: immich-postgresql-16-cluster-app
key: port
- name: DB_USERNAME
valueFrom:
secretKeyRef:
name: immich-postgresql-16-cluster-app
key: user
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: immich-postgresql-16-cluster-app
key: password
probes:
liveness:
enabled: true
custom: true
spec:
httpGet:
path: /api/server/ping
port: 2283
initialDelaySeconds: 0
periodSeconds: 10
timeoutSeconds: 1
failureThreshold: 3
readiness:
enabled: true
custom: true
spec:
httpGet:
path: /api/server/ping
port: 2283
initialDelaySeconds: 0
periodSeconds: 10
timeoutSeconds: 1
failureThreshold: 3
startup:
enabled: true
custom: true
spec:
httpGet:
path: /api/server/ping
port: 2283
initialDelaySeconds: 0
periodSeconds: 10
timeoutSeconds: 1
failureThreshold: 30
resources:
limits:
gpu.intel.com/i915: 1
requests:
gpu.intel.com/i915: 1
cpu: 10m
memory: 512Mi
machine-learning:
type: deployment
replicas: 1
strategy: Recreate
revisionHistoryLimit: 3
containers:
main:
image:
repository: ghcr.io/immich-app/immich-machine-learning
tag: v1.134.0
pullPolicy: IfNotPresent
env:
- name: TRANSFORMERS_CACHE
value: /cache
probes:
liveness:
enabled: true
custom: true
spec:
httpGet:
path: /ping
port: 3003
initialDelaySeconds: 0
periodSeconds: 10
timeoutSeconds: 1
failureThreshold: 3
readiness:
enabled: true
custom: true
spec:
httpGet:
path: /ping
port: 3003
initialDelaySeconds: 0
periodSeconds: 10
timeoutSeconds: 1
failureThreshold: 3
startup:
enabled: false
resources:
limits:
gpu.intel.com/i915: 1
requests:
gpu.intel.com/i915: 1
cpu: 10m
memory: 256Mi
service:
main:
controller: main
ports:
http:
port: 2283
targetPort: 2283
protocol: TCP
metrics-api:
port: 8081
targetPort: 8081
protocol: TCP
metrics-ms:
port: 8082
targetPort: 8082
protocol: TCP
machine-learning:
controller: machine-learning
ports:
http:
port: 3003
targetPort: 3003
protocol: TCP
persistence:
config:
enabled: true
type: secret
name: immich-config-secret
advancedMounts:
main:
main:
- path: /config/immich.json
readOnly: true
mountPropagation: None
subPath: immich.json
cache:
storageClass: ceph-block
accessMode: ReadWriteOnce
size: 10Gi
retain: true
advancedMounts:
machine-learning:
main:
- path: /cache
readOnly: false
media:
existingClaim: immich-nfs-storage
advancedMounts:
main:
main:
- path: /usr/src/app/upload
readOnly: false
valkey:
architecture: replication
auth:
enabled: false
usePasswordFiles: false
primary:
resources:
requests:
cpu: 100m
memory: 64Mi
persistence:
enabled: true
size: 1Gi
replica:
replicaCount: 1
resources:
requests:
cpu: 100m
memory: 64Mi
persistence:
enabled: true
size: 1Gi
postgres-16-cluster:
# Tensorchord
#--- https://github.com/immich-app/immich/discussions/9060
#--- https://docs.pgvecto.rs/admin/kubernetes.html
#--- https://github.com/tensorchord/cloudnative-pgvecto.rs
#--- https://github.com/immich-app/immich/discussions/17025
type: tensorchord
mode: recovery
cluster:
image:
repository: ghcr.io/tensorchord/cloudnative-pgvecto.rs
tag: 16.3-v0.2.1
storage:
storageClass: local-path
walStorage:
storageClass: local-path
resources:
requests:
memory: 384Mi
cpu: 200m
monitoring:
enabled: true
prometheusRule:
enabled: true
postgresql:
parameters:
shared_buffers: 256MB
recovery:
method: objectStore
objectStore:
endpointURL: https://nyc3.digitaloceanspaces.com
destinationPath: s3://postgres-backups-ce540ddf106d186bbddca68a/cl01tl/immich/immich-postgresql-17-cluster
endpointCredentials: immich-postgresql-17-cluster-backup-secret
recoveryIndex: 2
backup:
enabled: true
endpointURL: https://nyc3.digitaloceanspaces.com
destinationPath: s3://postgres-backups-ce540ddf106d186bbddca68a/cl01tl/immich/immich-postgresql-16-cluster
endpointCredentials: immich-postgresql-16-cluster-backup-secret
backupIndex: 2

View File

@@ -0,0 +1,25 @@
apiVersion: v2
name: jellyfin
version: 1.0.0
description: Jellyfin
keywords:
- jellyfin
- media
- movies
- tv shows
- books
- music
home: https://wiki.alexlebens.dev/s/a58be5b0-7935-458a-b990-b45223e39d68
sources:
- https://github.com/jellyfin/jellyfin
- https://hub.docker.com/r/jellyfin/jellyfin
- https://github.com/bjw-s-labs/helm-charts/tree/main/charts/other/app-template
maintainers:
- name: alexlebens
dependencies:
- name: app-template
alias: jellyfin
repository: https://bjw-s-labs.github.io/helm-charts/
version: 4.1.1
icon: https://cdn.jsdelivr.net/gh/selfhst/icons/png/jellyfin.png
appVersion: 10.10.7

View File

@@ -0,0 +1,55 @@
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: jellyfin-config-backup-secret
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: jellyfin-config-backup-secret
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
target:
template:
mergePolicy: Merge
engineVersion: v2
data:
RESTIC_REPOSITORY: "{{ `{{ .BUCKET_ENDPOINT }}` }}/jellyfin/jellyfin-config"
data:
- secretKey: BUCKET_ENDPOINT
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/volsync/restic/config
metadataPolicy: None
property: S3_BUCKET_ENDPOINT
- secretKey: RESTIC_PASSWORD
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/volsync/restic/config
metadataPolicy: None
property: RESTIC_PASSWORD
- secretKey: AWS_DEFAULT_REGION
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/volsync/restic/config
metadataPolicy: None
property: AWS_DEFAULT_REGION
- secretKey: AWS_ACCESS_KEY_ID
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /digital-ocean/home-infra/volsync-backups
metadataPolicy: None
property: access_key
- secretKey: AWS_SECRET_ACCESS_KEY
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /digital-ocean/home-infra/volsync-backups
metadataPolicy: None
property: secret_key

View File

@@ -0,0 +1,28 @@
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: http-route-jellyfin
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: http-route-jellyfin
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: traefik-gateway
namespace: traefik
hostnames:
- jellyfin.alexlebens.net
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- group: ''
kind: Service
name: jellyfin
port: 80
weight: 100

View File

@@ -0,0 +1,36 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: jellyfin-nfs-storage
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: jellyfin-nfs-storage
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
volumeName: jellyfin-nfs-storage
storageClassName: nfs-client
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: jellyfin-youtube-nfs-storage
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: jellyfin-youtube-nfs-storage
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
volumeName: jellyfin-youtube-nfs-storage
storageClassName: nfs-client
accessModes:
- ReadOnlyMany
resources:
requests:
storage: 1Gi

View File

@@ -0,0 +1,48 @@
apiVersion: v1
kind: PersistentVolume
metadata:
name: jellyfin-nfs-storage
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: jellyfin-nfs-storage
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
persistentVolumeReclaimPolicy: Retain
storageClassName: nfs-client
capacity:
storage: 1Gi
accessModes:
- ReadWriteMany
nfs:
path: /volume2/Storage
server: synologybond.alexlebens.net
mountOptions:
- vers=4
- minorversion=1
- noac
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: jellyfin-youtube-nfs-storage
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: jellyfin-youtube-nfs-storage
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
persistentVolumeReclaimPolicy: Retain
storageClassName: nfs-client
capacity:
storage: 1Gi
accessModes:
- ReadOnlyMany
nfs:
path: /volume2/Storage/YouTube
server: synologybond.alexlebens.net
mountOptions:
- vers=4
- minorversion=1
- noac

View File

@@ -0,0 +1,26 @@
apiVersion: volsync.backube/v1alpha1
kind: ReplicationSource
metadata:
name: jellyfin-config-backup-source
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: jellyfin-config-backup-source
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
sourcePVC: jellyfin-config
trigger:
schedule: 0 4 * * *
restic:
pruneIntervalDays: 7
repository: jellyfin-config-backup-secret
retain:
hourly: 1
daily: 3
weekly: 2
monthly: 2
yearly: 4
copyMethod: Snapshot
storageClassName: ceph-block
volumeSnapshotClassName: ceph-blockpool-snapshot
cacheCapacity: 10Gi

View File

@@ -0,0 +1,68 @@
jellyfin:
controllers:
main:
type: deployment
replicas: 1
strategy: Recreate
revisionHistoryLimit: 3
containers:
main:
image:
repository: ghcr.io/jellyfin/jellyfin
tag: 10.10.7
pullPolicy: IfNotPresent
env:
- name: TZ
value: US/Central
- name: JELLYFIN_hostwebclient
value: true
- name: JELLYFIN_PublishedServerUrl
value: https://jellyfin.alexlebens.net/
resources:
limits:
gpu.intel.com/i915: 1
requests:
gpu.intel.com/i915: 1
cpu: 1
memory: 2Gi
service:
main:
controller: main
ports:
http:
port: 80
targetPort: 8096
protocol: HTTP
persistence:
config:
forceRename: jellyfin-config
storageClass: ceph-block
accessMode: ReadWriteOnce
size: 100Gi
retain: true
advancedMounts:
main:
main:
- path: /config
readOnly: false
cache:
type: emptyDir
advancedMounts:
main:
main:
- path: /cache
readOnly: false
media:
existingClaim: jellyfin-nfs-storage
advancedMounts:
main:
main:
- path: /mnt/store
readOnly: false
youtube:
existingClaim: jellyfin-youtube-nfs-storage
advancedMounts:
main:
main:
- path: /mnt/youtube
readOnly: true

View File

@@ -0,0 +1,27 @@
apiVersion: v2
name: jellystat
version: 1.0.0
description: Jellystat
keywords:
- jellystat
- jellyfin
home: https://wiki.alexlebens.dev/s/d3fd2bf1-d2ab-4e94-a127-ee35f2d90142
sources:
- https://github.com/CyferShepard/Jellystat
- https://github.com/cloudnative-pg/cloudnative-pg
- https://hub.docker.com/r/cyfershepard/jellystat
- https://github.com/bjw-s-labs/helm-charts/tree/main/charts/other/app-template
- https://gitea.alexlebens.dev/alexlebens/helm-charts/src/branch/main/charts/postgres-cluster
maintainers:
- name: alexlebens
dependencies:
- name: app-template
alias: jellystat
repository: https://bjw-s-labs.github.io/helm-charts/
version: 4.1.1
- name: postgres-cluster
alias: postgres-17-cluster
version: 5.1.0
repository: oci://harbor.alexlebens.net/helm-charts
icon: https://cdn.jsdelivr.net/gh/selfhst/icons/png/jellystat.png
appVersion: 1.1.6

View File

@@ -0,0 +1,122 @@
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: jellystat-secret
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: jellystat-secret
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
data:
- secretKey: secret-key
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/jellystat/auth
metadataPolicy: None
property: secret-key
- secretKey: user
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/jellystat/auth
metadataPolicy: None
property: user
- secretKey: password
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/jellystat/auth
metadataPolicy: None
property: password
---
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: jellystat-data-backup-secret
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: jellystat-data-backup-secret
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
target:
template:
mergePolicy: Merge
engineVersion: v2
data:
RESTIC_REPOSITORY: "{{ `{{ .BUCKET_ENDPOINT }}` }}/jellystat/jellystat-data"
data:
- secretKey: BUCKET_ENDPOINT
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/volsync/restic/config
metadataPolicy: None
property: S3_BUCKET_ENDPOINT
- secretKey: RESTIC_PASSWORD
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/volsync/restic/config
metadataPolicy: None
property: RESTIC_PASSWORD
- secretKey: AWS_DEFAULT_REGION
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/volsync/restic/config
metadataPolicy: None
property: AWS_DEFAULT_REGION
- secretKey: AWS_ACCESS_KEY_ID
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /digital-ocean/home-infra/volsync-backups
metadataPolicy: None
property: access_key
- secretKey: AWS_SECRET_ACCESS_KEY
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /digital-ocean/home-infra/volsync-backups
metadataPolicy: None
property: secret_key
---
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: jellystat-postgresql-17-cluster-backup-secret
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: jellystat-postgresql-17-cluster-backup-secret
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
data:
- secretKey: ACCESS_KEY_ID
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /digital-ocean/home-infra/postgres-backups
metadataPolicy: None
property: access
- secretKey: ACCESS_SECRET_KEY
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /digital-ocean/home-infra/postgres-backups
metadataPolicy: None
property: secret

View File

@@ -0,0 +1,28 @@
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: http-route-jellystat
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: http-route-jellystat
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: traefik-gateway
namespace: traefik
hostnames:
- jellystat.alexlebens.net
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- group: ''
kind: Service
name: jellystat
port: 80
weight: 100

View File

@@ -0,0 +1,25 @@
apiVersion: volsync.backube/v1alpha1
kind: ReplicationSource
metadata:
name: jellystat-data-backup-source
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: jellystat-data-backup-source
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
sourcePVC: jellystat-data
trigger:
schedule: 0 4 * * *
restic:
pruneIntervalDays: 7
repository: jellystat-data-backup-secret
retain:
hourly: 1
daily: 3
weekly: 2
monthly: 2
yearly: 4
copyMethod: Snapshot
storageClassName: ceph-block
volumeSnapshotClassName: ceph-blockpool-snapshot

View File

@@ -0,0 +1,105 @@
jellystat:
controllers:
main:
type: deployment
replicas: 1
strategy: Recreate
revisionHistoryLimit: 3
containers:
main:
image:
repository: cyfershepard/jellystat
tag: 1.1.6
pullPolicy: IfNotPresent
env:
- name: TZ
value: US/Central
- name: JWT_SECRET
valueFrom:
secretKeyRef:
name: jellystat-secret
key: secret-key
- name: JS_USER
valueFrom:
secretKeyRef:
name: jellystat-secret
key: user
- name: JS_PASSWORD
valueFrom:
secretKeyRef:
name: jellystat-secret
key: password
- name: POSTGRES_USER
valueFrom:
secretKeyRef:
name: jellystat-postgresql-17-cluster-app
key: username
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: jellystat-postgresql-17-cluster-app
key: password
- name: POSTGRES_DB
valueFrom:
secretKeyRef:
name: jellystat-postgresql-17-cluster-app
key: dbname
- name: POSTGRES_IP
valueFrom:
secretKeyRef:
name: jellystat-postgresql-17-cluster-app
key: host
- name: POSTGRES_PORT
valueFrom:
secretKeyRef:
name: jellystat-postgresql-17-cluster-app
key: port
resources:
requests:
cpu: 10m
memory: 256Mi
service:
main:
controller: main
ports:
http:
port: 80
targetPort: 3000
protocol: HTTP
persistence:
data:
forceRename: jellystat-data
storageClass: ceph-block
accessMode: ReadWriteOnce
size: 5Gi
retain: true
advancedMounts:
main:
main:
- path: /app/backend/backup-data
readOnly: false
postgres-17-cluster:
mode: standalone
cluster:
storage:
storageClass: local-path
walStorage:
storageClass: local-path
monitoring:
enabled: true
prometheusRule:
enabled: true
recovery:
method: objectStore
objectStore:
endpointURL: https://nyc3.digitaloceanspaces.com
destinationPath: s3://postgres-backups-ce540ddf106d186bbddca68a/cl01tl/jellystat/jellystat-postgresql-17-cluster
endpointCredentials: jellystat-postgresql-17-cluster-backup-secret
recoveryIndex: 2
backup:
enabled: true
endpointURL: https://nyc3.digitaloceanspaces.com
destinationPath: s3://postgres-backups-ce540ddf106d186bbddca68a/cl01tl/jellystat/jellystat-postgresql-17-cluster
endpointCredentials: jellystat-postgresql-17-cluster-backup-secret
backupIndex: 2
retentionPolicy: "7d"

View File

@@ -0,0 +1,21 @@
apiVersion: v2
name: kiwix
version: 1.0.0
description: Kiwix
keywords:
- kiwix
- wikipedia
home: https://wiki.alexlebens.dev/s/16eaaf92-3607-421f-bc66-cb3c39eeaea0
sources:
- https://github.com/kiwix
- https://github.com/kiwix/kiwix-tools/pkgs/container/kiwix-serve
- https://github.com/bjw-s-labs/helm-charts/tree/main/charts/other/app-template
maintainers:
- name: alexlebens
dependencies:
- name: app-template
alias: kiwix
repository: https://bjw-s-labs.github.io/helm-charts/
version: 4.1.1
icon: https://cdn.jsdelivr.net/gh/selfhst/icons/png/kiwix-dark.png
appVersion: 3.7.0

View File

@@ -0,0 +1,28 @@
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: http-route-kiwix
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: http-route-kiwix
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: traefik-gateway
namespace: traefik
hostnames:
- kiwix.alexlebens.net
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- group: ''
kind: Service
name: kiwix
port: 80
weight: 100

Some files were not shown because too many files have changed in this diff Show More