From 16913ebbc7c03130da0049402305240812be157a Mon Sep 17 00:00:00 2001 From: kisfenyo Date: Sat, 20 Dec 2025 11:34:29 +0100 Subject: [PATCH] added calibre and adventurelog --- adventurelog-system/anventurelog.yaml | 474 ++++++++++++++++++++++++++ argocd-apps/homelab.yaml | 45 +++ calibre-system/calibre.yaml | 351 +++++++++++++++++++ 3 files changed, 870 insertions(+) create mode 100644 adventurelog-system/anventurelog.yaml create mode 100644 calibre-system/calibre.yaml diff --git a/adventurelog-system/anventurelog.yaml b/adventurelog-system/anventurelog.yaml new file mode 100644 index 0000000..3bcb62f --- /dev/null +++ b/adventurelog-system/anventurelog.yaml @@ -0,0 +1,474 @@ +--- +# AdventureLog System - Travel/Adventure logging application +# Namespace +apiVersion: v1 +kind: Namespace +metadata: + name: adventurelog-system +--- +# PostgreSQL with PostGIS Deployment +apiVersion: apps/v1 +kind: Deployment +metadata: + name: adventurelog-postgres + namespace: adventurelog-system + labels: + app.kubernetes.io/instance: adventurelog + app.kubernetes.io/name: postgres +spec: + replicas: 1 + strategy: + type: Recreate + selector: + matchLabels: + app.kubernetes.io/instance: adventurelog + app.kubernetes.io/name: postgres + template: + metadata: + labels: + app.kubernetes.io/instance: adventurelog + app.kubernetes.io/name: postgres + spec: + securityContext: + fsGroup: 999 + containers: + - name: postgres + image: postgis/postgis:16-3.5 + imagePullPolicy: IfNotPresent + env: + - name: POSTGRES_USER + valueFrom: + secretKeyRef: + name: adventurelog-db + key: username + - name: POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: adventurelog-db + key: password + - name: POSTGRES_DB + value: adventurelog + - name: PGDATA + value: /var/lib/postgresql/data/pgdata + ports: + - name: postgres + containerPort: 5432 + protocol: TCP + resources: + requests: + cpu: 100m + memory: 256Mi + limits: + cpu: "1" + memory: 1Gi + volumeMounts: + - name: data + mountPath: /var/lib/postgresql/data + subPath: data + volumes: + - name: data + persistentVolumeClaim: + claimName: adventurelog-postgres +--- +# Backend Deployment +apiVersion: apps/v1 +kind: Deployment +metadata: + name: adventurelog-backend + namespace: adventurelog-system + labels: + app.kubernetes.io/instance: adventurelog + app.kubernetes.io/name: backend + app.kubernetes.io/version: latest +spec: + replicas: 1 + strategy: + type: Recreate + selector: + matchLabels: + app.kubernetes.io/instance: adventurelog + app.kubernetes.io/name: backend + template: + metadata: + labels: + app.kubernetes.io/instance: adventurelog + app.kubernetes.io/name: backend + app.kubernetes.io/version: latest + spec: + containers: + - name: backend + image: ghcr.io/seanmorley15/adventurelog-backend:latest + imagePullPolicy: Always + env: + # Django settings + - name: DJANGO_ADMIN_USERNAME + valueFrom: + secretKeyRef: + name: adventurelog-admin + key: username + - name: DJANGO_ADMIN_PASSWORD + valueFrom: + secretKeyRef: + name: adventurelog-admin + key: password + - name: DJANGO_ADMIN_EMAIL + valueFrom: + secretKeyRef: + name: adventurelog-admin + key: email + - name: SECRET_KEY + valueFrom: + secretKeyRef: + name: adventurelog-admin + key: secret-key + # Public URL - update to your domain + - name: PUBLIC_URL + value: https://adventures.dooplex.hu + - name: CSRF_TRUSTED_ORIGINS + value: https://adventures.dooplex.hu,https://adventures.home + # Disable user registration (set to True to allow) + - name: DISABLE_REGISTRATION + value: "False" + # Database + - name: PGHOST + value: adventurelog-postgres + - name: PGPORT + value: "5432" + - name: PGDATABASE + value: adventurelog + - name: PGUSER + valueFrom: + secretKeyRef: + name: adventurelog-db + key: username + - name: PGPASSWORD + valueFrom: + secretKeyRef: + name: adventurelog-db + key: password + # SMTP Configuration + - name: EMAIL_BACKEND + value: email + - name: EMAIL_HOST + valueFrom: + secretKeyRef: + name: smtp-credentials + key: host + - name: EMAIL_PORT + valueFrom: + secretKeyRef: + name: smtp-credentials + key: port + - name: EMAIL_USE_TLS + value: "True" + - name: EMAIL_USE_SSL + value: "False" + - name: EMAIL_HOST_USER + valueFrom: + secretKeyRef: + name: smtp-credentials + key: username + - name: EMAIL_HOST_PASSWORD + valueFrom: + secretKeyRef: + name: smtp-credentials + key: password + - name: DEFAULT_FROM_EMAIL + valueFrom: + secretKeyRef: + name: smtp-credentials + key: from-address + # Frontend URL (for CORS) + - name: FRONTEND_URL + value: https://adventures.dooplex.hu + # Optional: Google Maps API (commented out - uses OpenStreetMap by default) + # Requires billing enabled on Google Cloud, but has free tier for personal use + # - name: GOOGLE_MAPS_API_KEY + # valueFrom: + # secretKeyRef: + # name: adventurelog-google + # key: api-key + ports: + - name: http + containerPort: 80 + protocol: TCP + resources: + requests: + cpu: 100m + memory: 256Mi + limits: + cpu: "1" + memory: 1Gi + livenessProbe: + httpGet: + path: /api/ + port: http + initialDelaySeconds: 60 + periodSeconds: 30 + timeoutSeconds: 10 + failureThreshold: 5 + readinessProbe: + httpGet: + path: /api/ + port: http + initialDelaySeconds: 30 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 3 + volumeMounts: + - name: media + mountPath: /code/media + volumes: + - name: media + hostPath: + path: /mnt/4_hdd/data/adventurelog + type: DirectoryOrCreate +--- +# Frontend Deployment +apiVersion: apps/v1 +kind: Deployment +metadata: + name: adventurelog-frontend + namespace: adventurelog-system + labels: + app.kubernetes.io/instance: adventurelog + app.kubernetes.io/name: frontend + app.kubernetes.io/version: latest +spec: + replicas: 1 + strategy: + type: Recreate + selector: + matchLabels: + app.kubernetes.io/instance: adventurelog + app.kubernetes.io/name: frontend + template: + metadata: + labels: + app.kubernetes.io/instance: adventurelog + app.kubernetes.io/name: frontend + app.kubernetes.io/version: latest + spec: + containers: + - name: frontend + image: ghcr.io/seanmorley15/adventurelog-frontend:latest + imagePullPolicy: Always + env: + # Public-facing URL + - name: PUBLIC_SERVER_URL + value: http://adventurelog-backend + - name: ORIGIN + value: https://adventures.dooplex.hu + - name: BODY_SIZE_LIMIT + value: "Infinity" + ports: + - name: http + containerPort: 3000 + protocol: TCP + resources: + requests: + cpu: 50m + memory: 128Mi + limits: + cpu: 500m + memory: 512Mi + livenessProbe: + httpGet: + path: / + port: http + initialDelaySeconds: 30 + periodSeconds: 30 + timeoutSeconds: 10 + failureThreshold: 3 + readinessProbe: + httpGet: + path: / + port: http + initialDelaySeconds: 15 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 3 +--- +# PostgreSQL Service +apiVersion: v1 +kind: Service +metadata: + name: adventurelog-postgres + namespace: adventurelog-system + labels: + app.kubernetes.io/instance: adventurelog + app.kubernetes.io/name: postgres +spec: + type: ClusterIP + ports: + - name: postgres + port: 5432 + targetPort: postgres + protocol: TCP + selector: + app.kubernetes.io/instance: adventurelog + app.kubernetes.io/name: postgres +--- +# Backend Service +apiVersion: v1 +kind: Service +metadata: + name: adventurelog-backend + namespace: adventurelog-system + labels: + app.kubernetes.io/instance: adventurelog + app.kubernetes.io/name: backend + app.kubernetes.io/version: latest +spec: + type: ClusterIP + ports: + - name: http + port: 80 + targetPort: http + protocol: TCP + selector: + app.kubernetes.io/instance: adventurelog + app.kubernetes.io/name: backend +--- +# Frontend Service +apiVersion: v1 +kind: Service +metadata: + name: adventurelog-frontend + namespace: adventurelog-system + labels: + app.kubernetes.io/instance: adventurelog + app.kubernetes.io/name: frontend + app.kubernetes.io/version: latest +spec: + type: ClusterIP + ports: + - name: http + port: 3000 + targetPort: http + protocol: TCP + selector: + app.kubernetes.io/instance: adventurelog + app.kubernetes.io/name: frontend +--- +# Main Ingress (Frontend + Backend API) +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: adventurelog + namespace: adventurelog-system + labels: + app.kubernetes.io/instance: adventurelog + app.kubernetes.io/name: adventurelog + annotations: + cert-manager.io/cluster-issuer: letsencrypt-prod + external-dns.alpha.kubernetes.io/hostname: adventures.dooplex.hu,adventures.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" +spec: + ingressClassName: nginx-internal + tls: + - hosts: + - adventures.dooplex.hu + secretName: adventurelog-tls + rules: + - host: adventures.dooplex.hu + http: + paths: + # Backend API routes + - path: /api + pathType: Prefix + backend: + service: + name: adventurelog-backend + port: + number: 80 + - path: /admin + pathType: Prefix + backend: + service: + name: adventurelog-backend + port: + number: 80 + - path: /media + pathType: Prefix + backend: + service: + name: adventurelog-backend + port: + number: 80 + - path: /static + pathType: Prefix + backend: + service: + name: adventurelog-backend + port: + number: 80 + # Frontend (default) + - path: / + pathType: Prefix + backend: + service: + name: adventurelog-frontend + port: + number: 3000 + - host: adventures.home + http: + paths: + - path: /api + pathType: Prefix + backend: + service: + name: adventurelog-backend + port: + number: 80 + - path: /admin + pathType: Prefix + backend: + service: + name: adventurelog-backend + port: + number: 80 + - path: /media + pathType: Prefix + backend: + service: + name: adventurelog-backend + port: + number: 80 + - path: /static + pathType: Prefix + backend: + service: + name: adventurelog-backend + port: + number: 80 + - path: / + pathType: Prefix + backend: + service: + name: adventurelog-frontend + port: + number: 3000 +--- +# PostgreSQL PVC +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: adventurelog-postgres + namespace: adventurelog-system + labels: + app.kubernetes.io/instance: adventurelog + app.kubernetes.io/name: postgres + recurring-job-group.longhorn.io/needbackup: enabled + recurring-job.longhorn.io/source: enabled +spec: + accessModes: + - ReadWriteOnce + storageClassName: longhorn + resources: + requests: + storage: 5Gi +--- diff --git a/argocd-apps/homelab.yaml b/argocd-apps/homelab.yaml index 2427af7..cac56cb 100644 --- a/argocd-apps/homelab.yaml +++ b/argocd-apps/homelab.yaml @@ -417,3 +417,48 @@ spec: syncPolicy: syncOptions: - CreateNamespace=true +--- +# Calibre +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: calibre + namespace: argocd + finalizers: + - resources-finalizer.argocd.argoproj.io +spec: + project: homelab + source: + repoURL: https://gitea.dooplex.hu/admin/homelab-manifests.git + targetRevision: main + path: calibre-system + destination: + server: https://kubernetes.default.svc + namespace: calibre-system + syncPolicy: + syncOptions: + - CreateNamespace=true + - PruneLast=true +--- +# Uptimekuma +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: adventurelog + namespace: argocd + finalizers: + - resources-finalizer.argocd.argoproj.io +spec: + project: homelab + source: + repoURL: https://gitea.dooplex.hu/admin/homelab-manifests.git + targetRevision: main + path: adventurelog-system + destination: + server: https://kubernetes.default.svc + namespace: adventurelog-system + syncPolicy: + syncOptions: + - CreateNamespace=true + - PruneLast=true +--- diff --git a/calibre-system/calibre.yaml b/calibre-system/calibre.yaml new file mode 100644 index 0000000..5845793 --- /dev/null +++ b/calibre-system/calibre.yaml @@ -0,0 +1,351 @@ +--- +# 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 + app.kubernetes.io/version: v8.16.2-ls375 +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 + app.kubernetes.io/version: v8.16.2-ls375 + spec: + securityContext: + fsGroup: 1000 + containers: + - name: calibre + image: lscr.io/linuxserver/calibre:v8.16.2-ls375 + imagePullPolicy: IfNotPresent + env: + - name: PUID + value: "1000" + - name: PGID + value: "1000" + - name: TZ + value: Europe/Budapest + 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: 2Gi + 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 + 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: v0.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 + app.kubernetes.io/version: v0.6.25-ls361 + spec: + securityContext: + fsGroup: 1000 + containers: + - name: calibre-web + image: lscr.io/linuxserver/calibre-web:v0.6.25-ls361 + 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 + 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: v0.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" +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" +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