Kubernetes and k3s
The manifests deploy one Tidefetch pod with a Recreate strategy, two PVCs, a secret-mounted password, non-root security settings, health probes, and a ClusterIP service.
Prerequisites
- Kubernetes 1.27 or newer, including k3s
- A default StorageClass or explicit storage classes in
storage.yaml - A published Tidefetch image accessible to cluster nodes
kubectland this repository checkout
Review storage
Defaults:
- Config PVC: 2 GiB,
ReadWriteOnce - Downloads PVC: 100 GiB,
ReadWriteOnce
Edit packaging/kubernetes/storage.yaml before applying. For a specific class:
spec:
storageClassName: longhorn
On k3s, the default local-path class ties data to one node. Longhorn, NFS CSI,
or another replicated class is preferable when node failure must not strand
the queue.
Create namespace and password
kubectl apply -f packaging/kubernetes/namespace.yaml
umask 077
openssl rand -base64 36 > web-password
kubectl -n tidefetch create secret generic tidefetch-web-password \
--from-file=password=./web-password
cat web-password
rm web-password
Save the displayed password in a password manager.
Deploy
kubectl apply -k packaging/kubernetes
kubectl -n tidefetch rollout status deployment/tidefetch --timeout=180s
kubectl -n tidefetch get pods,pvc,service
Test without an Ingress:
kubectl -n tidefetch port-forward service/tidefetch 8210:8210
Open http://127.0.0.1:8210.
Ingress and TLS
Copy the example, replace the hostname and issuer, then apply:
cp packaging/kubernetes/ingress.example.yaml /tmp/tidefetch-ingress.yaml
$EDITOR /tmp/tidefetch-ingress.yaml
kubectl apply -f /tmp/tidefetch-ingress.yaml
kubectl -n tidefetch get ingress
The application must remain at the hostname root. Current ingress controllers support its WebSocket endpoint without special annotations. See Reverse proxy and TLS.
Expose BitTorrent peer ports
The base service exposes only the web UI inside the cluster. Add a LoadBalancer service if inbound peers are required:
apiVersion: v1
kind: Service
metadata:
name: tidefetch-bittorrent
namespace: tidefetch
spec:
type: LoadBalancer
externalTrafficPolicy: Local
selector:
app.kubernetes.io/name: tidefetch
ports:
- name: bittorrent-tcp
port: 6881
targetPort: bittorrent-tcp
protocol: TCP
- name: bittorrent-udp
port: 6881
targetPort: bittorrent-udp
protocol: UDP
MetalLB is a common LoadBalancer implementation for bare-metal homelabs. Point router forwarding for TCP/UDP 6881 at the assigned address. Do not expose aria2 RPC port 6800.
Pin and update the image
Edit deployment.yaml to a release tag or digest:
image: ghcr.io/thre4dripper/tidefetch:0.2.0
Apply and watch the Recreate rollout:
kubectl apply -k packaging/kubernetes
kubectl -n tidefetch rollout status deployment/tidefetch
kubectl -n tidefetch logs deployment/tidefetch --tail=100
Recreate intentionally allows downtime so two aria2 processes never mount and write the same session volume.
Rotate the password
umask 077
openssl rand -base64 36 > web-password
kubectl -n tidefetch create secret generic tidefetch-web-password \
--from-file=password=./web-password \
--dry-run=client -o yaml | kubectl apply -f -
rm web-password
kubectl -n tidefetch rollout restart deployment/tidefetch
kubectl -n tidefetch rollout status deployment/tidefetch
Existing browser sessions end when the pod restarts.
Backups
Prefer CSI VolumeSnapshots when the storage driver supports them. Otherwise, scale down and back up the mounted PVC from a temporary pod or the storage backend:
kubectl -n tidefetch scale deployment/tidefetch --replicas=0
kubectl -n tidefetch wait --for=delete pod -l app.kubernetes.io/name=tidefetch --timeout=120s
After the storage snapshot or copy:
kubectl -n tidefetch scale deployment/tidefetch --replicas=1
kubectl -n tidefetch rollout status deployment/tidefetch
Back up the config PVC at minimum. The downloads PVC follows the normal data retention policy for the cluster.
Troubleshooting
kubectl -n tidefetch describe pod -l app.kubernetes.io/name=tidefetch
kubectl -n tidefetch logs deployment/tidefetch --tail=200
kubectl -n tidefetch get events --sort-by=.lastTimestamp
kubectl -n tidefetch get pvc
Common causes are an unbound PVC, image-pull credentials, a missing password secret, or a storage backend that cannot set ownership for fsGroup 1000.
Uninstall
kubectl delete -k packaging/kubernetes
kubectl -n tidefetch delete secret tidefetch-web-password
PVCs may remain depending on deletion order and storage policy. Confirm and back them up before deleting the namespace.