Media automation with Docker, in one container
Tell Nabbed what you want to watch. One container at home finds it on your indexers, downloads it, files it into your library and tells Plex or Jellyfin. Here is the whole setup.
What media automation does
For every series and film you follow, Nabbed:
- Watches for new releases with RSS sync, plus a daily search for missing episodes and a backfill search for older ones.
- Searches your Newznab and Torznab indexers and scores every result against your quality profile.
- Downloads the best one over Usenet or BitTorrent, with clients built into the agent.
- Verifies and extracts it, renames it to your library’s naming scheme and moves it into place.
- Triggers a Plex or Jellyfin scan, so it shows up straight away.
- Keeps looking for a better release until one meets your profile’s cutoff.
Deciding what to grab happens in the web app. Everything that touches files happens in the container, on your hardware.
The container
The agent image is ghcr.io/getnabbed/agent, built for linux/amd64, linux/arm64 and linux/arm/v7. You need a Nabbed account and Docker 20.10 or newer. Create a folder for the agent, save this as compose.yaml inside it and replace /srv/media with the folder that holds your libraries:
name: nabbed
services:
agent:
image: ghcr.io/getnabbed/agent:0.2
restart: unless-stopped
environment:
NABBED_API_URL: https://api.nabbed.media
NABBED_LIBRARY_ROOTS: /media
volumes:
- data:/data # credentials and state: must persist
- ./downloads:/downloads # downloads before they're imported
- /srv/media:/media # your libraries
ports:
- "6881:6881/tcp" # BitTorrent, optional but faster
- "6881:6881/udp"
read_only: true
tmpfs:
- /tmp:size=64m,mode=1777
cap_drop: [ALL]
security_opt:
- no-new-privileges:true
stop_grace_period: 30s
volumes:
data:Start it and follow the logs:
docker compose up -d
docker compose logs -f agentWhat each part is for
| Setting | Why it’s there |
|---|---|
data:/data | The agent’s credentials and state. Keep this volume: without it you pair again and re-enter your Usenet providers. |
./downloads:/downloads | Downloads in progress, before they’re imported. |
/srv/media:/media and NABBED_LIBRARY_ROOTS | Your libraries, and the only folders the agent may write to. Nothing is allowed until you list it. |
6881, TCP and UDP | Optional. Makes BitTorrent faster. No other inbound port is needed. |
read_only, cap_drop, no-new-privileges | Hardening: a read-only filesystem and no extra privileges. The image itself has no shell and runs as user 65532. |
NABBED_API_URL | Where the agent finds the web app when it pairs. |
Pair it with your account
On first start, the agent prints a link and a code:
To pair this agent, open: https://app.nabbed.media/device?code=ABCD-EFGH
and enter the code: ABCD-EFGHOpen the link while signed in, check the code matches and approve it. The agent connects within a few seconds and appears under Settings → Agents. Codes are valid for 15 minutes; restart the container to get a new one.
Then tell it what you want
In the web app, add your Usenet provider (your browser encrypts its credentials to the agent’s key, so only the agent can read them), check your library folders and indexers, and pick a quality profile. Then search for a series or film and add it. The library setup guide walks through each setting, and notifications can tell you when something is ready.
Not using Docker?
The same agent installs on Kubernetes with a Helm chart, or as a signed binary for Linux, macOS or Windows with a hardened systemd unit. Coming from Sonarr and Radarr? Read the Sonarr and Radarr comparison or see how one container replaces the whole *arr stack.
Questions
Will it run on my NAS?
If your NAS runs Docker 20.10 or newer on amd64, arm64 or armv7, yes. The same goes for a home server or a Raspberry Pi.
Do I need to open any ports?
No. The agent only connects out, to the web app, your Usenet providers and BitTorrent peers. Forwarding port 6881 is optional and only speeds up BitTorrent.
How do I update it?
Run docker compose pull, then docker compose up -d. The agent keeps its identity in the data volume, so it reconnects without pairing again.
Why do imports fail with a permission error?
The container runs as user 65532, so your download and library folders must be writable by it. Either chown them to 65532:65532 or run the container as your own user with user: "1000:1000".
Can I keep my files on a separate disk or share?
Yes. Mount the parent folder of your libraries into the container and list it in NABBED_LIBRARY_ROOTS. To allow several separate folders, separate them with a colon.