--- # 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