diff --git a/bootstrap/kustomizations/kustomization-media.yaml b/bootstrap/kustomizations/kustomization-media.yaml deleted file mode 100644 index 1681221..0000000 --- a/bootstrap/kustomizations/kustomization-media.yaml +++ /dev/null @@ -1,34 +0,0 @@ -apiVersion: kustomize.toolkit.fluxcd.io/v1 -kind: Kustomization -metadata: - name: media - namespace: flux-system -spec: - interval: 15m - path: ./media - prune: true # remove any elements later removed from the above path - timeout: 2m # if not set, this defaults to interval duration, which is 1h - sourceRef: - kind: GitRepository - name: flux-system - healthChecks: - - apiVersion: apps/v1 - kind: Deployment - name: prowlarr - namespace: media - - apiVersion: apps/v1 - kind: Deployment - name: qbittorrent - namespace: media - - apiVersion: apps/v1 - kind: Deployment - name: radarr - namespace: media - - apiVersion: apps/v1 - kind: Deployment - name: readarr - namespace: media - - apiVersion: apps/v1 - kind: Deployment - name: sonarr - namespace: media diff --git a/bootstrap/kustomizations/kustomization-qbittorrent.yaml b/bootstrap/kustomizations/kustomization-qbittorrent.yaml new file mode 100644 index 0000000..09cd774 --- /dev/null +++ b/bootstrap/kustomizations/kustomization-qbittorrent.yaml @@ -0,0 +1,18 @@ +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: qbittorrent + namespace: flux-system +spec: + interval: 15m + path: ./qbittorrent + prune: true # remove any elements later removed from the above path + timeout: 2m # if not set, this defaults to interval duration, which is 1h + sourceRef: + kind: GitRepository + name: flux-system + healthChecks: + - apiVersion: apps/v1 + kind: Deployment + name: qbittorrent + namespace: qbittorrent diff --git a/bootstrap/namespaces/namespace-media.yaml b/bootstrap/namespaces/namespace-qbittorrent.yaml similarity index 67% rename from bootstrap/namespaces/namespace-media.yaml rename to bootstrap/namespaces/namespace-qbittorrent.yaml index d592f0d..6bf78a7 100644 --- a/bootstrap/namespaces/namespace-media.yaml +++ b/bootstrap/namespaces/namespace-qbittorrent.yaml @@ -1,4 +1,4 @@ apiVersion: v1 kind: Namespace metadata: - name: media + name: qbittorrent diff --git a/qbittorrent/deployment.yaml b/qbittorrent/deployment.yaml new file mode 100644 index 0000000..5100b75 --- /dev/null +++ b/qbittorrent/deployment.yaml @@ -0,0 +1,66 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: qbittorrent + namespace: qbittorrent +spec: + selector: + matchLabels: + app: qbittorrent + template: + metadata: + labels: + app: qbittorrent + spec: + containers: + - name: qbittorrent + image: lscr.io/linuxserver/qbittorrent:latest + envFrom: + - configMapRef: + name: qbittorrent-config + optional: false + ports: + - containerPort: 8080 + name: http + protocol: TCP + volumeMounts: + - name: qbittorrent-config + mountPath: /config + - name: data + mountPath: /data/downloads + subPath: downloads + - name: gluetun + image: qmcgaw/gluetun + envFrom: + - configMapRef: + name: gluetun-config + securityContext: + capabilities: + add: + - NET_ADMIN + volumeMounts: + - name: wireguard-config-secret + mountPath: /gluetun/wireguard + initContainers: + - name: init-media-filesystem + image: busybox + command: + - /bin/sh + - -c + - | + mkdir -p -v /data/downloads/movies /data/downloads/tv /data/downloads/books /data/downloads/audiobooks /data/media/movies /data/media/tv /data/media/books /data/media/audiobooks + chown -R 1000:1000 /data + chmod -R a=,a+rX,u+w,g+w /data + volumeMounts: + - mountPath: /data + name: data + volumes: + - name: qbittorrent-config + persistentVolumeClaim: + claimName: qbittorrent-config + - name: data + persistentVolumeClaim: + claimName: data + - name: wireguard-config-secret + secret: + secretName: wireguard-config-secret diff --git a/qbittorrent/dns-endpoint.yaml b/qbittorrent/dns-endpoint.yaml new file mode 100644 index 0000000..f897364 --- /dev/null +++ b/qbittorrent/dns-endpoint.yaml @@ -0,0 +1,12 @@ +apiVersion: externaldns.k8s.io/v1alpha1 +kind: DNSEndpoint +metadata: + name: qbittorrent.michaelthomson.dev + namespace: qbittorrent +spec: + endpoints: + - dnsName: qbittorrent.michaelthomson.dev + recordTTL: 180 + recordType: CNAME + targets: + - server.michaelthomson.dev diff --git a/qbittorrent/gluetun-config.yaml b/qbittorrent/gluetun-config.yaml new file mode 100644 index 0000000..c89745a --- /dev/null +++ b/qbittorrent/gluetun-config.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: gluetun-config + namespace: qbittorrent +data: + VPN_SERVICE_PROVIDER: custom + VPN_TYPE: wireguard + VPN_PORT_FORWARDING: on + VPN_PORT_FORWARDING_PROVIDER: protonvpn diff --git a/qbittorrent/ingress.yaml b/qbittorrent/ingress.yaml new file mode 100644 index 0000000..d0bdfb7 --- /dev/null +++ b/qbittorrent/ingress.yaml @@ -0,0 +1,25 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: qbittorrent + namespace: qbittorrent + annotations: + traefik.ingress.kubernetes.io/router.entrypoints: websecure + traefik.ingress.kubernetes.io/router.middlewares: traefik-authentik@kubernetescrd + traefik.ingress.kubernetes.io/router.tls: "true" +spec: + rules: + - host: qbittorrent.michaelthomson.dev + http: + paths: + - pathType: ImplementationSpecific + path: / + backend: + service: + name: qbittorrent + port: + name: http + tls: + - hosts: + - qbittorrent.michaelthomson.dev + secretName: letsencrypt-wildcard-cert-michaelthomson.dev diff --git a/qbittorrent/pvc-data.yaml b/qbittorrent/pvc-data.yaml new file mode 100644 index 0000000..ad978d6 --- /dev/null +++ b/qbittorrent/pvc-data.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: data + namespace: qbittorrent +spec: + accessModes: + - ReadWriteOnce + storageClassName: longhorn + resources: + requests: + storage: 300Gi diff --git a/qbittorrent/pvc-qbittorrent-config.yaml b/qbittorrent/pvc-qbittorrent-config.yaml new file mode 100644 index 0000000..e20b330 --- /dev/null +++ b/qbittorrent/pvc-qbittorrent-config.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: qbittorrent-config + namespace: qbittorrent +spec: + resources: + requests: + storage: 1Gi + storageClassName: longhorn + accessModes: + - ReadWriteOnce diff --git a/qbittorrent/qbittorrent-config.yaml b/qbittorrent/qbittorrent-config.yaml new file mode 100644 index 0000000..3093c61 --- /dev/null +++ b/qbittorrent/qbittorrent-config.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: qbittorrent-config + namespace: qbittorrent +data: + PUID: "1000" + PGID: "1000" + DOCKER_MODS: arafatamim/linuxserver-io-mod-vuetorrent diff --git a/qbittorrent/service.yaml b/qbittorrent/service.yaml new file mode 100644 index 0000000..597245d --- /dev/null +++ b/qbittorrent/service.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: Service +metadata: + name: qbittorrent + namespace: qbittorrent +spec: + selector: + app: qbittorrent + ports: + - port: 80 + targetPort: http + name: http diff --git a/qbittorrent/wireguard-config-secret.yaml b/qbittorrent/wireguard-config-secret.yaml new file mode 100644 index 0000000..b38fcfc --- /dev/null +++ b/qbittorrent/wireguard-config-secret.yaml @@ -0,0 +1,14 @@ +kind: SealedSecret +apiVersion: bitnami.com/v1alpha1 +metadata: + name: wireguard-config-secret + namespace: qbittorrent + creationTimestamp: +spec: + template: + metadata: + name: wireguard-config-secret + namespace: qbittorrent + creationTimestamp: + encryptedData: + wg0.conf: AgDdF/rwKFANlByNG4But/CCqBC0BlQECdh4KartOeFaraA5EdqTo3G59q5uaC3nPmtyWFrzisi4nHORJc4rLDnhkg4l183WA4uVkry7KX8clO5yxZ5MeufnOjS/Mus81ckf1D+KWwUz1Z+N5N6kEa65bcnX3umqAc+i9dzjP0Ns+1eTVHwsSKJB+sbaDCN4+EeTjSYPfu3or52iJ/UACvK3ZnfCRiSYOUwl2dzOhioIKZZ6IF7uLqrHPXcJtU0X9CgTgsKou5LIuj1cNkXhaJLUWfNAaXP66rhtsBxs3SQw4rEi06nqm5201wSK2r5DSFiG3ndLbgn/4titKN0J5fa/IGq0aUPCI4x71qFoWcbq/oQnItk5QLCERGykElslKsaDphZwkFLuUYA53hXEsmqduuNKRrXpn0d+ic7O4McwtdyZkK6DVNiI+kzjSL8BipZmoAZg6LUXHcV0vTqsSly50QzTOfNtUh19XK8eBuDAtWHbd0KhXOok5IWu63eTsFUgxbCPF7Ua2tVieMLqwc5zw3GFiCfmcE7LUjr0g8KBEoKKtNo5pDv8Znvb7LjcPNNxJF6MDMmQpA1Krc7HYaEnZNRisFpaRcgpI3Ds82TnX/TCT562dqvpsado7fPqHTeonyo/47T8ZfATgBbwvya8e+8BZdXpNmJL88KR7tCOTUYLWD8UBZYb9McC7YIef5XKhTe+dvZatp6cZ9cWyx4iWWsgwsNMZgF9fGDKg6KLjk2bLZ493pkjXn6tOedCWes8DNzPug/1bmzi/OKHlDy4k7kVCB2kQVNdQbgKHr5eA4ueG27/OjWcs3jQ9WtXt6hAw5ljeKbmmKLQruw6Ss02Zq7toourNBmJXmmeNN8i4em7e5BiEhzRDVNPmtrJUnW7qPkvi7cTZXnjshkEa3+HN2k3Z6oiFay/KJ1/UyfR3v83GIpAjh/CpYA2q3QDWc2l2+NEUMUJkVkCZC4gUkrP5LRYGvsIumnshbTgftqBzWexnSWiHBSOYbGf4li3ICwZlbxgU6j0w75K+bNCaKvXjawlHNtdD7zbpL5TMF4W2OiSD2ddjpSUXh0rnYahfvkEAWLjRJKL+Mw/lp7YJ8UHD/gqQM4nE/FHB3TxvOnp6ERLOWkquRWLiN2j6NXVZqXcZDxUu8hteJNRhqI2UDJinV0ErD3FucK800lB