Compare commits

..

38 commits

Author SHA1 Message Date
c08ae2e334 ⬆️ Update ghcr.io/linuxserver/code-server Docker digest to 95a811f 2025-02-22 21:01:35 +00:00
571aa7d5c0 update README 2025-02-22 06:57:18 -05:00
930b4708a2 update README 2025-02-22 05:10:58 -05:00
fd488b67ba Update README.md 2025-02-22 03:02:36 -05:00
a273335c97 Update README.md 2025-02-22 02:46:27 -05:00
5dff719ba7 Update kubernetes/apps/production/arr/sabnzbd/helmrelease.yaml 2025-02-21 18:14:57 -05:00
8ae927e1f5 ⬆️ Update ghcr.io/linuxserver/kasm Docker digest to 64da6db 2025-02-20 22:15:19 -05:00
271dd195e6 update authentik cm 2025-02-20 15:33:51 -05:00
ff8f47ae94 update authentik host 2025-02-20 15:21:25 -05:00
085e689935 ⬆️ Update ghcr.io/linuxserver/jellyfin Docker digest to 075bc77 2025-02-20 15:11:43 -05:00
472c77ac69 ⬆️ Update searxng/searxng Docker digest to 0da476f 2025-02-20 15:11:20 -05:00
2f95a0926a ⬆️ Update ollama/ollama Docker tag to v0.5.11 2025-02-20 15:11:12 -05:00
652e54c82e update authentik config 2025-02-20 15:10:47 -05:00
b7913d1aa8 add more resources jellyseerr 2025-02-19 22:00:28 -05:00
0bac0c0100 update jellyseerr + pub domain 2025-02-19 21:46:43 -05:00
8899384780 update jellyseerr path 2025-02-19 16:04:32 -05:00
ee9ad86e8c add jellyseerr to kustomization 2025-02-19 16:01:08 -05:00
e4510912aa test add jellyseerr 2025-02-19 12:46:59 -05:00
bbfb108c9e update flaresolverr 2025-02-19 12:37:56 -05:00
6d1188ddfe fix renovate 2025-02-19 00:48:31 -05:00
1755ac4e1b add custom DNS nameserver to prowlarr and sonarr configurations 2025-02-19 00:05:56 -05:00
cb7163c123 add CoreDNS to DNS config test 2025-02-19 00:03:43 -05:00
3937d11814 test cluster first dns 2025-02-18 23:58:54 -05:00
9a5433277b update prowlarr port 2025-02-18 23:39:55 -05:00
82932972f2 revert 2025-02-18 23:08:05 -05:00
03a64791b7 add NET_ADMIN capability to qbitty pod security context 2025-02-18 23:06:41 -05:00
7f7299c443 update qbitty helm release to specify subPath for wireguard configuration 2025-02-18 22:58:56 -05:00
109ea66269 remove security context from qbitty helm release 2025-02-18 22:45:04 -05:00
d1d3a43903 fix qbitty 2025-02-18 22:39:23 -05:00
90c830e0e2 fix qbitty 2025-02-18 22:36:47 -05:00
bd5c0830df fix qbitty 2025-02-18 22:33:10 -05:00
32f645f51f update qbitty, sonarr,sab 2025-02-18 22:19:44 -05:00
928e59767e update sonarr api key 2025-02-18 21:10:09 -05:00
97bce71d51 update sonarr helmrelease 2025-02-18 21:07:45 -05:00
0c3d035aa3 update helmreleases 2025-02-18 20:45:45 -05:00
3962007574 Update radarr 2025-02-18 20:29:14 -05:00
652ad58fab test change permissions 2025-02-18 18:00:16 -05:00
8e9d6ed526 Update kubernetes/apps/production/arr/radarr/helmrelease.yaml 2025-02-18 17:55:18 -05:00
29 changed files with 546 additions and 262 deletions

View file

