Setting up your automated media server with docker and usenet
One of the main reasons home enthusiasts get a server is to use it to serve their media. Whether they use Plex, Emby, Jellyfin or any other player, the backend is generally the same: Sonarr, Radarr, Lidarr, a downloader, and possibly an indexer assistant like Jackett or Prowlarr.
In this article I'm going to share my setup and the basic app settings you can expect to need. Upfront info: from the various options available, this will cover Plex, NZBget and Overseer. I have a separate article for Prowlarr here, and if you want to read about similar setups for grabbing ebooks, you can read about that here. I have also included lidarr-extended
. Lidarr is for music what Sonarr is for TV shows, however the 'extended' Lidarr container also pulls music videos.

Prerequisites
This article assumes a certain level of familiarity with various tools related to docker and directory management. Before we get started, you'll need the following:
- Docker and docker-compose installed on your machine
- The ability to SSH / use CLI/terminal on your machine, or use Portainer to spin up your stacks
- Some sort of access and relevant permissions to manage and create new directories and modify permissions access to those directories
- An active Plex account (Plex Pass not necessarily unless you require hardware transcoding). If you don't have one, visit https://plex.tv
- An active subscription to at least one usenet indexer (you can follow this link to a techradar article which lists their best indexers for 2022, so to everyone reading this from the future, dyor!)
- An active subscription to at least one news-server (same website, different article)
- An account with either Tidal, Deezer, or both (for Lidarr-extended)
Setting up your media folder structure
This is important.
Radarr and Sonarr move files around during the renaming process. To give your system the most efficient and least destructive setup, your folder structure for all media and downloads should look something like this:
volume1
β
βββ media
βββ torrents
β βββ movies
β βββ music
β βββ tv
βββ usenet
β βββ movies
β βββ music
β βββ tv
βββ libraries
βββ movies
βββ music
βββ music videos
βββ tv
The main point here is that your download directories (torrents
or usenet
) are on the same folder level as your libraries
directory, which is where your final files are stored for Plex to read them.
MEDIADIR
and PLEXMEDIA
folder paths in the .env
file below, and not to be confused with the config folder structure in the next sectionSetting up your config folder structure
The stack I'll share with you below has a number of containers commented out as they're not totally necessary (though I find them nice-to-haves). What I've kept active are the following apps:
- NZBget (downloader)
- Overseer (automated content requester, integrates with Sonarr, Radarr and Plex)
- Plex (media server and player)
- Radarr (movie grabber)
- Sonarr (TV show grabber)
We need various volume mappings for all of them, and I recommend creating a 'media stack' folder with the following sub-directories:
docker directory
βββ media stack
βββ nzbget
βββ overseer
βββ plex
βββ radarr
βββ sonarr
Creating your docker network
I prefer to keep docker networks separated and dedicated to their intended containers. Our compose stack below will set the default docker network to one named 'media', so let's set that up.
- SSH into your machine
- type
sudo docker network create media
(sudo is not always required depending on your machine and docker setup)
Docker should now have a new network named 'media'. If you want to check this, you can type sudo docker network inspect media
and it should show you various info such as the IP subnet etc.
Creating your docker-compose files
- Inside the
media stack
folder, create a.env
file and copy the contents below into it, changing the variables as indicated:
.env
file does indeed have a .
as the first character#General
PUID=xxxx #change this to your user's UID
PGID=xxx #change this to your user's GID
TZ="Continent/City" #change
MEDIADIR=/path/to/your/media/directory #change
#Lidarr-extended - uncomment either or both of the following two lines as needed
#ARLTOKEN=xxxxxxxx #add your Deezer ARL token
#TIDALCOUNTRY=XX #Add your 2-letter country code here (e.g. US)
#Plex
PLEX_PASS=true #change to false if you do not have plex pass
PLEX_CLAIM=#enter plex claim token here
PLEXMEDIA=/path/to/your/media/libraries #change
PLEX_ADVERTISE_IP=http://yourServerIP:32400 #change to include your actual IP
PLEXMEDIA
is mapped to the libraries
directory- If you need to find your user's PU-/PGIDs, SSH into your machine as that user and type
ID
. If you cannot SSH in as your preferred user (because they're not an admin for instance) then SSH in as the admin and typeID [username]
(remove the[ ]
before pressingEnter
) - To find your arl token for deezer, please follow this link here
- To claim your Plex token, sign in to your Plex account and follow the steps listed here
Now create docker-compose.yml
and copy paste what's in the code block below into it, or click the link just here to view and save the file:
##############NETWORKS##############
networks:
default:
name: media
external: true
##############NETWORKS##############
services:
# bazarr: #subtitle grabber
# image: ghcr.io/linuxserver/bazarr
# container_name: bazarr
# environment:
# - PUID=$PUID
# - PGID=$PGID
# - TZ=$TZ
# volumes:
# - ./bazarr:/config
# - $MEDIADIR/media/movies:/movies #optional
# - $MEDIADIR/media/tv:/tv #optional
# ports:
# - 6767:6767
# restart: unless-stopped
lidarr-extended:
image: randomninjaatk/lidarr-extended:latest
container_name: lidarr-extended
volumes:
- ./lidarr:/config
- $MEDIADIR:/downloads-lidarr-extended
- $MEDIADIR:/media
- $MEDIADIR/media/music videos:/music-videos
- $LOCALTIME
environment:
- PUID=$PUID
- PGID=$PGID
- autoStart=true
- enableAudioScript=true
- enableVideoScript=true
- scriptInterval=15m
- configureLidarrWithOptimalSettings=true
- searchSort=date
- audioFormat=native
- audioBitrate=lossless
- requireQuality=true
- enableReplaygainTags=true
- dlClientSource=both #change to `deezer` or `tidal` if you only use one
- arlToken=$ARLTOKEN #remove this line if not using deezer
- tidalCountryCode=$TIDALCOUNTRY #remove line if not using tidal
- audioLyricType=both
- addDeezerTopArtists=true
- addDeezerTopAlbumArtists=false
- addDeezerTopTrackArtists=false
- topLimit=10
- addRelatedArtists=false
- numberOfRelatedArtistsToAddPerArtist=5
- addFeaturedVideoArtists=false
- plexUrl=PLEX_ADVERTISE_IP
- plexToken=$PLEXTOKEN
- youtubeSubtitleLanguage=en
- enableQueueCleaner=true
- matchDistance=5
ports:
- 8686:8686
restart: unless-stopped
nzbget: #usenet download agent
image: ghcr.io/linuxserver/nzbget
container_name: nzbget
environment:
- PUID=$PUID
- PGID=$PGID
- TZ=$TZ
volumes:
- ./nzbget:/config
- $MEDIADIR/usenet:/media/usenet
ports:
- 6789:6789
restart: unless-stopped
# ombi: #media requesting tool
# container_name: ombi
# image: lscr.io/linuxserver/ombi:latest
# ports:
# - 3579:3579
# environment:
# - PUID=$PUID
# - PGID=$PGID
# - TZ=$TZ
# - UMASK=002
# - ARGS
# - DEBUG=no
# volumes:
# - ./ombi:/config
overseerr: #media requesting tool
image: sctx/overseerr:latest
container_name: overseerr
environment:
- PUID=$PUID
- PGID=$PGID
- TZ=$TZ
volumes:
- ./overseerr:/app/config
ports:
- 5055:5055
restart: unless-stopped
plex: # Media Server
container_name: plex
image: cr.hotio.dev/hotio/plex
restart: unless-stopped
logging:
driver: json-file
environment:
- PUID=$PUID
- PGID=$PGID
- TZ=$TZ
- UMASK=002
- DEBUG=no
- PLEX_CLAIM=$PLEX_CLAIM
- PLEX_PASS=$PLEX_PASS
- ADVERTISE_IP=$PLEX_ADVERTISE_IP
volumes:
- ./plex:/config:rw
- $PLEXMEDIA:/data/media:rw
- /tmp:/transcode:rw
devices:
- /dev/dri:/dev/dri #required for Synology users
network_mode: host
# prowlarr: #indexer manager for Sonarr & Radarr
# image: ghcr.io/linuxserver/prowlarr:develop
# container_name: prowlarr
# environment:
# - PUID=$PUID
# - PGID=$PGID
# - TZ=$TZ
# volumes:
# - ./prowlarr:/config
# ports:
# - 9696:9696
# restart: unless-stopped
radarr: #movie search agent
image: ghcr.io/linuxserver/radarr
container_name: radarr
environment:
- PUID=$PUID
- PGID=$PGID
- TZ=$TZ
- UMASK=022
volumes:
- ./radarr:/config
- $MEDIADIR:/media
ports:
- 7878:7878
restart: unless-stopped
sonarr: #TV show search agent
image: ghcr.io/linuxserver/sonarr:latest
container_name: sonarr
environment:
- PUID=$PUID
- PGID=$PGID
- TZ=$TZ
- UMASK=022
volumes:
- ./sonarrV3:/config
- $MEDIADIR:/media
ports:
- 8989:8989
restart: unless-stopped
# tautulli: #plex monitoring
# image: ghcr.io/linuxserver/tautulli:latest
# container_name: tautulli
# environment:
# - PUID=$PUID
# - PGID=$PGID
# - TZ=$TZ
# - UMASK=002
# - DEBUG=no
# volumes:
# - ./tautulli:/config
# ports:
# - 8181:8181
# restart: unless-stopped
There's a lot to take in above. Some things to point out:
- We have defined the external 'media' docker network we created in a previous step as the default network for this stack. This means we do not have to specify the network for each service/container as they will revert to attaching to the default network
- Plex attaches to the 'host' network. This is done as it is normally the most consistent way to ensure hardware transcoding is available
- You'll notice that all config volume mappings begin with
./
. This instructs the stack to use the folder inside the same directory as thedocker-compose.yml
file - All variables that begin with the
$
sign reference the variables in the.env
file we created earlier - If you uncomment any of the other containers, be sure to create the necessary config folders inside the same directory as the others
- Depending on your existing containers and their port mappings, you may need to change some of the default ports listed above
To spin up your stack
- SSH into your machine
- Navigate to the directory where your
docker-compose.yml
is stored - Type
sudo docker-compose -p "media" up -d
. This will create a stack called 'media' and begin spinning up your containers.
Take a break!
Or don't. Up to you. Or if you're wondering where the VPN info is, click here.
App setups
You've got your containers running, now you need to make sure they're all talking to each other and playing nicely.
You can actually check your Plex app immediately by either going to http://yourServerIP:32400/manage
or by going to https://app.plex.tv
. If you've done everything correctly it should prompt you to set up your libraries, which entails pointing the Plex Movie and TV Libraries at your movies
and tv
folders.
Otherwise, we'll go through them in this order:
NZBget
- In your browser, type in
serverIP:6789
- If you're prompted to enter a username and password, by default these are
nzbget
andtegbzn6789
- It is recommended to change these immediately, or if you had no auth requirements to access, set them

Settings
> Security
. Don't forget to Save at the bottom- Still in
Settings
, hitNews-Servers
in the left-hand pane to set up yours. Fill in the information required, which can be found on your chosen news-server's site after logging in

There's quite a lot more settings to explore here, but that's all you need to do for the moment. On to:
Sonarr
There's altogether a lot more to do here. Before we get started, make sure you have the following to hand:
- Your NZBget username and password
- Your indexer credentials (such as the API which can be found after logging in to your indexer)

- In your browser, go to
http://serverIP:8989
- First up click
Settings
>Download Clients
>+
button (behind the modal in the image above) >NZBget

- Give this downloader a name, and enter
nzbget
as host and6789
as port - Enter your NZBget username and password in the relevant fields, and TV in category
- Click
Test
. All being well, you should get a green tick in place of theTest
text to show it's successful - Don't forget to hit
Save
nzbget
as the host. What we are doing here is using the container name. This is possible as both our Sonarr and NZBget containers are on the same docker network. If they were on different networks, you would have to use the IP gateway for NZBget's docker network insteadNow we'll set our first indexer. (Again, only necessary if you're not using Prowlarr)

- In
Settings
, clickIndexers
- Set the minimum age you want before a monitored show is grabbed
- Set the max retention as per your indexer (if you have more than one indexer, set whichever is the lowest)
- Set your max MB size for a single grab if you want
- Click save (at the top)
- Now click
+
to add your indexer

Chances are you've got one of the Newznab indexers. Click the 'presets' drop down and select yours from the list.

- Change the name if you want, make sure the URL is correct, and add your API Key
- Click
Test
and when you get the green tick, hitSave
That's all the actual Sonarr configuration we need to do, however at this time it's a good idea to go over to Settings
> General
in the left-hand navigation pane and copy the API Key
. We'll need it later.
Radarr
So not because I'm lazy or anything, but for those of you who haven't figured it out, both Sonarr and Radarr are essentially exactly the same layouts. Whatever we did above for Sonarr, go do for Radarr. The only difference should be adding Movies
as the Category
when setting up NZBget as your download agent.
Don't forget to copy that API key, remember which is which!
Lidarr
See Sonarr and Radarr above. It's a little different in the navigation pane layout, but you'll be able to see what needs to go where quickly enough.
Overseer
I really like Overseer. It's great for discovering new shows and movies, and you can send requests to Radarr and Sonarr right from the gui. Nice.
- In your browser, go to
http://serverIP:5055
and you'll be greeted with a login page

- Click the
Sign In
button and authenticate with Plex
First we're going to connect to our Plex Media Server.

- Go to
Settings
>Plex
- Click the 'refresh' button (no. 3 in the image above) and then select your server from the drop down list. The host and port fields will be automatically populated
- Click
Save Changes
- Further down the screen you can then select
Sync Libraries
- Other options which aren't shown above are a manual library scan, and inputting credentials for Tautulli if you have your own instance running
Next, hit the Services
button at the top (next to Plex
), and add a Radarr Server.

- Make sure
Default Server
is checked - If your Radarr instance serves 4k content only, check that 4k box
- Enter a
Server Name
- Use
radarr
as the hostname, and7878
for the port - Use your radarr API key in the right field, then click
Test
- If all is well, a 'successful' prompt will appear top right, and the
Quality Profile
,Root Folder
andMinimum Availability
fields should auto populate - Hit
Save Changes
Now add a Sonarr server in the same way, using the sonarr API key, sonarr
as the host and 8989
for the port. Don't forget to Test then Save Changes.
Congratulations! You've now set up your own media server with automated content grabbing and easy, centralized content requesting. You can test this immediately by making a request for something recently released in Overseer, check Sonarr/Radarr to see that it was added and searched for, check the download progress in NZBget, watch it get renamed by Radarr/Sonarr, and finally appear in your Plex 'Recommendations' screen as something newly added.
Next Steps
So the grabbing and downloading is working, now you need to specify what quality you grab, what you download, and how it gets renamed. The following applies to both Sonarr and Radarr.
Import existing (organized) content
Under Series
/ Movies
> Library Import
, you can import your existing content. Read the notes on those pages though as they explain what will and what won't be imported.
Media Management
The default naming conventions are generally suitable for all media players, but if you have any changes you want to make, do so now from the Settings
> Media Management
screen.
Once you've done that, if you've got existing TV show content that you want to rename, then in Sonarr you can do this via Series
> Mass Editor
. Select the desired series and then hit Rename Files
bottom right.

In Radarr, this can be done from Movies
> Movie Editor
and works much the same way.

Set your Custom Formats (Radarr) and Release Profiles (Sonarr)
I recommend following the Trash Guides for these. You can find them here and here respectively.
Set your Profiles and Quality
Profiles
are pretty straightforward, choose from the lists available.
Quality
is a little less intuitive, and it's worth reading up on it in the official Radarr and Sonarr documentation.
Import Lists
If you have a Plex Watchlist or a Trakt list, you can set your Sonarr or Radarr instances to follow those and automatically grab anything that gets added to those lists (when it becomes available).
Connect
If you want notifications when content is grabbed, downloaded or available on Plex there are are a raft of options. Personally I use Pushover, and I give a short guide on how to set that up in this article here.
If you've got any questions, or have got stuck on something above, drop a comment below and I'll respond.
A note about permissions
A lot of Radarr/Sonarr users complain that once a file has been downloaded, it sits in their Activity
tab with an error that the file can't be found and so can't be imported. This is a permissions error, where the app(s) can't see into the folder you've pointed them at. By using the same PU-/PGID in the docker-compose.yml
as the directory owner you shouldn't have any issues with permissions, but sometimes things don't go right.
The easy fix for this is to change permissions for those directories to an 'everyone can read and write'. In Synology NAS units this can be done via File Station in DSM (right click the folder in question > properties
). In terminal/CLI, this can be done with a chmod 777
command.
This fix opens the folder up completely to every single user and app on your NAS, and maybe you're ok with that. If not, double check who owns the folder you're having difficulty with, and which users have explicit permissions to it to understand what changes you need to make.
Finally (and not recommended), rather than using PU-/PGID in the docker compose file, you can specify a user with the user: UID:GID
in the same column as the environment
block (it would look something like this):
nzbget: #usenet download agent
image: ghcr.io/linuxserver/nzbget
container_name: nzbget
environment:
- TZ=$TZ
user: PID:GID #change to the specific user and group ID numbers
volumes:
- ./nzbget:/config
- $MEDIADIR/usenet:/media/usenet
ports:
- 6789:6789
restart: unless-stopped
PUID
and PGID
variables in the environment
block to avoid conflictThis doesn't always work particularly well though, and you may end up with a number of errors/issues with that user. It's up to you whether you want to try it or not.
A note about VPNs
Some of you who don't use usenet may want to pass the network connection for a certain container through a VPN. This is possible to do, and pretty easy, but does have a few steps to be aware of. Check out the below example for qbittorrent + gluetun:
networks:
default:
name: vpn
external: true
services:
gluetun:
image: qmcgaw/gluetun
container_name: gluetun-vpn
cap_add:
- NET_ADMIN
environment:
- VPN_SERVICE_PROVIDER=$VPNPROVIDER
- OPENVPN_USER=$GTUSER
- OPENVPN_PASSWORD=$GTPW
- SERVER_COUNTRIES=$GTCOUNTRY
- SERVER_REGIONS=$GTREGION
ports:
#the container port(s) should be the ones needed for the container you want to use the gluetun network
- 8080:8080
- 6881:6881
- 6881:6881/udp
qbittorrent:
image: lscr.io/linuxserver/qbittorrent:latest
container_name: qbittorrent
environment:
- PUID=$PUID
- PGID=$PGID
- TZ=$TZ
- WEBUI_PORT=8080
volumes:
- ./qbit:/config
- $DOWNLOADDIRECTORY:/downloads
# ports:
# - 8080:8080
# - 6881:6881
# - 6881:6881/udp
network_mode: service:gluetun
restart: unless-stopped
Let's look at the above:
- The
gluetun
container needs a docker bridge network to function, so we've added one in calledvpn
, which you can create in the same way as shown earlier in this guide - You must already have an account and specific credentials from a VPN provider which is compatible with gluetun. A list of those can be found on this page in their documentation, and each provider will have their own documentation on the format for credentials when using OpenVPN or Wireguard (the above example uses OpenVPN)
- The
ports
- you'll notice that the ports set in glutetun are exactly those which have been commented out in the qbit container. This is necessary as you will be accessing your qbit container through gluetun - Other than
ports
, the biggest addition to the qbit container isnetwork_mode:
. In the example above, because both containers are in the same stack, we can define thenetwork_mode:
as theservice
name, which in this case isgluetun
. If the containers were in different stacks, we would have to define it by the container name, meaning it would look likenetwork_mode: container:gluetun-vpn
Either way, you should now be able to set up a vpn container and route any other container through it.
Related Articles



Have some feedback or something to add? Comments are welcome!
Please note comments should be respectful, and may be moderated