add audiobookshelf

Signed-off-by: gwg313 <gwg313@pm.me>
This commit is contained in:
gwg313 2026-05-19 12:25:02 -04:00
parent bbbb96bd6a
commit d8e2543152
Signed by: gwg313
GPG key ID: 60FF63B4826B7400
25 changed files with 110 additions and 331 deletions

View file

@ -1,8 +1,3 @@
apiVersion: v1
kind: Namespace
metadata:
name: audiobookshelf
---
apiVersion: apps/v1 apiVersion: apps/v1
kind: Deployment kind: Deployment
metadata: metadata:
@ -22,7 +17,7 @@ spec:
spec: spec:
containers: containers:
- name: audiobookshelf - name: audiobookshelf
image: ghcr.io/advplyr/audiobookshelf:latest image: ghcr.io/advplyr/audiobookshelf:2.35.0
imagePullPolicy: IfNotPresent imagePullPolicy: IfNotPresent
ports: ports:
- containerPort: 80 - containerPort: 80
@ -31,6 +26,15 @@ spec:
env: env:
- name: TZ - name: TZ
value: "America/Toronto" value: "America/Toronto"
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
cpu: 1000m
memory: 1Gi
volumeMounts: volumeMounts:
- name: audiobooks-volume - name: audiobooks-volume
mountPath: /audiobooks mountPath: /audiobooks
@ -53,18 +57,3 @@ spec:
- name: metadata-volume - name: metadata-volume
persistentVolumeClaim: persistentVolumeClaim:
claimName: audiobookshelf-metadata claimName: audiobookshelf-metadata
---
apiVersion: v1
kind: Service
metadata:
name: audiobookshelf-svc
namespace: audiobookshelf
spec:
type: ClusterIP
ports:
- name: http
port: 8080
targetPort: http # References the named string 'http' from the containerPort map
protocol: TCP
selector:
app: audiobookshelf

View file

@ -0,0 +1,62 @@
# ----------------------------------------------------
# Ingress only from Gateway API
# ----------------------------------------------------
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: allow-ingress
namespace: audiobookshelf
spec:
endpointSelector:
matchLabels:
app: audiobookshelf
ingress:
- fromEntities:
- ingress
toPorts:
- ports:
- port: "80"
protocol: TCP
---
# ----------------------------------------------------
# audible access (cover art, metadata)
# ----------------------------------------------------
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: allow-audible
namespace: audiobookshelf
spec:
endpointSelector:
matchLabels:
app: audiobookshelf
egress:
- toFQDNs:
- matchName: audible.com
toPorts:
- ports:
- port: "443"
protocol: TCP
# ----------------------------------------------------
# OPTIONAL: unrestricted HTTPS egress (disabled)
# ----------------------------------------------------
# apiVersion: cilium.io/v2
# kind: CiliumNetworkPolicy
# metadata:
# name: allow-all-egress
# namespace: audiobookshelf
# spec:
# endpointSelector:
# matchLabels:
# app: audiobookshelf
#
# egress:
# - toEntities:
# - world
# toPorts:
# - ports:
# - port: "443"
# protocol: TCP

View file

@ -11,7 +11,6 @@ spec:
storage: 1Gi storage: 1Gi
volumeName: audiobookshelf-config-pv volumeName: audiobookshelf-config-pv
storageClassName: audiobookshelf-iscsi storageClassName: audiobookshelf-iscsi
--- ---
apiVersion: v1 apiVersion: v1
kind: PersistentVolumeClaim kind: PersistentVolumeClaim
@ -26,7 +25,6 @@ spec:
storage: 1Gi storage: 1Gi
volumeName: audiobookshelf-metadata-pv volumeName: audiobookshelf-metadata-pv
storageClassName: audiobookshelf-iscsi storageClassName: audiobookshelf-iscsi
--- ---
apiVersion: v1 apiVersion: v1
kind: PersistentVolumeClaim kind: PersistentVolumeClaim

View file

