155 lines
5.2 KiB
YAML
155 lines
5.2 KiB
YAML
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: qbittorrent
|
|
namespace: qbittorrent
|
|
spec:
|
|
# qBittorrent has one writable configuration volume and one Proton port
|
|
# forwarding lease, so upgrades replace the Pod rather than overlap two.
|
|
replicas: 1
|
|
strategy:
|
|
type: Recreate
|
|
selector:
|
|
matchLabels:
|
|
app: qbittorrent
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app: qbittorrent
|
|
spec:
|
|
# The SOPS-managed Secret is read-only, but Hotio writes Proton's current
|
|
# forwarded port beside wg0.conf. Copy the secret into a writable emptyDir
|
|
# without ever storing the plaintext WireGuard key in Git.
|
|
initContainers:
|
|
- name: prepare-wireguard-config
|
|
image: busybox:1.37.0
|
|
command:
|
|
- sh
|
|
- -ec
|
|
- >-
|
|
cp /vpn-secret/wg0.conf /wireguard/wg0.conf &&
|
|
chmod 0600 /wireguard/wg0.conf
|
|
volumeMounts:
|
|
- name: wireguard-secret
|
|
mountPath: /vpn-secret
|
|
readOnly: true
|
|
- name: wireguard-runtime
|
|
mountPath: /wireguard
|
|
containers:
|
|
- name: qbittorrent
|
|
image: ghcr.io/hotio/qbittorrent:release
|
|
imagePullPolicy: Always
|
|
# Hotio automatically permits the Pod's directly attached /24 but
|
|
# rejects that same subnet in VPN_LAN_NETWORK. Add every *other* /24
|
|
# from this cluster's 10.244.0.0/21 Pod range at runtime so traffic
|
|
# from ingress-nginx and media apps works regardless of scheduling.
|
|
command:
|
|
- /bin/sh
|
|
- -ec
|
|
- |
|
|
own_octet="${POD_IP#10.244.}"
|
|
own_octet="${own_octet%%.*}"
|
|
case "$own_octet" in
|
|
0|1|2|3|4|5|6|7) ;;
|
|
*) echo "Unexpected Pod IP: $POD_IP" >&2; exit 1 ;;
|
|
esac
|
|
for octet in 0 1 2 3 4 5 6 7; do
|
|
if [ "$octet" != "$own_octet" ]; then
|
|
VPN_LAN_NETWORK="${VPN_LAN_NETWORK},10.244.${octet}.0/24"
|
|
fi
|
|
done
|
|
export VPN_LAN_NETWORK
|
|
exec /init
|
|
securityContext:
|
|
# Hotio needs this capability to create the WireGuard interface,
|
|
# routes, firewall rules, and VPN kill switch inside the Pod.
|
|
capabilities:
|
|
add:
|
|
- NET_ADMIN
|
|
env:
|
|
- name: POD_IP
|
|
valueFrom:
|
|
fieldRef:
|
|
fieldPath: status.podIP
|
|
- name: PUID
|
|
value: "1000"
|
|
- name: PGID
|
|
value: "1000"
|
|
- name: UMASK
|
|
value: "002"
|
|
- name: TZ
|
|
value: Europe/London
|
|
- name: WEBUI_PORTS
|
|
value: 8080/tcp
|
|
- name: VPN_ENABLED
|
|
value: "true"
|
|
- name: VPN_CONF
|
|
value: wg0
|
|
- name: VPN_PROVIDER
|
|
value: proton
|
|
# Permit the physical LAN to reach the Web UI/API without allowing
|
|
# ordinary internet traffic to bypass the VPN. Do not add the
|
|
# Kubernetes Pod CIDR here: Hotio detects the Pod's attached network
|
|
# itself and rejects an overlapping VPN_LAN_NETWORK route.
|
|
- name: VPN_LAN_NETWORK
|
|
value: 10.10.0.0/16
|
|
- name: VPN_LAN_LEAK_ENABLED
|
|
value: "false"
|
|
# Proton assigns a dynamic inbound port through NAT-PMP. Hotio
|
|
# renews it and updates qBittorrent's listening port automatically.
|
|
- name: VPN_AUTO_PORT_FORWARD
|
|
value: "true"
|
|
- name: VPN_HEALTHCHECK_ENABLED
|
|
value: "true"
|
|
- name: VPN_NAMESERVERS
|
|
value: wg
|
|
ports:
|
|
- name: http
|
|
containerPort: 8080
|
|
protocol: TCP
|
|
# Proton must negotiate a forwarded port before qBittorrent starts
|
|
# its Web UI, so avoid expected connection-refused events during that
|
|
# normal initialization window.
|
|
startupProbe:
|
|
httpGet:
|
|
path: /
|
|
port: http
|
|
initialDelaySeconds: 30
|
|
periodSeconds: 5
|
|
timeoutSeconds: 3
|
|
failureThreshold: 36
|
|
readinessProbe:
|
|
httpGet:
|
|
path: /
|
|
port: http
|
|
periodSeconds: 10
|
|
timeoutSeconds: 5
|
|
failureThreshold: 3
|
|
livenessProbe:
|
|
httpGet:
|
|
path: /
|
|
port: http
|
|
periodSeconds: 30
|
|
timeoutSeconds: 10
|
|
failureThreshold: 3
|
|
volumeMounts:
|
|
- name: qbittorrent-config
|
|
mountPath: /config
|
|
- name: wireguard-runtime
|
|
mountPath: /config/wireguard
|
|
- name: torrents
|
|
mountPath: /data/torrents
|
|
volumes:
|
|
- name: qbittorrent-config
|
|
persistentVolumeClaim:
|
|
claimName: qbittorrent-config
|
|
- name: wireguard-secret
|
|
secret:
|
|
secretName: qbittorrent-wireguard
|
|
- name: wireguard-runtime
|
|
emptyDir: {}
|
|
- name: torrents
|
|
nfs:
|
|
server: nas.ahmza.com
|
|
path: /srv/media/torrents
|