Build a robust, private media center with Nanocl using Deluge, Jackett, Radarr, Sonarr, Lidarr, and Jellyfin. This guide is concise, reproducible, and secure-by-default.
- Stack: Deluge (downloads), Jackett (indexers), Radarr/Sonarr/Lidarr (automation), Jellyfin (media server)
- Networking: Internal DNS + gateway via Nanocl
- Access: Friendly internal domains, VPN-only option
- One-command deploy:
nanocl state apply -s media_center.yml
Prerequisites
- Linux host with Nanocl v0.17+ installed and running
- Free ports 80/443 on the host (Nanocl gateway)
- A data directory on the host (e.g.,
/opt/media
) writable by your user or set via PUID/PGID
Install Nanocl if needed (requires Docker):
curl -fsSL https://download.next-hat.com/scripts/get-nanocl.sh | sh
Documentation:
Step 1 – Create media_center.yml
This Statefile deploys all services with consistent domains and internal networking. Adjust domains and paths as needed. Ensure /opt/media
exists on the host and is writable.
ApiVersion: v0.17
SubStates:
- Path: https://nr.next-hat.com/v0.17/deluge.yml
Args:
- Name: domain
Value: deluge.local.io
- Name: enable_internal_dns
Value: True
- Name: enable_internal_gateway
Value: True
# Optional: restrict to VPN only (see Bonus)
# - Name: proxy-network
# Value: Private
- Path: https://nr.next-hat.com/v0.17/jackett.yml
Args:
- Name: domain
Value: jackett.local.io
- Name: enable_internal_dns
Value: True
- Name: enable_internal_gateway
Value: True
# - Name: proxy-network
# Value: Private
- Path: https://nr.next-hat.com/v0.17/radarr.yml
Args:
- Name: domain
Value: radarr.local.io
- Name: enable_internal_dns
Value: True
- Name: enable_internal_gateway
Value: True
# - Name: proxy-network
# Value: Private
- Path: https://nr.next-hat.com/v0.17/sonarr.yml
Args:
- Name: domain
Value: sonarr.local.io
- Name: enable_internal_dns
Value: True
- Name: enable_internal_gateway
Value: True
# - Name: proxy-network
# Value: Private
- Path: https://nr.next-hat.com/v0.17/lidarr.yml
Args:
- Name: domain
Value: lidarr.local.io
- Name: enable_internal_dns
Value: True
- Name: enable_internal_gateway
Value: True
# - Name: proxy-network
# Value: Private
- Path: https://nr.next-hat.com/v0.17/jellyfin.yml
Args:
- Name: domain
Value: jellyfin.local.io
- Name: enable_internal_dns
Value: True
- Name: enable_internal_gateway
Value: True
# - Name: proxy-network
# Value: Private
Tip: If your substates support PUID/PGID and media paths, set them in each substate file or via Args to match your host user (often 1000:1000) and /opt/media
.
Note: You can open each registry URL (e.g., https://nr.next-hat.com/v0.17/radarr.yml) in your browser to see the available Args for that substate.
Step 2 – Apply the state
Run once to deploy everything:
nanocl state apply -s media_center.yml
Check status:
nanocl ps
Step 3 – Enable name resolution for internal domains
Nanocl’s gateway IP will serve DNS for your internal domains (e.g., deluge.local.io
). If you didn’t note it yet, retrieve it now:
1) Find the gateway IP:
nanocl info
Look for network nanoclbr0
and note Gateway, typically 172.17.0.1
.
2) Point your system DNS to the Nanocl gateway so the internal domains resolve:
-
/etc/resolv.conf
is a regular file (not a symlink):
echo "nameserver 172.17.0.1" | sudo tee /etc/resolv.conf
Verify:
dig +short deluge.local.io @172.17.0.1 || true
Note: Use a VPN (see Bonus) to keep services private.
Step 4 – Post-deploy configuration
Deluge
- URL:
http://deluge.local.io
- Default password:
deluge
→ change immediately - Enable the “Label” plugin (Preferences → Plugins)
Jackett
- URL:
http://jackett.local.io
- Add your preferred, legal indexers → Save → Test
Radarr
- URL:
http://radarr.local.io
- Enable auth (Settings → Security). Example for demo: username
radarr
, passwordradarr
(change in real use) - Download client (Settings → Download Clients):
- Name: Deluge
- Host: deluge.local.io, Port: 80
- Password: your updated Deluge password
- Test → Save
- Indexer (Settings → Indexers): Add “Torznab” and paste the Jackett Torznab Feed URL + API Key from Jackett
- Media management: set Root Folder to
/media/movies
(ensure the folder exists and is mounted)
- Add a movie → Optional: Interactive Search to pick a release
- Monitor Deluge for download progress
Jellyfin
- URL:
http://jellyfin.local.io
- Complete setup wizard, add a Movies library pointing to
/media/movies
Sonarr and Lidarr
- URLs:
http://sonarr.local.io
andhttp://lidarr.local.io
- Repeat Radarr’s steps: add Deluge as download client; add Jackett via Torznab; set root folders (e.g.,
/media/tv
,/media/music
)
Bonus – Lock down access with a VPN
Use a WireGuard VPN so only your devices can reach the services.
You can check my previous blog post on how to deploy wireguard on nanocl here
After your VPN is up, make each service VPN-only by adding the following Arg under each substate:
- Name: proxy-network
Value: Private
Then re-apply:
nanocl state apply -s media_center.yml
Troubleshooting
- DNS not resolving
*.local.io
:- Re-check the gateway IP from
nanocl info
- Ensure your system uses that IP as DNS (see Step 3)
- Re-check the gateway IP from
- Permissions on
/opt/media
:- Set folder ownership to your PUID/PGID, e.g.
sudo chown -R 1000:1000 /opt/media
- Reapply the state:
nanocl state apply -rs media_center.yml
- Set folder ownership to your PUID/PGID, e.g.
- Service won’t start:
-
nanocl logs -f
the failing context/service for details
-
- Authentication:
- Change all default passwords immediately and enable auth for Radarr/Sonarr/Lidarr/Jellyfin
Disclaimer
This guide is for educational purposes only. Use only legal sources and respect copyright laws in your jurisdiction.