@ -9,6 +9,9 @@ spec:
- ReadWriteOnce - ReadWriteOnce
persistentVolumeReclaimPolicy: Retain persistentVolumeReclaimPolicy: Retain
storageClassName: audiobookshelf-iscsi storageClassName: audiobookshelf-iscsi
claimRef:
namespace: audiobookshelf
name: audiobookshelf-config
iscsi: iscsi:
targetPortal: truenas.local.gwg313.xyz:3260 targetPortal: truenas.local.gwg313.xyz:3260
iqn: iqn.2005-10.org.freenas.ctl:audiobookshelf-config iqn: iqn.2005-10.org.freenas.ctl:audiobookshelf-config
@ -31,6 +34,9 @@ spec:
- ReadWriteOnce - ReadWriteOnce
persistentVolumeReclaimPolicy: Retain persistentVolumeReclaimPolicy: Retain
storageClassName: audiobookshelf-iscsi storageClassName: audiobookshelf-iscsi
claimRef:
namespace: audiobookshelf
name: audiobookshelf-metadata
iscsi: iscsi:
targetPortal: truenas.local.gwg313.xyz:3260 targetPortal: truenas.local.gwg313.xyz:3260
iqn: iqn.2005-10.org.freenas.ctl:audiobookshelf-metadata iqn: iqn.2005-10.org.freenas.ctl:audiobookshelf-metadata
@ -52,10 +58,13 @@ spec:
accessModes: accessModes:
- ReadOnlyMany - ReadOnlyMany
persistentVolumeReclaimPolicy: Retain persistentVolumeReclaimPolicy: Retain
storageClassName: audiobookshelf-nfs
claimRef:
namespace: audiobookshelf
name: audiobookshelf-audiobooks
nfs: nfs:
server: truenas.local.gwg313.xyz server: truenas.local.gwg313.xyz
path: /mnt/tank/media/audiobooks path: /mnt/tank/media/audiobooks
storageClassName: audiobookshelf-nfs
--- ---
apiVersion: v1 apiVersion: v1
kind: PersistentVolume kind: PersistentVolume
@ -67,7 +76,10 @@ spec:
accessModes: accessModes:
- ReadOnlyMany - ReadOnlyMany
persistentVolumeReclaimPolicy: Retain persistentVolumeReclaimPolicy: Retain
storageClassName: audiobookshelf-nfs
claimRef:
namespace: audiobookshelf
name: audiobookshelf-podcasts
nfs: nfs:
server: truenas.local.gwg313.xyz server: truenas.local.gwg313.xyz
path: /mnt/tank/media/podcasts path: /mnt/tank/media/podcasts
storageClassName: audiobookshelf-nfs

View file

@ -1,12 +0,0 @@
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: linkwarden-cert
namespace: istio-system
spec:
secretName: linkwarden-cert
issuerRef:
name: letsencrypt-dns
kind: ClusterIssuer
dnsNames:
- bookmarks.gwg313.xyz

View file

@ -1,18 +0,0 @@
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
name: linkwarden-gateway
namespace: linkwarden
spec:
selector:
istio: gateway
servers:
- port:
number: 443
name: https
protocol: HTTPS
tls:
mode: SIMPLE
credentialName: linkwarden-cert
hosts:
- bookmarks.gwg313.xyz

View file