@ -37,6 +37,14 @@
"registryUrls": [
"https://emberstack.github.io/helm-charts"
]
},
{
"matchPackageNames": [
"app-template"
],
"registryUrls": [
"https://bjw-s.github.io/helm-charts"
]
}
],
"kubernetes": {

View file

@ -9,19 +9,76 @@
# iac (wip)
Currently migrating [Auto-Homelab](https://git.mafyuh.dev/mafyuh/Auto-Homelab), [Iac-Homelab](https://git.mafyuh.dev/mafyuh/IaC-Homelab), [ansible-playbooks](https://git.mafyuh.dev/mafyuh/ansible-playbooks) and [kub](https://git.mafyuh.dev/mafyuh/kub) repos into this one.
This is my homelab infrastructure, defined in code.
This is my homelab, defined in code.
</div>
---
<div align="center">
| Hypervisor | OS | Tools | VPS (arm) | Firewall | Misc. Automations |
|---|---|---|---|---|---|
| [![Proxmox](https://img.shields.io/badge/-Proxmox-%23c9d1d9?logo=Proxmox)](https://www.proxmox.com) | [![Ubuntu](https://img.shields.io/badge/Ubuntu_22.04-%23c9d1d9?&logo=ubuntu&logoColor=red)](https://releases.ubuntu.com/jammy/) [![Ubuntu](https://img.shields.io/badge/Ubuntu_24-%23c9d1d9?&logo=ubuntu&logoColor=red)](https://releases.ubuntu.com/noble/) | [![Forgejo](https://img.shields.io/badge/-Forgejo-%23c9d1d9?logo=forgejo&logoColor=orange)](https://forgejo.org/) [![Docker](https://img.shields.io/badge/-Docker-%23c9d1d9?logo=docker)](https://www.docker.com/) [![Renovate](https://img.shields.io/badge/-Renovate-%23c9d1d9?logo=renovate&logoColor=blue)](https://github.com/renovatebot/renovate) [![OpenTofu](https://img.shields.io/badge/-OpenTofu-%23c9d1d9?logo=opentofu&logoColor=black)](https://opentofu.org/) [![Packer](https://img.shields.io/badge/-Packer-%23c9d1d9?logo=packer)](https://www.packer.io/) [![Ansible](https://img.shields.io/badge/-Ansible-%23c9d1d9?logo=ansible&logoColor=red)](https://www.ansible.com/) | [![Oracle](https://img.shields.io/badge/-Oracle_Cloud-%23c9d1d9?logo=oracle&logoColor=red)](https://www.oracle.com/cloud/) | [![pfSense](https://img.shields.io/badge/-pfSense-%23c9d1d9?logo=pfsense&logoColor=blue)](https://www.pfsense.org/) | [![n8n](https://img.shields.io/badge/-n8n-%23c9d1d9?logo=n8n)](https://n8n.io/)
| Hypervisor | OS | Tools | Firewall | Misc. Automations |
|---|---|---|---|---|
| [![Proxmox](https://img.shields.io/badge/-Proxmox-%23c9d1d9?logo=Proxmox)](https://www.proxmox.com) | [![Debian](https://img.shields.io/badge/Debian-%23c9d1d9?&logo=debian&logoColor=black)](https://www.debian.org/) [![Ubuntu](https://img.shields.io/badge/Ubuntu-%23c9d1d9?&logo=ubuntu&logoColor=red)](https://releases.ubuntu.com/noble/) | [![Forgejo](https://img.shields.io/badge/-Forgejo-%23c9d1d9?logo=forgejo&logoColor=orange)](https://forgejo.org/) [![Docker](https://img.shields.io/badge/-Docker-%23c9d1d9?logo=docker)](https://www.docker.com/) [![Kubernetes](https://img.shields.io/badge/-Kubernetes-%23c9d1d9?logo=kubernetes)](https://k3s.io/) [![Renovate](https://img.shields.io/badge/-Renovate-%23c9d1d9?logo=renovate&logoColor=blue)](https://github.com/renovatebot/renovate) [![OpenTofu](https://img.shields.io/badge/-OpenTofu-%23c9d1d9?logo=opentofu)](https://opentofu.org/) [![Packer](https://img.shields.io/badge/-Packer-%23c9d1d9?logo=packer)](https://www.packer.io/) [![Ansible](https://img.shields.io/badge/-Ansible-%23c9d1d9?logo=ansible&logoColor=red)](https://www.ansible.com/) | [![pfSense](https://img.shields.io/badge/-pfSense-%23c9d1d9?logo=pfsense&logoColor=blue)](https://www.pfsense.org/) | [![n8n](https://img.shields.io/badge/-n8n-%23c9d1d9?logo=n8n)](https://n8n.io/) [![Actions](https://img.shields.io/badge/-Actions-%23c9d1d9?logo=forgejo&logoColor=orange)](https://forgejo.org/docs/latest/user/actions/)
</div>
## To-Do
## 📖 **Overview**
This repository contains the IaC ([Infrastructure as Code](https://en.wikipedia.org/wiki/Infrastructure_as_code)) configuration for my homelab.
Most of my homelab runs on **Proxmox**, with VMs managed and maintained using [OpenTofu](https://opentofu.org/). All VMs are cloned from templates I created with [Packer](https://www.packer.io/).
All services are **containerized**, either managed with **Docker Compose** or **orchestrated with Kubernetes ([K3s](https://k3s.io/))**. Over time, Ive been migrating everything to Kubernetes using **[GitOps](https://en.wikipedia.org/wiki/DevOps) practices**, which is my long-term goal.
To automate infrastructure updates, I use **Forgejo Actions**, which trigger workflows upon changes to this repo. This ensures seamless deployment and maintenance across my homelab:
- **[Flux](https://fluxcd.io/)** manages Continuous Deployment (CD) for Kubernetes, bootstrapped via [OpenTofu](https://git.mafyuh.dev/mafyuh/iac/src/branch/main/terraform/flux/main.tf).
- **[Docker CD Workflow](https://git.mafyuh.dev/mafyuh/iac/src/branch/main/.forgejo/workflows/CD.yml)** handles Continuous Deployment for Docker services.
- **[Renovate](https://github.com/renovatebot/renovate)** keeps services updated by opening PRs for new versions.
- **[Yamllint](https://github.com/adrienverge/yamllint)** ensures configuration files are properly structured.
- **[Ansible](https://github.com/ansible/ansible)** is used to execute playbooks on all of my VMs, automating management and configurations
### 🔒 **Security & Networking**
For Secret management I use [Bitwarden Secrets](https://bitwarden.com/products/secrets-manager/) and their various [integrations](https://bitwarden.com/help/ansible-integration/) into the tools used.
> Kubernetes is using SOPS with Age encryption until migration over to Bitwarden Secrets.
I use **Oracle Cloud** for their [Always-Free](https://www.oracle.com/cloud/free/) VM's and deploy Docker services that require uptime here (Uptime Kuma, this website). [Twingate](https://www.twingate.com/) is used to connect my home network to the various VPS's securely using [Zero Trust architecture](https://en.wikipedia.org/wiki/Zero_trust_architecture).
I use **Cloudflare** for my DNS provider with **Cloudflare Tunnels** to expose some of the services to the world. **Cloudflare Access** is used to restrict the access to some of the services, this is paired with **Fail2Ban** looking through all my reverse proxy logs for malicious actors who made it through **Access** and banning them via **Cloudflare WAF**.
For my home network I use **PfSense** with VLAN segmentation and strict firewall rules to isolate public-facing machines, ensuring they can only communicate with the necessary services and nothing else.
### **📊 Monitoring & Observability**
I use a combination of **Grafana, Loki, and Prometheus** with various exporters to collect and visualize system metrics, logs, and alerts. This helps maintain visibility into my infrastructure and detect issues proactively.
- **Prometheus** Metrics collection and alerting
- **Loki** Centralized logging for containers and VMs
- **Grafana** Dashboarding and visualization
- **Exporters** Node Exporter, cAdvisor, Blackbox Exporter, etc.
## 🧑‍💻 **Getting Started**
This repo is not structured like a project you can easily replicate. Although if you are new to any of the tools used I encourage you to read through the directories that make up each tool to see how I am using them.
Over time I will try to add more detailed instructions in each directories README.
Some good references for how I learned this stuff (other than RTM)
- [Kubernetes Cluster Setup](https://technotim.live/posts/k3s-etcd-ansible/)
- [Kubernetes + Flux](https://technotim.live/posts/flux-devops-gitops/)
- [Kubernetes Secrets with SOPS](https://technotim.live/posts/secret-encryption-sops/)
- [Packer with Proxmox](https://www.youtube.com/watch?v=1nf3WOEFq1Y)
- [Terraform with Proxmox](https://www.youtube.com/watch?v=dvyeoDBUtsU)
- [Docker](https://www.youtube.com/watch?v=eGz9DS-aIeY)
- [Ansible](https://www.youtube.com/watch?v=goclfp6a2IQ)
## 🖥️ **Hardware**
| Name | Device | CPU | RAM | Storage | Purpose |
|------------|--------------|----------------|-------------|--------------------------------|--------------------------------|
| Arc-Ripper | Optiplex 3050 | Intel i5-6500 | 32 GB DDR4 | 1TB NVMe | Jellyfin Server, Blu-ray Ripper |
| PVE Node 1 | Custom | Intel i7-9700K | 64 GB DDR4 | NVMe for boot and VMs, 4x4TB HDD RaidZ10 | Main node with most VMs, NAS |
| PVE Node 2 | Custom | Intel i7-8700K | 64 GB DDR4 | 1x2TB NVMe | More VMs |
## 📌 **To-Do**
See [Project Board](https://git.mafyuh.dev/mafyuh/iac/projects/2)

View file

@ -1,6 +1,6 @@
services:
ollama:
image: ollama/ollama:0.5.10
image: ollama/ollama:0.5.11
container_name: ollama
restart: unless-stopped
networks:
@ -39,7 +39,7 @@ services:
- host.docker.internal:host-gateway
searxng:
image: searxng/searxng@sha256:e22d8617effc484649d01fa80614b4859e134c6b77a5d2a2cff9236789aa1749
image: searxng/searxng@sha256:0da476ff64bf801e3b36fd3c79c50f30f7041ab78b27cbc8c189c4c6f8c696d6
container_name: searxng
networks:
- ai-stack

View file

@ -148,7 +148,7 @@ services:
## Should move this to Ubu
code-server:
image: ghcr.io/linuxserver/code-server@sha256:5c900277e10a8c2868d4db86d0870c94096c9e3140ec9480cb7c47726b9d059c
image: ghcr.io/linuxserver/code-server@sha256:95a811ff3262083bbbc2b14fc03d4b65271140be904a8e0cabc2e320233474a7
container_name: code-server
environment:
- PUID=1000

View file

@ -1,7 +1,7 @@
---
services:
jellyfin:
image: ghcr.io/linuxserver/jellyfin@sha256:7cdcd4b6b60765290af7a2740960ce30c1f5548313ae60f7e23f6995ed4d147e
image: ghcr.io/linuxserver/jellyfin@sha256:075bc77361e6466f5cd546c9d97646428cc1f26d4b355991e8f66d0ffbc7c15a
container_name: jellyfin
devices:
- /dev/dri/renderD129:/dev/dri/renderD129

View file

@ -1,7 +1,7 @@
---
services:
kasm:
image: ghcr.io/linuxserver/kasm@sha256:5ff0ef8bd7f279cb6806aae9caabe5457eaadd89fb0f02e63ce26dcdac747d10
image: ghcr.io/linuxserver/kasm@sha256:64da6db15ab574d67f9fbdcc812796f00f259be543e6dc2e60ad4f5d6c05d005
container_name: kasm
privileged: true
environment:

View file

@ -30,4 +30,10 @@ spec:
cpu: "100m"
limits:
memory: "300Mi"
cpu: "200m"
cpu: "200m"
dnsPolicy: None
dnsConfig:
nameservers:
- 10.43.0.10
- 1.1.1.1
- 8.8.8.8

View file

@ -0,0 +1,111 @@
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: &app jellyseerr
namespace: arr
spec:
interval: 15m
chart:
spec:
chart: app-template
version: 3.7.1
interval: 30m
sourceRef:
kind: HelmRepository
name: bjw-s
namespace: flux-system
install:
remediation:
retries: 3
upgrade:
remediation:
retries: 3
values:
global:
fullnameOverride: *app
namespace: arr
controllers:
jellyseerr:
enabled: true
type: statefulset
annotations:
reloader.stakater.com/auto: "true"
replicas: 1
statefulset:
volumeClaimTemplates:
- name: jellyseerr-config
accessMode: ReadWriteOnce
size: 2Gi
storageClass: longhorn
globalMounts:
- path: /app/config
pod:
securityContext:
runAsUser: 1000
runAsGroup: &group 1000
fsGroup: *group
fsGroupChangePolicy: "OnRootMismatch"
dnsPolicy: None
dnsConfig:
nameservers:
- 10.43.0.10
- 1.1.1.1
- 8.8.8.8
containers:
app:
image:
repository: fallenbagel/jellyseerr
tag: 2.3.0
pullPolicy: IfNotPresent
env:
TZ: "${TZ}"
LOG_LEVEL: info
probes:
liveness:
enabled: false
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
resources:
requests:
cpu: 20m
memory: 128Mi
limits:
memory: 256Mi
service:
app:
primary: true
controller: jellyseerr
ports:
http:
port: 5055
ingress:
internal:
enabled: true
className: nginx
hosts:
- host: "request.${PUBLIC_DOMAIN}"
paths:
- path: /
pathType: Prefix
service:
identifier: app
port: http
tls:
- hosts:
- "request.${PUBLIC_DOMAIN}"
secretName: mafyuh-dev-production-tls

View file

@ -0,0 +1,4 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- helmrelease.yaml

View file

@ -4,6 +4,7 @@ resources:
- bazarr/
- flaresolverr/
- prowlarr/
- jellyseerr/
- qbitty/
- radarr/
- recyclarr/

View file

@ -1,53 +0,0 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: prowlarr
namespace: arr
labels:
app: prowlarr
spec:
replicas: 1
selector:
matchLabels:
app: prowlarr
template:
metadata:
labels:
app: prowlarr
spec:
securityContext:
runAsUser: 65534
runAsGroup: 65534
fsGroup: 65534
fsGroupChangePolicy: OnRootMismatch
containers:
- name: prowlarr
image: ghcr.io/onedr0p/prowlarr:rolling@sha256:7234ae8ca5b14153baddf42257cc2ddc928695ce604d11a9616b635eca0e43e7
imagePullPolicy: IfNotPresent
resources:
requests:
memory: 512Mi
cpu: 150m
limits:
memory: 2Gi
cpu: 500m
volumeMounts:
- mountPath: /config
name: prowlarr-config
volumes:
- name: prowlarr-config
persistentVolumeClaim:
claimName: prowlarr-config
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: prowlarr-config
namespace: arr
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: longhorn

View file

@ -0,0 +1,124 @@
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: &app prowlarr
namespace: arr
spec:
interval: 15m
chart:
spec:
chart: app-template
version: 3.7.1
interval: 30m
sourceRef:
kind: HelmRepository
name: bjw-s
namespace: flux-system
install:
remediation:
retries: 3
upgrade:
remediation:
retries: 3
values:
global:
fullnameOverride: *app
namespace: arr
controllers:
prowlarr:
enabled: true
type: statefulset
annotations:
reloader.stakater.com/auto: "true"
replicas: 1
statefulset:
volumeClaimTemplates:
- name: prowlarr-config
accessMode: ReadWriteOnce
size: 3Gi
storageClass: longhorn
globalMounts:
- path: /config
pod:
securityContext:
runAsUser: 1000
runAsGroup: &group 1000
fsGroup: *group
fsGroupChangePolicy: "OnRootMismatch"
dnsPolicy: None
dnsConfig:
nameservers:
- 10.43.0.10
- 1.1.1.1
- 8.8.8.8
containers:
app:
image:
repository: ghcr.io/onedr0p/prowlarr
tag: 1.30.2.4939
pullPolicy: IfNotPresent
env:
TZ: "${TZ}"
PROWLARR__INSTANCE_NAME: *app
PROWLARR__PORT: &port 9696
PROWLARR__APPLICATION_URL: "https://prowlarr.${LOCAL_DOMAIN}"
PROWLARR__THEME: dark
PROWLARR__LOG_LEVEL: info
probes:
liveness:
enabled: false
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
resources:
requests:
cpu: 50m
memory: 150Mi
limits:
memory: 512Mi
service:
app:
primary: true
controller: prowlarr
ports:
http:
port: *port
ingress:
internal:
enabled: true
className: nginx
hosts:
- host: "prowlarr.${LOCAL_DOMAIN}"
paths:
- path: /
pathType: Prefix
service:
identifier: app
port: http
tls:
- hosts:
- "prowlarr.${LOCAL_DOMAIN}"
secretName: local-mafyuh-dev-production-tls
persistence:
data:
enabled: true
type: nfs
server: "${NAS_IP}"
path: /mnt/thePool/thePoolShare
globalMounts:
- path: /data

View file

@ -1,22 +0,0 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: prowlarr
namespace: arr
spec:
ingressClassName: nginx
rules:
- host: "prowlarr.local.mafyuh.dev"
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: headless-prowlarr
port:
number: 9696
tls:
- hosts:
- "prowlarr.local.mafyuh.dev"
secretName: local-mafyuh-dev-production-tls

View file

@ -1,6 +1,4 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
- service.yaml
- ingress.yaml
- helmrelease.yaml

View file

@ -1,13 +0,0 @@
apiVersion: v1
kind: Service
metadata:
name: headless-prowlarr
namespace: arr
spec:
selector:
app: prowlarr
ports:
- port: 9696
targetPort: 9696
protocol: TCP
type: ClusterIP

View file

@ -1,99 +0,0 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: qbitty
namespace: arr
labels:
app: qbitty
spec:
replicas: 1
selector:
matchLabels:
app: qbitty
template:
metadata:
labels:
app: qbitty
spec:
containers:
- name: qbitty
image: ghcr.io/hotio/qbittorrent@sha256:43312cb59ec3054d99848481f0913336275b7afa18ef814d2091e0b87509fc23
imagePullPolicy: IfNotPresent
env:
- name: VPN_ENABLED
value: "true"
- name: VPN_CONF
value: "wg0"
- name: VPN_PROVIDER
value: "proton"
- name: VPN_KEEP_LOCAL_DNS
value: "false"
- name: VPN_AUTO_PORT_FORWARD
value: "true"
- name: VPN_LAN_NETWORK
valueFrom:
secretKeyRef:
name: lan-network
key: lan-network
- name: VPN_LAN_LEAK_ENABLED
value: "false"
- name: VPN_FIREWALL_TYPE
value: "auto"
- name: PRIVOXY_ENABLED
value: "false"
- name: WEBUI_PORT
value: "8080"
- name: VPN_HEALTHCHECK_ENABLED
value: "false"
- name: UNBOUND_ENABLED
value: "false"
resources:
requests:
memory: "256Mi"
cpu: "100m"
limits:
memory: "1Gi"
cpu: "5000m"
volumeMounts:
- mountPath: /config
name: qbitty-conf
- mountPath: /data
name: nas
- mountPath: /config/wireguard/
name: wireguard-config
- mountPath: /incomplete
name: qbitty-incomplete
securityContext:
capabilities:
add: ["NET_ADMIN"]
ports:
- containerPort: 8080
name: webui
protocol: TCP
volumes:
- name: nas
nfs:
path: /mnt/thePool/thePoolShare
server: 10.0.0.10
- name: qbitty-conf
persistentVolumeClaim:
claimName: qbitty-conf
- name: wireguard-config
secret:
secretName: qbitty-wireguard
- name: qbitty-incomplete
emptyDir:
sizeLimit: 100Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: qbitty-conf
namespace: arr
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
storageClassName: longhorn

View file

@ -0,0 +1,137 @@
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: &app qbitty
namespace: arr
spec:
interval: 15m
chart:
spec:
chart: app-template
version: 3.7.1
interval: 30m
sourceRef:
kind: HelmRepository
name: bjw-s
namespace: flux-system
install:
remediation:
retries: 3
upgrade:
remediation:
retries: 3
values:
global:
fullnameOverride: *app
namespace: arr
controllers:
qbitty:
enabled: true
type: statefulset
annotations:
reloader.stakater.com/auto: "true"
replicas: 1
statefulset:
volumeClaimTemplates:
- name: qbitty-config
accessMode: ReadWriteOnce
size: 500Mi
storageClass: longhorn
globalMounts:
- path: /config
containers:
app:
image:
repository: ghcr.io/hotio/qbittorrent
tag: release-5.0.4
pullPolicy: IfNotPresent
env:
TZ: "${TZ}"
WEBUI_PORT: &port 8080
VPN_ENABLED: "true"
VPN_CONF: "wg0"
VPN_PROVIDER: "proton"
VPN_KEEP_LOCAL_DNS: "false"
VPN_AUTO_PORT_FORWARD: "true"
VPN_LAN_NETWORK:
valueFrom:
secretKeyRef:
name: lan-network
key: lan-network
VPN_LAN_LEAK_ENABLED: "false"
VPN_FIREWALL_TYPE: "auto"
PRIVOXY_ENABLED: "false"
VPN_HEALTHCHECK_ENABLED: "false"
UNBOUND_ENABLED: "false"
probes:
liveness:
enabled: false
securityContext:
capabilities:
add:
- NET_ADMIN
resources:
requests:
cpu: 20m
memory: 200Mi
limits:
memory: 4000Mi
service:
app:
primary: true
controller: qbitty
ports:
http:
port: *port
ingress:
internal:
enabled: true
className: nginx
hosts:
- host: "qbitty.${LOCAL_DOMAIN}"
paths:
- path: /
pathType: Prefix
service:
identifier: app
port: http
tls:
- hosts:
- "qbitty.${LOCAL_DOMAIN}"
secretName: local-mafyuh-dev-production-tls
persistence:
data:
enabled: true
type: nfs
server: "${NAS_IP}"
path: /mnt/thePool/thePoolShare
globalMounts:
- path: /data
incomplete:
enabled: true
type: emptyDir
sizeLimit: 100Gi
globalMounts:
- path: /incomplete
wireguard-config:
enabled: true
type: secret
name: qbitty-wireguard
defaultMode: 0400
globalMounts:
- path: /config/wireguard/wg0.conf
subPath: wg0.conf

View file

@ -1,22 +0,0 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: qbitty
namespace: arr
spec:
ingressClassName: nginx
rules:
- host: "qbitty.local.mafyuh.dev"
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: qbitty
port:
number: 8080
tls:
- hosts:
- "qbitty.local.mafyuh.dev"
secretName: local-mafyuh-dev-production-tls

View file

@ -1,6 +1,4 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
- service.yaml
- ingress.yaml
- helmrelease.yaml

View file

@ -1,13 +0,0 @@
apiVersion: v1
kind: Service
metadata:
name: qbitty
namespace: arr
spec:
selector:
app: qbitty
ports:
- port: 8080
targetPort: 8080
protocol: TCP
type: ClusterIP

View file

@ -46,9 +46,15 @@ spec:
- path: /config
pod:
securityContext:
runAsUser: 1000
runAsGroup: &group 1000
fsGroup: *group
fsGroupChangePolicy: "OnRootMismatch"
dnsPolicy: None
dnsConfig:
nameservers:
- 10.43.0.10
- 1.1.1.1
- 8.8.8.8
@ -64,16 +70,22 @@ spec:
RADARR__PORT: &port 7878
RADARR__APPLICATION_URL: "https://radarr.${LOCAL_DOMAIN}"
RADARR__THEME: dark
RADARR__LOG_LEVEL: debug
RADARR__LOG_LEVEL: info
probes:
liveness:
enabled: false
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
resources:
requests:
cpu: 200m
memory: 300Mi
cpu: 50m
memory: 150Mi
limits:
memory: 512Mi

View file

@ -44,10 +44,15 @@ spec:
pod:
securityContext:
runAsUser: &context 65534
runAsUser: &context 1000
runAsGroup: *context
fsGroup: *context
fsGroupChangePolicy: "OnRootMismatch"
dnsPolicy: None
dnsConfig:
nameservers:
- 1.1.1.1
- 8.8.8.8
containers:
app:

View file

@ -38,8 +38,8 @@ spec:
statefulset:
volumeClaimTemplates:
- name: config
accessMode: ReadWriteMany
- name: sabnzbd-config
accessMode: ReadWriteOnce
size: 500Mi
storageClass: longhorn
globalMounts:
@ -47,10 +47,16 @@ spec:
pod:
securityContext:
runAsUser: 65534
runAsGroup: &group 65534
runAsUser: 1000
runAsGroup: &group 1000
fsGroup: *group
fsGroupChangePolicy: "OnRootMismatch"
dnsPolicy: None
dnsConfig:
nameservers:
- 10.43.0.10
- 1.1.1.1
- 8.8.8.8
containers:
app:
@ -61,6 +67,12 @@ spec:
env:
TZ: "${TZ}"
SABNZBD__PORT: &port 8080
SABNZBD__HOST_WHITELIST_ENTRIES: >-
{{ .Release.Name }},
{{ .Release.Name }}.arr,
{{ .Release.Name }}.arr.svc,
{{ .Release.Name }}.arr.svc.cluster.local,
sab.${LOCAL_DOMAIN}
probes:
liveness:
@ -92,7 +104,7 @@ spec:
enabled: true
className: nginx
hosts:
- host: "sabnzbd.${LOCAL_DOMAIN}"
- host: "sab.${LOCAL_DOMAIN}"
paths:
- path: /
pathType: Prefix
@ -101,7 +113,7 @@ spec:
port: http
tls:
- hosts:
- "sabnzbd.${LOCAL_DOMAIN}"
- "sab.${LOCAL_DOMAIN}"
secretName: local-mafyuh-dev-production-tls
persistence:
@ -111,4 +123,11 @@ spec:
server: "${NAS_IP}"
path: /mnt/thePool/thePoolShare
globalMounts:
- path: /data
- path: /data
incomplete:
enabled: true
type: emptyDir
sizeLimit: 100Gi
globalMounts:
- path: /incomplete

View file

@ -38,8 +38,8 @@ spec:
statefulset:
volumeClaimTemplates:
- name: config
accessMode: ReadWriteMany
- name: sonarr-config
accessMode: ReadWriteOnce
size: 3Gi
storageClass: longhorn
globalMounts:
@ -47,10 +47,16 @@ spec:
pod:
securityContext:
runAsUser: 65534
runAsGroup: &group 65534
runAsUser: 1000
runAsGroup: &group 1000
fsGroup: *group
fsGroupChangePolicy: "OnRootMismatch"
dnsPolicy: None
dnsConfig:
nameservers:
- 10.43.0.10
- 1.1.1.1
- 8.8.8.8
containers:
app:

View file

@ -4,7 +4,7 @@ metadata:
name: authentik-values
namespace: authentik
data:
values.yaml: ENC[AES256_GCM,data:vdNxG8ySftHb/nSx7OyGs87Nk3nmy7WYJ4xJt5AHce/x1T6zShgbTrqB7uU7I/lG3C83bjQXuNSANdRdEWyEoTDPunWZ9gBftaM+6N4z30ndo/095RGlguG+0Llhz9Y1fLEEIVCtom9Pv9IdadL7dDayb3lvyQHsYYcLE93/eJXcaZo0ENYNtNq0nliRTx6Vt0HfKhCu0MzPbkoOS3nx0wBzJ6IRNqBHZShcbsRHT7Ud7Ohb2jRw9jwplqktkTrd6t/Q/Nq66wwuvKSokxkwb/JYCmvsEHrfl72YCSeP9cbXyiuYLvr8l+ganyas/XpaTkrjS3TWqfzQJA4XWARkSFZE80rfrmPCrIDbSt1UkdHkaM+S1MV8nRTbx3q9vbErT/GiyGgOFMUNSAPdRTtEh2roSz8fgrlsd56ZyLCYcbv2olQTvo9Gggr25taCONX3b2AbVkYpAThVTQe5eCl+SlxeDPDhSjx9aFI8J2SZnZ2wsbGo95Pmf8mmulcant7NuK5JnQMh+z9dzTimhJXkpBusMPk59KU7pMNbhqzQfOJ3HRR+srnFOzRHrcUrAiojAMasDoU+lBJZznqe9dQv5+/Qexci/oWLd39bTvxVTY0btd0bKrLlQYNRULKZktvm4Qg6p8kktJNkEuTHUaNBotHKuIBfqmJdhUd2clso4PHz93jJXUTWWeGbtmTUkZuelzYTs/MRFIXeOvJUJAJa1QyTz6GK5So5VNsRxdUq+12oEmUd8RDtt7Ft0vzgEkDp4eND/AuX8Ex3llvz74K4cY59ldgWJSVpLrYJGzIQZKjdX6DHvavsqKCM7AvYrrybNF1ct43yC/janL/ELV1nOTQSAVLn9osQ8k5sbuZ1wOE76PjSZPsrubHbc85T5ejVORCtjRK/xmRVK3WjNZhD1Cnk1b6aTydEx60sHPEr7Mhx3Z5+t4Szf15x+QqhJnY4hshbj62kXsYcdRg35LhwEPNABXkfv+1ekjJ2tmzobi7foxfIB7oyI2GOtHYA37jGsR03zPdwjRIv5XNwao6RpOtGvcXHEUH9gBctGWYw6RNHQ7trKr2i4Du3gj8/qH9Eg/E3NBPU4NLjJNMq3Y1WFoPGxu9yzM8KZjlE4ZIPPSS8Bp93oN1YXgesrmXv1kFnvcD19sOh6cCsBmknP8RFTkWOKYiEea6DYwg8A+kc/YNSrikVzUqQTZEew89dziW7+9L7GlLsGuXycYxW4IZHxMaKlzfXc9AzAb4BuANsYHaML4Ymy/Vtha3qdB/Nss9VQjXe00YUvifMmIWMS9ea1kb6qTIzBzYoNTTt+9tXUNwAleAWN2rQJo9ifpzfQuptHZ2C9IKgNQQmRGF2zAkpoTDtqx/IUKvxuTHGh8W3g2ZNHc4j2mhGx7QG8bYtJ6FrzrVEslK6u1StuU1WzIhzir8A1CmkuLTRSihymKmM0fAF9VJ0bydxPbn0QTsMrgsGwz6JtPAeOW2Umh3IpcvkbeyRy0X3eZaj,iv:EWpc+nAIXNqVpPn2DC3EL/bfEzM6PTtRXdLtYF5OqgY=,tag:a50CftQxTxy6mOLAxi//Ow==,type:str]
values.yaml: ENC[AES256_GCM,data:n/ITNeK+JVQB5AI5MiDDcxu5RapIPTuDxqJLIHysopawa5gCHwgppnLKv9tW6Sg9B4Tqb3FT8e2zgoVVhQ3+lRvC6HRVhB9+Em+gB8zu7aeOnfd3l3Cj6oSQkjVLxjDCdHHGU/9KFm5YToJER0tzMBXS3M/apvN9+B/VKDI+D/1FDz2bG66QoK+oWd0pq/BShZ1nMhvZXxQ8TFkpQKORnF8qwYq+ArY2ucAsoWbbs4QzEYxqVVa6BmRrpoXlK9i8ak9zTTRn6iPgWf5dhBkvexCI///jZODTYWWiiDo7XQBjS8C4xA4rOK99cav1QhA5j6tPGEKhdNNk2z/ViolFfpzEj4KBdvRSmu/fFBCIka9aP6ZFWU7efIcP2qS3KrIibosQ1Wr4va+P9wzmDA+wSGxKsxeA1BkUhrs9t/+hc6fdsXT30+4sM70zZOJ0+nH9UwNDpJjBfOpc9soAItPzXzWTlX7JCei8CGnloAMrekc3ShQI2L2pHRNLsTDMXJq6Goc3Xk5OF4PC/jjVxSVisXki7qEVZoUKZeoM81i1MXfIOFcGUBfRnntVPK8dBw44KVlPaD4iamRwh3juhy4X/bKWpKs9o5mIB+eQIOiNH5Nxm9g0oI5Ck1A6h/KtJwiHYFc7SH+qhzSubym9x52l960ar18N5zt6oqWz6peFmYY7lGxqBh5muHobWTJ/4QF7Lr3KDZvK5C5ppnxb0/AENbH+t6bQ1ZavOhMs2ojELnL2sG/eXWDXQ8+5OlN0/uCOWHTZ7FtgBhfFXJ/SsU/nquk6aC4smv/boKP1JKJBihAs7yhJMbWBDTHUSNPUef39E7FzyMYqYYU5hxmEfytlt3ZD0Y62rF4zPJBmA2cZzqYAWK2qXhXvpdMcEvTbUEJ3ez6cgHQvEyXutZUiyoN+3YesK8VyXHzq5A6VX/AX7nl5G+P3Afwi/+a6SkkmJ6Q9dVAeEe7CsIrJheNNlweA5aT+GzUD2dNtsjb6/1yQGYejfu/3Ve/0qyHkykBJDwMTLbb3W13/BRzXPhrUIz+nglBlWB3zzVOIQ5Gdx2X9htcvIyiYTZ0epUFEGjZYUzd8/d4WazwjvUFACFpooDSQgMWd5ODTmSn/kvWd+IR6Zxr/cg0UiGnDDUmbhRy/uwSGvkmb/evodweBvij1bbilgGmuO0X9TWVtXQkw7Vii/SS69+Imy/iap07zJJBobfyTU7hZvgrc/BWHqW2oHPYu4tTuKgbOopjPX+vkylu+FYC4seqOXUNvCczF0l712+RWXQpFF/iKBDbviI0twTFF4Qmn,iv:Xsg10IX3Q+UjyoaMGrqbf1i9zsTOndZ3IvBatViwBV4=,tag:FPDrUpu5KM0S7TxLVNxIfA==,type:str]
sops:
kms: []
gcp_kms: []
@ -20,8 +20,8 @@ sops:
RndrQ2JxZnMxZlBIM3RHS0E1WTlZQzQK7oTkv/PG3poAdYnqXnzX3j5ZUgMa3GFB
aQtceF96jKRltwPrnUgZZ5EadTaLyGAD30fqvUJ9/oP6NLe7kmsTWg==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-02-17T01:33:23Z"
mac: ENC[AES256_GCM,data:cz25q40TD7XWnJWIu9FgS55LsfORvfFRpNgp0Zju66i6IBF3NakUjfo48rD/Nu9ebEC8iIpo8P3Y2YT6w0wPDWGDLkww0iLzFIr8IMWzCS1wrIyaq/BZmzh26jd4r2qY1knqQAqlVdOJ9grPqjBxKxed/o3Lu++Irp7n7dOY0rA=,iv:HUCgrKlLC1u/3/oeQLM3alBRWc0hf3YhhsuMYowKYCU=,tag:pUWKkQ2sy0sPPWAcK0yqnQ==,type:str]
lastmodified: "2025-02-20T20:33:40Z"
mac: ENC[AES256_GCM,data:rL+ugPPHcRzpHA70mmn7BLdhO0PG63EMqaHq7eJfBguIcdREGrQCpGQbbw6YN2GGCuE8NWB6sLHaUVn09LMywNfcUT4Hw1kInXRxzZ+L4M4UdqjUCCQj69UGGPnXoyM5GopCIA60/JVTtsQ9EPmJHJJI8LYQrQEtT6O+5FnlaMo=,iv:Jnst3uaJArcxM29hqrVPHKSSAW7Ac84xG6LJP2lz0+g=,tag:J/OAZq4dHXOOiE243Xo0LA==,type:str]
pgp: []
encrypted_regex: ^(data|stringData|secret_key|password|hosts)$
version: 3.9.4

View file

@ -0,0 +1,18 @@
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: mafyuh-dev
namespace: cert-manager
spec:
secretName: mafyuh-dev-production-tls
secretTemplate:
annotations:
reflector.v1.k8s.emberstack.com/reflection-auto-enabled: "true"
reflector.v1.k8s.emberstack.com/reflection-allowed: "true"
issuerRef:
name: letsencrypt-production
kind: ClusterIssuer
commonName: "*.mafyuh.dev"
dnsNames:
- "*.mafyuh.dev"

View file

@ -18,3 +18,4 @@ spec:
selector:
dnsZones:
- local.mafyuh.dev
- mafyuh.dev

View file

@ -2,6 +2,7 @@ apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- certificates/local.yaml
- certificates/public.yaml
- helmrelease.yaml
- helmrepo.yaml
- issuers/letsencrypt.yaml

View file

@ -5,8 +5,8 @@ metadata:
namespace: arr
type: Opaque
stringData:
RADARR_API_KEY: ENC[AES256_GCM,data:7TG0ku1JbJ2u4SuoCOJTIYbaNipuw+4ZVIkvkdIvcGM=,iv:AABASIeiNPi76yxvVIHFqzOHgkdn5fg2r2NCnRS9Eqk=,tag:QV35b8Yo345rFnf29oYLMA==,type:str]
SONARR_API_KEY: ENC[AES256_GCM,data:0FfjBWrWHrQJWjki5nXZG+nuM35jEq4DMOi0wzKVU8M=,iv:dlgFto0t+ED33jQkZ0GVyUhcEZnqPHMspAYOQ2FN5g0=,tag:B2RDZ+qdofxCcQaxFQNPog==,type:str]
RADARR_API_KEY: ENC[AES256_GCM,data:eMGcEuKJxh0ZW9TFOSEeBSaJkLiT1A/rZpZYs2rq7vs=,iv:eYPVbiYKKBc8rYcd8yqIpT01g2SZuMHdpv5Dh/sWO5o=,tag:qyqR2YYcKY7FLa+97cvThg==,type:str]
SONARR_API_KEY: ENC[AES256_GCM,data:PjU7Qse/GzarQa3PPp8BB6G2AWz4ib3Y6Dqq6YV8QLI=,iv:QkGlkG9yOi4w9ZEc0Pkice8MZXqKFctnKMAxkdJ8FTY=,tag:/P2U2tgAMZIZ8IeqG9l9jA==,type:str]
sops:
kms: []
gcp_kms: []
@ -22,8 +22,8 @@ sops:
KzdOczVjakovQlE1TkF4VUJORk5IdWsKx12AioJfcpmzCAbI+RwrJW1607YYsQbf
N8EKX70kyhdlwyCMDwr7B0+eFAWsJAjsR+2Z91peXCxlfeVXu28eFQ==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-02-18T05:24:59Z"
mac: ENC[AES256_GCM,data:Fr6LRYW21WjwyWlQLY3V3KqmM6JrQvfs4kVSgLr+a4RhlYp1qWFP7EbFvcdJbCCuvHi5f1xRDsW7s01nKth0Qw97h14aJVxsyEgD7R/OoI4sfJMQBEryV8JZWwzUqr2lnZ5dqow4kxdw/LTakVxDzDcSF4jOUFV1vRKcncB+zRA=,iv:DtoO7ewd43R3TnenfvDTMJfZi4GxupDQody/v3BzMT8=,tag:ahaN3mRHfB7IjtdhihkBGw==,type:str]
lastmodified: "2025-02-19T02:10:01Z"
mac: ENC[AES256_GCM,data:JRDy6M1idGEX9M5Xn0Tli+ojStM94H756vDWPJamde1Wl3F9r0YVzcgtnHBl6NO0RnSSjQhEuTkZnSp737uEBizStTddKwDQ3L2MNFHYQ9c56PVkdXaFFmhnV7YYoX6YjlvsBPfitm8skKo9OE0B1Zkv0Jkr3W4uOzwF8tz1Opo=,iv:Plj+bp028byD38RrBqo8JC0z7f3cfdw3pforCt9MW80=,tag:OG2cLmaw//nVWLR3xSg3DQ==,type:str]
pgp: []
encrypted_regex: ^(data|stringData)$
version: 3.9.4