It is possible to run multiple instances of Readarr. This is typically done when one wants a audiobook and ebook copy of a book.
Note that you can configure Readarr to use a second Readarr as a list. This is helpful if you wish to keep both in sync.
The following requirements should be noted:
-data=
or /data=
argument passedThis guide will show you how to run multiple instances of Readarr on Windows using only one base installation. This guide was put together using Windows 10; if you are using a previous version of Windows (7, 8, etc.) you may need to adjust some things. This guide also assumes that you have installed Readarr to the default directory, and your second instance of Readarr will be called Readarr-audiobooks. Feel free to change things to fit your own installations, though.
nssm stop Readarr
sc config Readarr binpath= "C:\ProgramData\Readarr\bin\Readarr.exe -data=C:\ProgramData\Readarr"
This command tells the original instance of Readarr to explicitly use
C:\ProgramData\Readarr
for its data directory. If you didn't use the
default Readarr install, or if your data folder is somewhere else, you
may have to change your paths here.
C:\ProgramData\Readarr-audiobooks
nssm install Readarr-audiobooks
. A popup window will open where you can type yourC:\ProgramData\Readarr\bin\Readarr.exe
C:\ProgramData\Readarr\bin
-data=C:\ProgramData\Readarr-audiobooks
Note that Arguments points to the new folder created in step 1.
This is crucial, as it keeps all the data files from both instances in
separate locations.
/data=
argument to allow multiple instances%appdata%\Microsoft\Windows\Start Menu\Programs\Startup
and edit the existing shortcut if needed.C:\ProgramData\Readarr\bin\Readarr.exe /data=C:\ProgramData\Readarr-audiobooks
Readarr-audiobooks
and finish the wizard.Port Number
from 8787
to a different port e.g. 8879
so Readarr and Readarr-audiobooks do not conflictRun with highest privileges
On Launch
5
or 10
minutesStart a Program
powershell
-File D:\ReadarrInstancesChecker.ps1
################################################################################################
### ReadarrInstancesChecker.ps1 ###
################################################################################################
### Keeps multiple Readarr Instances up by checking the port ###
### Please use Readarr´s Discord or Reddit for support! ###
### https://wiki.servarr.com/readarr/installation#windows-multi ###
################################################################################################
### Version: 1.1 ###
### Updated: 2020-10-22 ###
### Author: reloxx13 ###
################################################################################################
### SET YOUR CONFIGURATION HERE ###
# Set your host ip and port correctly and use your service or scheduledtask names!
# (string) The type how Readarr is starting
# "Service" (default) Service process is used
# "ScheduledTask" Task Scheduler is used
$startType = 'Service'
# (bool) Writes the log to C:\Users\YOURUSERNAME\log.txt when enabled
# $false (default)
# $true
$logToFile = $false
$instances = @(
[pscustomobject]@{ # Instance 1
Name = 'Readarr'; # (string) Service or Task name (default: Readarr)
IP = '192.168.178.12'; # (string) Server IP where Readarr runs (default: 192.168.178.12)
Port = '8873'; # (string) Server Port where Readarr runs (default: 8873)
}
[pscustomobject]@{ # Instance 2
Name = 'Readarr-audiobooks'; # (string) Service or Task name (default: Readarr-audiobooks)
IP = '192.168.178.12'; # (string) Server IP where Readarr runs (default: 192.168.178.12)
Port = '8874'; # (string) Server Port where Readarr runs (default: 8874)
}
# If needed you can add more instances here... by uncommenting out the below lines
# [pscustomobject]@{ # Instance 3
# Name='Readarr-3D'; # (string) Service or Task name (default: Readarr-3D)
# IP='192.168.178.12'; # (string) Server IP where Readarr runs (default: 192.168.178.12)
# Port='8875'; # (string) Server Port where Readarr runs (default: 7875)
# }
)
### DONT CHANGE ANYTHING BELOW THIS LINE ###
###
# This function will write to a log file or in console output
###
function Write-Log
{
#Will write to C:\Users\YOURUSERNAME\log.txt
Param(
$Message,
$Path = "$env:USERPROFILE\log.txt"
)
function TS { Get-Date -Format 'hh:mm:ss' }
#Console output
Write-Output "[$(TS)]$Message"
#File Output
if ($logToFile)
{
"[$(TS)]$Message" | Tee-Object -FilePath $Path -Append | Write-Verbose
}
}
Write-Log 'START ====================='
$instances | ForEach-Object {
Write-Log "Check $($_.Name) $($_.IP):$($_.Port)"
$PortOpen = ( Test-NetConnection $_.IP -Port $_.Port -WarningAction SilentlyContinue ).TcpTestSucceeded
if (!$PortOpen)
{
Write-Log "Port $($_.Port) is closed, restart $($startType) $($_.Name)!"
if ($startType -eq 'Service')
{
Get-Service -Name $_.Name | Stop-Service
Get-Service -Name $_.Name | Start-Service
}
elseif ($startType -eq 'ScheduledTask')
{
Get-ScheduledTask -TaskName $_.Name | Stop-ScheduledTask
Get-ScheduledTask -TaskName $_.Name | Start-ScheduledTask
}
else
{
Write-Log '[ERROR] STARTTYPE UNKNOWN! USE Service or ScheduledTask !'
}
}
else
{
Write-Log "Port $($_.Port) is open!"
}
}
Write-Log 'END ====================='
-data=
argument passed.systemctl stop readarr
Below is an example script to create a Readarr-audiobooks instance. The below systemd creation script will use a data directory of
/var/lib/readarr-audiobooks/
. Ensure the directory exists or modify it as needed.
cat << EOF | sudo tee /etc/systemd/system/readarr-audiobooks.service > /dev/null
[Unit]
Description=Readarr-audiobooks Daemon
After=syslog.target network.target
[Service]
User=readarr
Group=media
Type=simple
ExecStart=/opt/Readarr/Readarr -nobrowser -data=/var/lib/readarr-audiobooks/
TimeoutStopSec=20
KillMode=process
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl -q daemon-reload
sudo systemctl enable --now -q readarr-audiobooks
This guide was made and tested with macOS 13 (Ventura), but should work on any version that Readarr supports.
/Applications
folder~/.config/Readarr
to ~/.config/readarr-books
or ~/.config/readarr-audiobooks
to keep data.You will create two new applications: "Readarr Books" and "Readarr Audiobooks".
New Document
, then Application
Run Shell Script
, then double-click on it# Readarr Books
open -F -n -a Readarr --args -data="$HOME"/.config/readarr-books
Readarr Books
File
> Duplicate
in the menu bar# Readarr Audiobooks
open -F -n -a Readarr --args -data="$HOME"/.config/readarr-audiobooks
Readarr Audiobooks
Get Info
window).Now, you will be setting the ports and names for each instance.
8787
for e-books and 8789
for audiobooks.Settings
> General
in Readarr, and set the correct port.Optionally: Toggle advanced options and set
Instance Name
to your liking.
When you update one instance, the updater shuts both down and only restarts the one you updated. To work around this, a port checker periodic task will be created (adapted but slightly changed from the Windows guide).
readarrportchecker.zsh
.#!/bin/zsh
# First instance's *application name*
name0="Readarr Books"
# First instance's port number
port0=8787
# Second instance's *application name*
name1="Readarr Audiobooks"
# Second instance's port number
port1=8789
# Logging
LOGFILE="$HOME/.local/state/readarr.log"
test -d "$HOME/.local/state" || mkdir -p "$HOME/.local/state"
function checkport {
lsof -i ":${1}" &>/dev/null
}
# One instance running means both should be
if checkport "${port0}" && ! checkport "${port1}"; then
open -a "${name1}"
echo "Opened ${name1}" >> "$LOGFILE"
elif checkport "${port1}" && ! checkport "${port0}"; then
open -a "${name0}"
echo "Opened ${name0}" >> "$LOGFILE"
fi
chmod +x readarrportchecker.zsh
~/Library/LaunchAgents
named local.readarr.portchecker.plist
:<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>local.readarr.portchecker</string>
<key>Program</key>
<!-- Find the path by right clicking, then Option and copy -->
<string>/path/to/readarrportchecker.zsh</string>
<key>StartInterval</key>
<!-- Periodic interval in seconds. 300 for five minutes,
600 for ten minutes. -->
<integer>300</integer>
</dict>
</plist>
launchctl load ~/Library/LaunchAgents/local.readarr.portchecker.plist
TODO
: possibly integrate this into a custom script for the update process, or observe file change instead of running every 300 seconds.