@ -1,19 +0,0 @@
---
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
creationTimestamp: null
name: linkwarden-iscsi-auth
namespace: linkwarden
spec:
encryptedData:
discovery.sendtargets.auth.password: AgAo6dvx0sb5AklRqs6kLDp+Axa39HF9VvbRmiAqTb1aqS1pmpkt774c6X5B0pVM9Tkz5XANdPriEzpKcBsPLCuBRGrXAjIrzdao6RgXS+11zLx4rnIhw/HUTrFcsbPC1N3ilxICu6y/1pr1alOrtoRa9azKN0R9LoCuM8+T2ea3w7NHjLhxeIGnOe1aOsZQ1Dp3cZQbHiajSGZW9kj0NquJAvVq+tpFNIYDwo08YtOPvGa0jKiZCDq1a29t8yMUY7YLKpEDIibVtFU+OkpiK7TW/cTzURO1Hr+bH3WdLsB6bcQjrtnD75vxYGLTXbjNTjWtkolsZ3tsvR1FVr1iELrXooMrtsEDEum7UyNOf079pwvLMFsz+UrM78bE/JEYzm9YowfBdvOAkvqkwZq9MiJq5heAi1kMgE1p5LPHZGTtVKTBXxwdFRM3qZWRl82nTI+nVAiTqNDP2ZCHvsEOTIIgxb6zSvEcQ1Mjit3PnNh9KmiasGX454S1vS7TROwLsjzubWaMoS3ADN2DSV1uh6pe7/lfn8GcfSfcyYOzGZcgVFWeQoBMXPG+3HsFfidQU+DLdovdqw0DPsEYK7Crvhskz6thfERZDYFMt2RIbsTUeo46SyqhiMuIetmVcvvomgngUM7rclS86B3bMnrXwjkYBznaYBw9+XrUBAoaMChAPkVGT6JKi9hF9cd5R3mfPkvjphKWegyYQlYvyjvG93EN
discovery.sendtargets.auth.username: AgBcERjX9uRVG5MsS6ZALQax8BjEtmfnNuyMMNw5P3Z5Y/ktHQJPY533u2nDaRYp/Gu7EaREQ50UpJ4X93TbbqCHG11N6KLnhxYO1UhlOV3ZJhWvvfKjGF9328uuJdN1Kgf1kZIaZ28bTBQqKFuYCkQzxTuQc5rmXov9uwHFJkcn1+eqHfHMNoBT5L7ljFziLstK11s/WlVpVseMfvOL4nTtLRckAn136ToDakYXX3jJnw/f2ZQADwXN5am53+B24Wcu+ugZxCbESKMQ4qCJc3VAkv+5809N6UPvCKXe8by1J8L6RUZH1ax4bUGci6rEekSl9dEuSaKxMuUZ8dwPf5lMOvGwCm0LvfMqoMFjonb290wU4UgLwVKK7vkoh0ZCBLRkX/zl0BaUAdtcUozT88ZeFfSi8Yv5qEO5jLXb+oUQOID/7PWxyFh0AH2ct/b7utGK06m6HXZnEjOb20tTZw6W16OZxTd7qwGvj6JLznLZBeJGDNeg2AjCIBcBsmA6ocI4pMOpSlAfGWZuvYnRPbov32QEP+zB4aqDk7cRAWUATIs0ES4HK/COpah7k2M0PZ9/YOhWgYfRFKWpHdeB2CUDKRgT0Hyi3xx6HBK0o4S/doBQmaPJq3GsjpVLLaqH6W+KL962/VMSx1QXmcn1dUGT1Qs6o52622dD8WawLIuazRl0pkteckTuEsbxVFms2+nfQUzyihZF6L01
node.session.auth.password: AgAk19CA2EtTgSPRgzD2B7Zbw58r3+rlVyOEkxuMUvWlULqsWp7DSUFcIySH/2kCU4XkMxZOLQiuCdIx7ccBx5CRKFrVAS1L/2L6tZGeLc7NfI8M5Ka8HFy4K1X75yBBd0KiUHn0VEkwyinfDTzSK66+ZYhxgYlBviyhjB+1ieSBTaoXZcJ2AsS9ZsHYmUniro3wr2v/VvmsC2Tgx2TYMpBjC6KWxTJW7QNEMMrBOTnaaYrYDGFe9/as52amuM0Qqygb6bmSp+QEJGUohVgk1dpLFTHubUxMM3aA8UVAh8Ual81DXmBsVUQEx+IuEpNRm76UXlW7Iod5yi9zDWA3Lo4AzdPE112CYwQOR5lf7jqVSyLdcVrweFxY2J8Yh3hPVoM8P93HVGUlatwIlSJXmApfx3TeGvZ7gi1xIfKCpsBlifLCOxLIFE7IghcumDw20lFamuEgXX2iyqbtCgcbibjYbS7NflfjYq5JXx8EwKS89Zqdt3UdsJcvWskO4i0ouXzLxERy+jnRHGtNoUrgziYbkSRyzSCTLIcypn80HA/rZpZc1ZuQYTpJF1JO05QI0pz73U58Tf/gWf/rnwRVtoZmmGZ2tKl+HG0oqlZNEMdrxLcERQ1zEuXXoaSaRm4bbSfhzVfYVyLNA3O+T4EXm4jWY9v7bMHitn+iyfVFTCXhitoIc10F/ZcYHT5rb9cuxE2R5ivqxnDKc0ldbU2JU8Eu
node.session.auth.username: AgAjBMKyXteIqLgPraY9U7n5NzsoWvyi5jVyz0M7i+StCVp2BeKaqhxNMpmxQ98EhAflhh4A/DeLsQueDAMSv2v9So4WmwTCHFRVKxUgLoXjAgzttlsaMrItmIuzGEy5Kx22MkDN5K25PJ2ZelGzY6FUy7LYzJtHLZvU+vZaLKpraw9RrqGHd3M2se5e5GalzIOI3h2K/5Ljs0VfggZEy9wjZvGSeLTPVMXvCtAExAll8wZ5j1U78ddG+rE2Ox0SwB7aF5BqK9f+calijYHNxyCGwoh35T8uCJELIG2GVXIifNvFtLX8vv/si7d60ptoPd1kxcKgCV5mJx1mE7FfeTrFFuqzZThsqwOzfFAoEbcPlE+CJOsJm8DnWlXxHicK6DMaN2LIxk9hMvns8tcr/8VURwZ/8yU9Z8GvEG8tP8zAMc/RP5ZysQIDYAA2EZGtsVrynWRo6K82u5I1axMcwEt0oslQyHrJpmLZv/AOBdjWsvWV6lT7Sv3PlUuqxsw1IRyjokiro74kLNgvTlgluiyhRHb7mjzREZzHoKSYI/6Yzx8xNoLZM2y0VA6NTHHFOorXcxWSeoG1eTynpuJY6jQma1Ie3bN9ohEwoV0trvqotaxku1meJAmZUJTzJ3AkrO43XGMYFYkQfuF8wmEU0Yp1GOtNMKhoa/GnFobnJaviJz8RL6aXUek1Y8LV0s9fhyCxWyuzJxpBUDrm
template:
metadata:
creationTimestamp: null
name: linkwarden-iscsi-auth
namespace: linkwarden
type: kubernetes.io/iscsi-chap

