Kubernetes
Install the agent with Helm, pair it, and mount your library from NFS or any volume.
The nabbed-agent Helm chart runs the agent as a single pod,
<release>-nabbed-agent-0, with persistent storage for its identity and
downloads.
Before you start
- A Nabbed account. See Create an account.
- Kubernetes 1.27 or newer, and Helm 3.8 or newer.
jq, to read pairing codes from the logs.- A volume holding your media library, such as an NFS share, that pods can mount read-write.
Install the chart
The chart is published as a signed OCI artifact:
helm install nabbed oci://ghcr.io/wilderness-cloud/charts/nabbed-agent \
--version 0.1.1 \
--namespace nabbed --create-namespace \
--values values.yamlOr from the Helm repository:
helm repo add nabbed https://wilderness-cloud.github.io/agent
helm install nabbed nabbed/nabbed-agent --namespace nabbed --create-namespace \
--values values.yamlConfigure it
A minimal values.yaml sets the API and mounts your library. This example
mounts two folders from an NFS server with the
csi-driver-nfs storage
class:
config:
api_url: https://api.nabbed.media
volumes:
movies:
mountPath: /media/movies
libraryRoots: ["."] # the web app may import into this folder
claim:
create: true
storageClassName: nfs-csi
size: 300Gi
persistentVolume:
csi:
driver: nfs.csi.k8s.io
volumeAttributes:
server: nas.lan
share: /export/media
subDir: movies
mountOptions: [nfsvers=4.1]
tv:
mountPath: /media/tv
libraryRoots: ["."]
claim:
create: false
name: media-tv # an existing claim in the same namespaceWithout at least one libraryRoots entry (or config.library.allowed_roots),
the agent refuses every import. The install notes tell you if that's the case.
Other settings you may want:
| Value | Default | What it does |
|---|---|---|
persistence.size | 1Gi | Volume for the agent's credentials and state. It must persist. |
downloads.size | 100Gi | Volume for downloads before import. |
downloads.volume | none | Name of an entry in volumes to download onto instead. On the same volume as your library, imports are a rename rather than a copy. |
config.downloads.max_concurrent | 3 | Downloads running at once. |
torrent.hostPort / torrent.service | off | Expose BitTorrent port 6881 for faster downloads. |
podSecurityContext.runAsUser | 65532 | User that owns imported files. Set it to the user your media server expects. |
resources | none | Set requests and limits, for example 250m CPU and 256Mi, limit 1Gi. |
Run helm show values oci://ghcr.io/wilderness-cloud/charts/nabbed-agent for
the full list.
Pair the agent
On first start the agent logs a pairing link and code. Pull them from its logs:
kubectl -n nabbed logs nabbed-nabbed-agent-0 --tail=200 \
| jq -rR 'fromjson? | select(.user_code) | "\(.verification_uri) code \(.user_code)"' \
| tail -1Open the link while signed in to Nabbed, check the code, and approve it. Codes are valid for 15 minutes; when one expires, the pod exits and Kubernetes restarts it with a new code. Run the command again to get it.
Check the agent once it's paired:
kubectl -n nabbed exec nabbed-nabbed-agent-0 -- agent statusUpgrade
helm upgrade nabbed oci://ghcr.io/wilderness-cloud/charts/nabbed-agent \
--version <new version> --namespace nabbed --values values.yamlThe agent keeps its identity in its data claim, so it reconnects without pairing again.
Keep the data claim
The data claim (data-nabbed-nabbed-agent-0) holds the agent's identity. It's
kept when you uninstall, so reinstalling resumes the same agent. If you delete
it, revoke the agent in the web app first; you'll need to pair it again and
re-enter its usenet providers.
Troubleshooting
A pod crash-loops with exit code 3. The agent was revoked or its credentials expired. Give it a new identity by replacing its data claim, then pair it again:
kubectl -n nabbed delete pvc data-nabbed-nabbed-agent-0 --wait=false
kubectl -n nabbed delete pod nabbed-nabbed-agent-0Every file on an NFS volume changed group when the pod started. Some CSI
drivers, including csi-driver-nfs, apply the pod's fsGroup to the whole
volume. Prepare the folder once on the NAS so the kubelet leaves it alone:
chgrp 65532 <folder> && chmod g+rws <folder>