From 54046d2bdf5309d55d0338a85a48b8e5545f5f86 Mon Sep 17 00:00:00 2001 From: kisfenyo Date: Sun, 25 Jan 2026 17:51:53 +0100 Subject: [PATCH] replaced calibre+web with cwa --- calibre-system/calibre.yaml | 380 ------------------------------------ calibre-system/cwa.yaml | 240 +++++++++++++++++++++++ 2 files changed, 240 insertions(+), 380 deletions(-) delete mode 100644 calibre-system/calibre.yaml create mode 100644 calibre-system/cwa.yaml diff --git a/calibre-system/calibre.yaml b/calibre-system/calibre.yaml deleted file mode 100644 index bbd1155..0000000 --- a/calibre-system/calibre.yaml +++ /dev/null @@ -1,380 +0,0 @@ ---- -# Calibre System - Calibre + Calibre-web sharing the same library -# Namespace -apiVersion: v1 -kind: Namespace -metadata: - name: calibre-system ---- -# Calibre Deployment (main desktop app with web GUI) -apiVersion: apps/v1 -kind: Deployment -metadata: - name: calibre - namespace: calibre-system - labels: - app.kubernetes.io/instance: calibre - app.kubernetes.io/name: calibre -spec: - replicas: 1 - strategy: - type: Recreate - selector: - matchLabels: - app.kubernetes.io/instance: calibre - app.kubernetes.io/name: calibre - template: - metadata: - labels: - app.kubernetes.io/instance: calibre - app.kubernetes.io/name: calibre - annotations: - match-regex.version-checker.io/calibre: '^[0-9]{1,2}\.\d+\.\d+$' - spec: - containers: - - name: calibre - image: linuxserver/calibre:8.16.2 - imagePullPolicy: IfNotPresent - env: - - name: PUID - value: "1000" - - name: PGID - value: "1000" - - name: TZ - value: Europe/Budapest - # KasmVNC authentication - - name: CUSTOM_USER - valueFrom: - secretKeyRef: - name: calibre-auth - key: username - - name: PASSWORD - valueFrom: - secretKeyRef: - name: calibre-auth - key: password - ports: - - name: http - containerPort: 8080 - protocol: TCP - - name: https - containerPort: 8181 - protocol: TCP - - name: webserver - containerPort: 8081 - protocol: TCP - resources: - requests: - cpu: 100m - memory: 512Mi - limits: - cpu: "2" - memory: 4Gi - livenessProbe: - tcpSocket: - port: http - initialDelaySeconds: 120 - periodSeconds: 60 - timeoutSeconds: 10 - failureThreshold: 5 - readinessProbe: - tcpSocket: - port: http - initialDelaySeconds: 60 - periodSeconds: 10 - timeoutSeconds: 5 - failureThreshold: 3 - volumeMounts: - - name: config - mountPath: /config - - name: books - mountPath: /books - volumes: - - name: config - persistentVolumeClaim: - claimName: calibre-config - - name: books - hostPath: - path: /mnt/4_hdd/data/calibre - type: DirectoryOrCreate ---- -# Calibre-web Deployment -apiVersion: apps/v1 -kind: Deployment -metadata: - name: calibre-web - namespace: calibre-system - labels: - app.kubernetes.io/instance: calibre - app.kubernetes.io/name: calibre-web - app.kubernetes.io/version: 0.6.25-ls361 -spec: - replicas: 1 - strategy: - type: Recreate - selector: - matchLabels: - app.kubernetes.io/instance: calibre - app.kubernetes.io/name: calibre-web - template: - metadata: - labels: - app.kubernetes.io/instance: calibre - app.kubernetes.io/name: calibre-web - annotations: - match-regex.version-checker.io/calibre-web: '^[0-2]\.\d+\.\d+$' - spec: - containers: - - name: calibre-web - image: linuxserver/calibre-web:0.6.25 - imagePullPolicy: IfNotPresent - env: - - name: PUID - value: "1000" - - name: PGID - value: "1000" - - name: TZ - value: Europe/Budapest - # Enable calibre ebook-convert for format conversion - - name: DOCKER_MODS - value: linuxserver/mods:universal-calibre - ports: - - name: http - containerPort: 8083 - protocol: TCP - resources: - requests: - cpu: 100m - memory: 256Mi - limits: - cpu: "1" - memory: 1Gi - livenessProbe: - httpGet: - path: / - port: http - initialDelaySeconds: 60 - periodSeconds: 30 - timeoutSeconds: 10 - failureThreshold: 5 - readinessProbe: - httpGet: - path: / - port: http - initialDelaySeconds: 30 - periodSeconds: 10 - timeoutSeconds: 5 - failureThreshold: 3 - startupProbe: - httpGet: - path: / - port: http - periodSeconds: 10 - timeoutSeconds: 5 - failureThreshold: 60 - volumeMounts: - - name: config - mountPath: /config - - name: books - mountPath: /books - readOnly: false - volumes: - - name: config - persistentVolumeClaim: - claimName: calibre-web-config - - name: books - hostPath: - path: /mnt/4_hdd/data/calibre - type: DirectoryOrCreate ---- -# Calibre Service (desktop GUI) -apiVersion: v1 -kind: Service -metadata: - name: calibre - namespace: calibre-system - labels: - app.kubernetes.io/instance: calibre - app.kubernetes.io/name: calibre - app.kubernetes.io/version: v8.16.2-ls375 -spec: - type: ClusterIP - ports: - - name: http - port: 8080 - targetPort: http - protocol: TCP - - name: https - port: 8181 - targetPort: https - protocol: TCP - - name: webserver - port: 8081 - targetPort: webserver - protocol: TCP - selector: - app.kubernetes.io/instance: calibre - app.kubernetes.io/name: calibre ---- -# Calibre-web Service -apiVersion: v1 -kind: Service -metadata: - name: calibre-web - namespace: calibre-system - labels: - app.kubernetes.io/instance: calibre - app.kubernetes.io/name: calibre-web - app.kubernetes.io/version: 0.6.25-ls361 -spec: - type: ClusterIP - ports: - - name: http - port: 8083 - targetPort: http - protocol: TCP - selector: - app.kubernetes.io/instance: calibre - app.kubernetes.io/name: calibre-web ---- -# Calibre Ingress (desktop GUI - for library management) -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: calibre - namespace: calibre-system - labels: - app.kubernetes.io/instance: calibre - app.kubernetes.io/name: calibre - annotations: - cert-manager.io/cluster-issuer: letsencrypt-prod - external-dns.alpha.kubernetes.io/hostname: calibre.dooplex.hu,calibre.home - nginx.ingress.kubernetes.io/proxy-body-size: "0" - nginx.ingress.kubernetes.io/proxy-read-timeout: "3600" - nginx.ingress.kubernetes.io/proxy-send-timeout: "3600" - nginx.ingress.kubernetes.io/ssl-redirect: "true" - nginx.ingress.kubernetes.io/configuration-snippet: | - set $geo_allowed 0; - if ($remote_addr ~ "^192\.168\.") { set $geo_allowed 1; } - if ($remote_addr ~ "^10\.") { set $geo_allowed 1; } - if ($geoip2_country_code = "HU") { set $geo_allowed 1; } - if ($geo_allowed = 0) { - return 403 "Access restricted to Hungary"; - } -spec: - ingressClassName: nginx-internal - tls: - - hosts: - - calibre.dooplex.hu - secretName: calibre-tls - rules: - - host: calibre.dooplex.hu - http: - paths: - - path: / - pathType: Prefix - backend: - service: - name: calibre - port: - number: 8080 - - host: calibre.home - http: - paths: - - path: / - pathType: Prefix - backend: - service: - name: calibre - port: - number: 8080 ---- -# Calibre-web Ingress (reading interface) -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: calibre-web - namespace: calibre-system - labels: - app.kubernetes.io/instance: calibre - app.kubernetes.io/name: calibre-web - annotations: - cert-manager.io/cluster-issuer: letsencrypt-prod - external-dns.alpha.kubernetes.io/hostname: books.dooplex.hu,books.home - nginx.ingress.kubernetes.io/proxy-body-size: "0" - nginx.ingress.kubernetes.io/proxy-read-timeout: "600" - nginx.ingress.kubernetes.io/proxy-send-timeout: "600" - nginx.ingress.kubernetes.io/ssl-redirect: "true" - nginx.ingress.kubernetes.io/configuration-snippet: | - set $geo_allowed 0; - if ($remote_addr ~ "^192\.168\.") { set $geo_allowed 1; } - if ($remote_addr ~ "^10\.") { set $geo_allowed 1; } - if ($geoip2_country_code = "HU") { set $geo_allowed 1; } - if ($geo_allowed = 0) { - return 403 "Access restricted to Hungary"; - } -spec: - ingressClassName: nginx-internal - tls: - - hosts: - - books.dooplex.hu - secretName: calibre-web-tls - rules: - - host: books.dooplex.hu - http: - paths: - - path: / - pathType: Prefix - backend: - service: - name: calibre-web - port: - number: 8083 - - host: books.home - http: - paths: - - path: / - pathType: Prefix - backend: - service: - name: calibre-web - port: - number: 8083 ---- -# Calibre Config PVC -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: calibre-config - namespace: calibre-system - labels: - app.kubernetes.io/instance: calibre - app.kubernetes.io/name: calibre - recurring-job-group.longhorn.io/needbackup: enabled - recurring-job.longhorn.io/source: enabled -spec: - accessModes: - - ReadWriteOnce - storageClassName: longhorn - resources: - requests: - storage: 2Gi ---- -# Calibre-web Config PVC -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: calibre-web-config - namespace: calibre-system - labels: - app.kubernetes.io/instance: calibre - app.kubernetes.io/name: calibre-web - recurring-job-group.longhorn.io/needbackup: enabled - recurring-job.longhorn.io/source: enabled -spec: - accessModes: - - ReadWriteOnce - storageClassName: longhorn - resources: - requests: - storage: 1Gi diff --git a/calibre-system/cwa.yaml b/calibre-system/cwa.yaml new file mode 100644 index 0000000..c6c69de --- /dev/null +++ b/calibre-system/cwa.yaml @@ -0,0 +1,240 @@ +--- +# Calibre-Web-Automated - All-in-one eBook library solution +# Replaces Calibre + Calibre-web with automation features +# Namespace +apiVersion: v1 +kind: Namespace +metadata: + name: calibre-system +--- +# Calibre-Web-Automated Deployment +apiVersion: apps/v1 +kind: Deployment +metadata: + name: calibre-web-automated + namespace: calibre-system + labels: + app.kubernetes.io/instance: calibre + app.kubernetes.io/name: calibre-web-automated +spec: + replicas: 1 + strategy: + type: Recreate + selector: + matchLabels: + app.kubernetes.io/instance: calibre + app.kubernetes.io/name: calibre-web-automated + template: + metadata: + labels: + app.kubernetes.io/instance: calibre + app.kubernetes.io/name: calibre-web-automated + annotations: + # Version checker pattern - CWA uses semantic versioning + match-regex.version-checker.io/calibre-web-automated: '^V?[0-9]+\.[0-9]+\.[0-9]+$' + spec: + containers: + - name: calibre-web-automated + image: crocodilestick/calibre-web-automated:latest + imagePullPolicy: IfNotPresent + env: + - name: PUID + value: "1000" + - name: PGID + value: "1000" + - name: TZ + value: Europe/Budapest + # Use default port 8083 + - name: CWA_PORT_OVERRIDE + value: "8083" + # Disable WAL mode if on network share (set to true if using NFS) + - name: NETWORK_SHARE_MODE + value: "false" + # Number of proxies in chain (Cloudflare -> nginx-ingress -> app) + - name: TRUSTED_PROXY_COUNT + value: "2" + ports: + - name: http + containerPort: 8083 + protocol: TCP + resources: + requests: + cpu: 100m + memory: 512Mi + limits: + cpu: "2" + memory: 2Gi + livenessProbe: + httpGet: + path: / + port: http + initialDelaySeconds: 120 + periodSeconds: 60 + timeoutSeconds: 10 + failureThreshold: 5 + readinessProbe: + httpGet: + path: / + port: http + initialDelaySeconds: 60 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 3 + startupProbe: + httpGet: + path: / + port: http + periodSeconds: 10 + timeoutSeconds: 5 + # CWA can take time to initialize, especially first run + failureThreshold: 60 + volumeMounts: + # Config directory for app database, logs, processed books backup + - name: config + mountPath: /config + # Book ingest folder - files here are DELETED after processing + - name: ingest + mountPath: /cwa-book-ingest + # Calibre library - your existing library location + - name: library + mountPath: /calibre-library + volumes: + - name: config + persistentVolumeClaim: + claimName: calibre-web-automated-config + # Ingest folder on hostPath for easy file dropping + - name: ingest + hostPath: + path: /mnt/4_hdd/data/calibre-ingest + type: DirectoryOrCreate + # Your existing Calibre library location + - name: library + hostPath: + path: /mnt/4_hdd/data/calibre + type: DirectoryOrCreate +--- +# Calibre-Web-Automated Service +apiVersion: v1 +kind: Service +metadata: + name: calibre-web-automated + namespace: calibre-system + labels: + app.kubernetes.io/instance: calibre + app.kubernetes.io/name: calibre-web-automated +spec: + type: ClusterIP + ports: + - name: http + port: 8083 + targetPort: http + protocol: TCP + selector: + app.kubernetes.io/instance: calibre + app.kubernetes.io/name: calibre-web-automated +--- +# Main Ingress (books.dooplex.hu - primary reading interface) +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: calibre-web-automated + namespace: calibre-system + labels: + app.kubernetes.io/instance: calibre + app.kubernetes.io/name: calibre-web-automated + annotations: + cert-manager.io/cluster-issuer: letsencrypt-prod + external-dns.alpha.kubernetes.io/hostname: books.dooplex.hu,books.home + nginx.ingress.kubernetes.io/proxy-body-size: "0" + nginx.ingress.kubernetes.io/proxy-read-timeout: "600" + nginx.ingress.kubernetes.io/proxy-send-timeout: "600" + nginx.ingress.kubernetes.io/ssl-redirect: "true" + # Forward auth headers for Authentik integration + nginx.ingress.kubernetes.io/auth-response-headers: Set-Cookie,X-authentik-username,X-authentik-groups,X-authentik-email,X-authentik-name,X-authentik-uid + nginx.ingress.kubernetes.io/auth-snippet: proxy_set_header X-Forwarded-Host $http_host; + nginx.ingress.kubernetes.io/configuration-snippet: | + set $geo_allowed 0; + if ($remote_addr ~ "^192\.168\.") { set $geo_allowed 1; } + if ($remote_addr ~ "^10\.") { set $geo_allowed 1; } + if ($geoip2_country_code = "HU") { set $geo_allowed 1; } + if ($geo_allowed = 0) { + return 403 "Access restricted to Hungary"; + } +spec: + ingressClassName: nginx-internal + tls: + - hosts: + - books.dooplex.hu + secretName: calibre-web-automated-tls + rules: + - host: books.dooplex.hu + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: calibre-web-automated + port: + number: 8083 + - host: books.home + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: calibre-web-automated + port: + number: 8083 +--- +# Config PVC - stores app.db, logs, processed_books backup +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: calibre-web-automated-config + namespace: calibre-system + labels: + app.kubernetes.io/instance: calibre + app.kubernetes.io/name: calibre-web-automated + recurring-job-group.longhorn.io/needbackup: enabled + recurring-job.longhorn.io/source: enabled +spec: + accessModes: + - ReadWriteOnce + storageClassName: longhorn + resources: + requests: + # Larger than typical - stores backup of processed books by default + storage: 10Gi +--- +# Optional: Authentik integration for SSO +# Uncomment and configure if using Authentik proxy authentication +# apiVersion: networking.k8s.io/v1 +# kind: Ingress +# metadata: +# name: calibre-web-automated-auth +# namespace: calibre-system +# annotations: +# cert-manager.io/cluster-issuer: letsencrypt-prod +# nginx.ingress.kubernetes.io/auth-url: http://authentik-outpost-proxy.authentik-system.svc.cluster.local:9000/outpost.goauthentik.io/auth/nginx +# nginx.ingress.kubernetes.io/auth-signin: https://auth.dooplex.hu/outpost.goauthentik.io/start?rd=$escaped_request_uri +# nginx.ingress.kubernetes.io/auth-response-headers: Set-Cookie,X-authentik-username,X-authentik-groups,X-authentik-email,X-authentik-name,X-authentik-uid +# nginx.ingress.kubernetes.io/auth-snippet: proxy_set_header X-Forwarded-Host $http_host; +# spec: +# ingressClassName: nginx-internal +# tls: +# - hosts: +# - books.dooplex.hu +# secretName: calibre-web-automated-tls +# rules: +# - host: books.dooplex.hu +# http: +# paths: +# - path: / +# pathType: Prefix +# backend: +# service: +# name: calibre-web-automated +# port: +# number: 8083 \ No newline at end of file