View file

@ -1,47 +0,0 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: linkwarden
namespace: linkwarden
spec:
replicas: 1
selector:
matchLabels:
app: linkwarden
template:
metadata:
labels:
app: linkwarden
spec:
containers:
- name: linkwarden
image: ghcr.io/linkwarden/linkwarden:latest
ports:
- containerPort: 3000
env:
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: postgresql-secret-linkwarden
key: POSTGRESQL_PASSWORD
- name: NEXTAUTH_SECRET
valueFrom:
secretKeyRef:
name: nextauth-secret
key: NEXTAUTH_SECRET
- name: DATABASE_URL
value: "postgres://postgres:$(POSTGRES_PASSWORD)@postgres:5432/postgres"
- name: NEXTAUTH_URL
value: "https://bookmarks.gwg313.xyz/api/v1/auth"
- name: NEXTAUTH_URL_INTERNAL
value: "http://localhost:3000"
- name: NEXT_PUBLIC_DISABLE_REGISTRATION
value: "false"
volumeMounts:
- mountPath: /data/data
name: linkwarden-data
volumes:
- name: linkwarden-data
persistentVolumeClaim:
claimName: linkwarden-data-pvc

View file

@ -1,22 +0,0 @@
apiVersion: v1
kind: PersistentVolume
metadata:
name: linkwarden-data-pv
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
iscsi:
targetPortal: truenas.local.gwg313.xyz:3260
iqn: iqn.2005-10.org.freenas.ctl:linkwarden-data
lun: 0
fsType: ext4
chapAuthDiscovery: true
chapAuthSession: true
secretRef:
name: linkwarden-iscsi-auth
claimRef:
namespace: linkwarden
name: linkwarden-data-pvc

View file

@ -1,13 +0,0 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: linkwarden-data-pvc
namespace: linkwarden
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 5Gi
storageClassName: manual
volumeName: linkwarden-data-pv

View file

@ -1,4 +0,0 @@
apiVersion: v1
kind: Namespace
metadata:
name: linkwarden

View file

@ -1,16 +0,0 @@
---
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
creationTimestamp: null
name: nextauth-secret
namespace: linkwarden
spec:
encryptedData:
NEXTAUTH_SECRET: AgAiZqiSowOJZydmFCxo3EdntZXJp0P5nRucT6N7XMCY0dq523tFYjCU7N+e/DbAQzXcCEF61Bm0E9d37CtlMkgboQbgsrZbTX/Hym1RfECusu0QhLiRI0TLw7/FghFInV4IA133xddBGGN55sQL1VXixK1RWrhF3LCUvchld2dOu6BWZ4QoG8t4Ma+p2vMpC4tfWK8SM8RAurNPLI2E2P7p/RavSFTC3kd7Dniuo6SVbgp/ey4W4qn7R7kb4KD7UyGDB6CW78uNBKI4wqbAhz+LhOdvVizgF99qdgt9hwwd97OIWRQxmDb+B1NjQMdAIy5cv98Zmb0TTR1farefJ2WrzaKLfnWE7Pl0NYTuSrVgl7NYan+Q5k50jiFow5OfrmFXJjcz9quIKjbgGmVDaKi2yyhgbQLUw/LwM7RZJVBTweh9ECcFSLhnjXmJu9lNpLiWlkwKbV8tn+OIxn6SH9lXcuRWIU3DAQ4TNEwwtVe9GRGqDbDQ+uRiElvgsMzmNQHkir3c57YT7NSABaW4YA+W8JMU6pZ3pxmwmg+bwwG64Ej4r2+PtkH+gmD/BqIajo55zUHEm2/Nz7P9wsSEwqRCXh5U5J3Wg8T/p20yjdHMHebsenYb+M4xYOHtUDMbsoreDe0SWVpRoqaxuRBByzhg12ZwBoULfsI4563kBJzxJGZaC712aeuLS3Ln6VwVVgWHYtPzhJqBMb1783XZdV5JIu5vNA==
template:
metadata:
creationTimestamp: null
name: nextauth-secret
namespace: linkwarden
type: Opaque

View file

@ -1,25 +0,0 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: postgresql-config
namespace: linkwarden
data:
POSTGRESQL_FSYNC: "on"
POSTGRESQL_SYNCHRONOUS_COMMIT: "on"
POSTGRESQL_FULL_PAGE_WRITES: "on"
POSTGRESQL_WAL_LEVEL: "replica"
POSTGRESQL_ARCHIVE_MODE: "on"
POSTGRESQL_MAX_WAL_SIZE: "2GB"
POSTGRESQL_MIN_WAL_SIZE: "1GB"
POSTGRESQL_CHECKPOINT_TIMEOUT: "5min"
POSTGRESQL_LOG_CONNECTIONS: "on"
POSTGRESQL_LOG_DISCONNECTIONS: "on"
POSTGRESQL_LOG_STATEMENT: "all"
POSTGRESQL_LOG_DURATION: "1000"
POSTGRESQL_AUTOVACUUM: "on"
POSTGRESQL_VACUUM_COST_DELAY: "20ms"
POSTGRESQL_LOG_TIMEZONE: "UTC"
POSTGRESQL_LOG_CHECKPOINTS: "on"
POSTGRESQL_LOG_ERROR_VERBOSITY: "verbose"
POSTGRESQL_HOT_STANDBY: "on"
POSTGRESQL_ARCHIVE_TIMEOUT: "60s"

View file

@ -1,43 +0,0 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: postgres
namespace: linkwarden
spec:
replicas: 1
selector:
matchLabels:
app: postgres
template:
metadata:
labels:
app: postgres
spec:
securityContext:
fsGroup: 999 # PostgreSQL's default GID (postgres group)
containers:
- name: postgres
image: bitnami/postgresql:latest
ports:
- containerPort: 5432
env:
- name: POSTGRESQL_PASSWORD
valueFrom:
secretKeyRef:
name: postgresql-secret-linkwarden
key: POSTGRESQL_PASSWORD
- name: POSTGRESQL_PERFORM_RESTORE
value: "true"
envFrom:
- configMapRef:
name: postgresql-config
volumeMounts:
- mountPath: /var/lib/postgresql/data
name: postgres-storage
volumes:
- name: postgres-storage
persistentVolumeClaim:
claimName: linkwarden-postgres-pvc
securityContext:
runAsUser: 999 # Ensure the container runs as the 'postgres' user (UID 999)
fsGroup: 999 # Ensure the filesystem group is 'postgres' (GID 999)

View file

@ -1,22 +0,0 @@
apiVersion: v1
kind: PersistentVolume
metadata:
name: linkwarden-postgres-pv
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
iscsi:
targetPortal: truenas.local.gwg313.xyz:3260
iqn: iqn.2005-10.org.freenas.ctl:linkwarden-postgres
lun: 1
fsType: ext4
chapAuthDiscovery: true
chapAuthSession: true
secretRef:
name: linkwarden-iscsi-auth
claimRef:
namespace: linkwarden
name: linkwarden-postgres-pvc

View file

@ -1,13 +0,0 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: linkwarden-postgres-pvc
namespace: linkwarden
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
storageClassName: manual
volumeName: linkwarden-postgres-pv

View file

@ -1,8 +0,0 @@
apiVersion: v1
kind: Secret
metadata:
name: postgresql-secret-linkwarden
namespace: linkwarden
type: Opaque
data:
POSTGRESQL_PASSWORD: dWtGbTYyOGR2QnpKQUpLWGVVdUs=

View file

@ -1,12 +0,0 @@
apiVersion: v1
kind: Service
metadata:
name: postgres
namespace: linkwarden
spec:
type: ClusterIP
selector:
app: postgres
ports:
- port: 5432
targetPort: 5432

View file

@ -1,13 +0,0 @@
apiVersion: v1
kind: Service
metadata:
name: linkwarden
namespace: linkwarden
spec:
selector:
app: linkwarden
ports:
- name: http
port: 80
targetPort: 3000
type: ClusterIP

View file

@ -1,19 +0,0 @@
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: linkwarden
namespace: linkwarden
spec:
hosts:
- bookmarks.gwg313.xyz
gateways:
- linkwarden-gateway
http:
- match:
- uri:
prefix: /
route:
- destination:
host: linkwarden
port:
number: 80

View file

@ -0,0 +1,23 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: audiobookshelf
namespace: argocd
annotations:
argoproj.io/sync-wave: "0"
spec:
project: default
source:
repoURL: https://github.com/gwg313/homelab-gitops.git
targetRevision: main
path: apps/audiobookshelf
destination:
server: https://kubernetes.default.svc
namespace: audiobookshelf
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
- ServerSideApply=true

View file

@ -11,6 +11,7 @@ resources:
- monitoring.yaml - monitoring.yaml
- nfs-subdir.yaml - nfs-subdir.yaml
- forgejo.yaml - forgejo.yaml
- audiobookshelf.yaml
- yopass.yaml - yopass.yaml
- tekton.yaml - tekton.yaml
- navidrome.yaml - navidrome.yaml