Automated torrent seeding with VPN protection and intelligent rotation
- Overview
- Features
- Quick Start
- Architecture
- Prerequisites
- VPN Configuration
- Installation
- Email Notifications (Optional)
- route23 - The Rotator
- Additional Features
- File Structure
- Troubleshooting
- Contributing
- License
route23 is a self-hosted, Docker-based automated torrent rotation system designed for low-power devices like Raspberry Pi.
Why "route23"? The name comes from the 23 different VPN providers supported through Gluetun integration - offering you flexibility to choose the VPN service that best fits your needs, whether that's port forwarding support, privacy features, or price. It's also a major US Highway that runs from Michigan to Florida that I frequently drive on.
What it does: route23 automatically manages your torrent seeding by rotating through your collection in batches. Instead of trying to seed hundreds or thousands of torrents simultaneously (which would overwhelm most hardware), route23 intelligently seeds small batches for configurable periods, then automatically cycles to the next batch. Over time, your entire collection gets seeded fairly and efficiently.
The Stack: route23 is built on a foundation of proven technologies - ruTorrent for torrent management, Gluetun for VPN protection (supporting all 23 providers), and Postfix for email notifications. These supporting services exist to enable the core route23 rotation functionality.
Core route23 Features:
- Intelligent Batch Rotation — Automatically cycles through your torrent library in manageable batches
- Time-Based Scheduling — Configurable rotation periods (default: 14 days per batch)
- Persistent State Management — Remembers exactly where it left off across restarts
- Load-Aware Operations — Monitors system load and throttles operations for low-power devices
- Progress Tracking — Real-time status reporting showing progress through your collection
- Remote Preload (Optional) — Pre-seed new torrents from a local Plex/media server over SSH so seeding starts within minutes instead of waiting for the swarm
- Hash-Check Verification — After preload, route23 waits for the recheck and stops any torrent that ended up with 0% valid data, so broken preloads are visible instead of silently seeding nothing
- Recovery Modes — Repreload the full current batch or force-preload a single torrent without rotating
Supporting Infrastructure:
- VPN Protection — All torrent traffic routed through your choice of 23+ VPN providers (Gluetun)
- Web Interface — Full ruTorrent UI for manual torrent management
- Email Notifications — Optional digest email after each rotation/preload summarizing what was preloaded and what was missed
- Docker-Based — Easy deployment and management with docker compose
Get up and running with route23 in 5 steps:
1. Prerequisites
- Docker and Docker Compose installed
- A VPN subscription with one of the 23 supported providers
- Your local network subnet (usually
192.168.1.0/24or192.168.0.0/24)
2. Clone and Configure
git clone https://github.com/rcland12/route23.git
cd route23
cp .env.example .env # Create your configuration file3. Get Your Credentials
Before editing .env, gather these credentials:
| What You Need | Where to Get It | Notes |
|---|---|---|
| VPN credentials | Your VPN provider dashboard | See VPN Configuration for detailed guides |
| Local network subnet | Run: ip route | awk '$1 ~ /^192\.168\./ {print $1; exit}' |
Usually 192.168.1.0/24 or 192.168.0.0/24 |
| Email credentials (optional) | Your email provider | See Email Notifications for setup |
4. Edit Configuration
Open .env and fill in your values (see Installation for detailed explanations).
5. Start Services
# Install htpasswd tool if needed
sudo apt update && sudo apt install apache2-utils
# Create web UI credentials (choose your own username/password)
htpasswd -Bbn your_username your_password > ./rutorrent/passwd/rutorrent.htpasswd
# Start the services
docker compose up -d nginx
# Access web UI at http://<your-server-ip>:8080That's it! Your route23 instance is running. Add .torrent files to ./rutorrent/torrents/ and run your first rotation with docker compose run --rm app.
For detailed configuration options and advanced features, continue reading below.
┌──────────────────────────────────────────────────────────────┐
│ Docker Network │
│ │
│ ┌──────────┐ ┌──────────────┐ ┌──────────────────┐ │
│ │ nginx │───▶│ ruTorrent │───▶│ VPN (Gluetun) │──▶ │ Internet
│ │ :8080 │ │ Web UI │ │ NordVPN/WG │ │
│ └──────────┘ └──────────────┘ └──────────────────┘ │
│ │ │ │
│ │ ┌──────────────┐ │ │
│ │ │ Rotator │─────────────┘ │
│ │ │ Service │ │
│ │ └──────────────┘ │
│ │ │
│ │ ┌──────────────┐ │
│ └────────▶│ Postfix │───▶ Gmail SMTP │
│ │ Relay │ │
│ └──────────────┘ │
└──────────────────────────────────────────────────────────────┘
The route23 Rotator Service is the core component that orchestrates everything. It connects to ruTorrent via API to add/remove torrents in batches, while the VPN ensures all torrent traffic is protected. The web UI (nginx + ruTorrent) and email notifications (Postfix) are optional supporting features.
- Docker & Docker Compose
- Supported VPN subscription (see VPN Configuration below)
- Email account for notifications - optional (see Email Notifications)
route23 supports multiple VPN providers through Gluetun. Choose your provider and follow the setup guide:
route23 supports all 23 VPN providers available through Gluetun. Click any provider name for detailed setup instructions.
| Provider | Port Forwarding | WireGuard | Price | Servers | Recommendation |
|---|---|---|---|---|---|
| Private Internet Access | Yes (included) | Yes | $ | 35000+ | Recommended for torrenting |
| ProtonVPN | Yes (included) | Yes | $$ | 1900+ | Recommended for torrenting |
| AirVPN | Yes (included) | Yes | $$ | 250+ | Recommended for torrenting |
| Perfect Privacy | Yes (included) | Yes | $$$ | 25+ | Recommended for torrenting |
| TorGuard | Yes (addon) | Yes |
|
3000+ | Recommended for torrenting |
| Mullvad | No | Yes | $ | 900+ | Good (privacy-focused) |
| IVPN | No | Yes | $$ | 100+ | Good (privacy-focused) |
| NordVPN | No | Yes | $$ | 5500+ | Good (general use) |
| Surfshark | No | Yes | $ | 3200+ | Good (unlimited devices) |
| Windscribe | Static only | Pro only |
|
600+ | Good (budget option) |
| CyberGhost | No | Yes | $$ | 9000+ | Good (P2P servers) |
| VyprVPN | No | No | $$ | 700+ | Limited |
| ExpressVPN | No | No | $$$ | 3000+ | Not recommended |
| IPVanish | No | Limited | $$ | 2000+ | Not recommended |
| PureVPN | Addon only | Limited | $ | 6500+ | Not recommended |
| PrivateVPN | No | No | $ | 200+ | Not recommended |
| HideMyAss | No | No | $$ | 1100+ | Not recommended |
| FastestVPN | No | No | $ | 600+ | Not recommended |
| Privado | No | Yes |
|
45+ | Not recommended |
| VPN Unlimited | No | No | $$ | 500+ | Not recommended |
| VPN Secure | No | Yes | $$ | 100+ | Not recommended |
| SlickVPN | No | No | $ | 150+ | Not recommended |
| Custom Configuration | Depends | Depends | - | - | For advanced users |
Best for Torrenting (Port Forwarding Required):
- Private Internet Access (PIA) - Best overall value with included port forwarding
- ProtonVPN - Strong privacy with port forwarding support
- AirVPN - Excellent for technical users and privacy-conscious torrenters
Best for Privacy (Without Port Forwarding):
- Mullvad - Anonymous accounts, independently audited
- IVPN - No personal information required, multi-hop support
- ProtonVPN - Swiss-based with strong privacy protections
Best Value:
- PIA - Approximately $3/month with port forwarding included
- Mullvad - Fixed pricing at 5 EUR/month
- Windscribe - Free tier available or affordable Pro plan
Not Recommended:
- Providers without port forwarding support are less optimal for torrenting
- ExpressVPN, IPVanish, HideMyAss, and FastestVPN have limitations for this use case
Why Port Forwarding Matters: Port forwarding significantly improves seeding ratios and peer connections. Without it, you can still seed but with reduced efficiency:
- With Port Forwarding: Accept incoming connections, better peer discovery, higher upload speeds, improved ratios
- Without Port Forwarding: Outgoing connections only, slower seeding, lower ratios
Providers with Port Forwarding: PIA, ProtonVPN, AirVPN, Perfect Privacy, TorGuard (addon)
Click any VPN provider above to access detailed setup guides including:
- How to get your API keys, tokens, or credentials
- Step-by-step configuration for route23
- Server recommendations optimized for P2P
- Port forwarding setup (where applicable)
- Troubleshooting common issues
- Performance tips
git clone https://github.com/rcland12/route23.git
cd route23Before creating your .env file, you'll need to collect the following information:
Your VPN provider will give you credentials needed for Gluetun. Each provider is different:
- NordVPN: Access token from account dashboard
- Private Internet Access: Username and password
- ProtonVPN: OpenVPN/WireGuard credentials
- Other providers: See VPN Configuration for detailed guides
Click your VPN provider in the Supported VPN Providers table for specific instructions on obtaining these credentials.
Your local network subnet allows route23 to communicate with your host machine. Find yours with:
ip route show | awk '/proto kernel/ && /192\.168\./ {print $1}'Common values are 192.168.1.0/24, 192.168.0.0/24, or 10.0.0.0/24. If the command returns nothing, try:
ip -4 addr show | grep inet | grep -v 127.0.0.1 | awk '{print $2}'Choose a username and password for accessing the ruTorrent web interface. These are credentials you create yourself - pick something secure. You'll need these in step 3.
If you want email notifications for torrent completion, you'll need:
- Your email address
- An app-specific password from your email provider
See Email Notifications for provider-specific instructions on generating app passwords for Gmail, Outlook, Yahoo, iCloud, and others.
Create a .env file in the route23 directory with your configuration:
# ============================================
# VPN Configuration (Required)
# ============================================
# Get these credentials from your VPN provider dashboard
# See VPN Configuration section for provider-specific guides
VPN_SERVICE="nordvpn" # Your VPN provider name
NORDVPN_TOKEN=your_token_here # Replace with your VPN token/username
WIREGUARD_PRIVATE_KEY=your_key_here # Replace with your WireGuard private key
# ============================================
# Network Configuration (Required)
# ============================================
# Find your subnet with: ip route show | awk '/proto kernel/ && /192\.168\./ {print $1}'
# Common values: 192.168.1.0/24, 192.168.0.0/24, 10.0.0.0/24
PRIVATE_SUBNET="192.168.0.0/24" # Replace with YOUR local network subnet
# ============================================
# System Configuration (Required)
# ============================================
TIMEZONE="America/New_York" # Your timezone (e.g., America/Chicago, Europe/London)
SERVER_NAME="route23" # Hostname for your server (can be anything)
# ============================================
# ruTorrent Web UI Credentials (Required)
# ============================================
# CREATE YOUR OWN username and password here
# You'll use these in Step 4 with htpasswd command
# You'll also use these to login to the web UI
RTORRENT_USER=your_username # Choose your own username
RTORRENT_PASS=your_password # Choose your own password
# ============================================
# Email Notifications (Optional)
# ============================================
# Leave blank or comment out if you don't want email notifications
# See Email Notifications section for provider setup guides
POSTFIX_EMAIL=youremail@gmail.com # Your email address
POSTFIX_PASSWORD=your_app_password # App password from email provider (not your regular password)
POSTFIX_HOSTNAME=mail.website.com # Optional: Your domain name
POSTFIX_ALLOWED_SENDER_DOMAINS="servername localhost website.com" # Add your domain if using POSTFIX_HOSTNAMECreate the authentication file using the SAME username and password you specified in .env above:
# Install htpasswd if needed
sudo apt update && sudo apt install apache2-utils
# Create authentication file
# Replace your_username and your_password with the values from RTORRENT_USER and RTORRENT_PASS in .env
htpasswd -Bbn your_username your_password > ./rutorrent/passwd/rutorrent.htpasswdImportant: The username and password here MUST match RTORRENT_USER and RTORRENT_PASS from your .env file.
docker compose up -d nginxWait for containers to start (30-60 seconds), then access the web UI at http://<your-server-ip>:8080 using the credentials you created in steps 3 and 4.
Check that all containers are running:
docker compose psYou should see:
route23-nginx(running)route23-rutorrent(running)route23-vpn(running)route23-postfix(running, if configured)
Test VPN connection:
docker compose exec vpn curl -s https://am.i.mullvad.net/connectedShould return: "You are connected to Mullvad" or similar message indicating VPN is active.
route23 can send email notifications when torrents are added or completed. This section covers setup for major email providers.
route23 uses Postfix as an SMTP relay and supports any email provider that allows SMTP authentication:
- Gmail
- Outlook/Hotmail/Live
- Yahoo Mail
- ProtonMail
- iCloud Mail
- Custom SMTP servers
Gmail requires an App Password for third-party applications.
- Go to your Google Account: https://myaccount.google.com/
- Navigate to Security
- Enable 2-Step Verification if not already enabled
- Go to: https://myaccount.google.com/apppasswords
- Select Mail as the app
- Select Other (Custom name) as the device
- Enter "route23" or "Postfix"
- Click Generate
- Copy the 16-character app password (remove spaces)
POSTFIX_EMAIL=your-email@gmail.com
POSTFIX_PASSWORD=your_app_password_hereThe default configuration already supports Gmail:
postfix:
environment:
RELAYHOST: "[smtp.gmail.com]:587"
RELAYHOST_USERNAME: ${POSTFIX_EMAIL}
RELAYHOST_PASSWORD: ${POSTFIX_PASSWORD}Microsoft accounts work with their unified SMTP service.
- Sign in to your Microsoft account: https://account.microsoft.com/
- Go to Security → Advanced security options
- Ensure SMTP authentication is enabled (usually enabled by default)
Outlook does not require app passwords for SMTP (unless you have 2FA enabled).
POSTFIX_EMAIL=your-email@outlook.com # or @hotmail.com, @live.com
POSTFIX_PASSWORD=your_account_passwordpostfix:
environment:
RELAYHOST: "[smtp-mail.outlook.com]:587"
RELAYHOST_USERNAME: ${POSTFIX_EMAIL}
RELAYHOST_PASSWORD: ${POSTFIX_PASSWORD}Yahoo requires an App Password for third-party applications.
- Go to: https://login.yahoo.com/account/security
- Click Generate app password
- Select Other App
- Enter "route23" as the app name
- Click Generate
- Copy the app password
POSTFIX_EMAIL=your-email@yahoo.com
POSTFIX_PASSWORD=your_app_password_herepostfix:
environment:
RELAYHOST: "[smtp.mail.yahoo.com]:587"
RELAYHOST_USERNAME: ${POSTFIX_EMAIL}
RELAYHOST_PASSWORD: ${POSTFIX_PASSWORD}ProtonMail requires the ProtonMail Bridge application for SMTP access.
- Download ProtonMail Bridge: https://proton.me/mail/bridge
- Install and log in with your ProtonMail account
- Bridge will provide SMTP credentials
- Open ProtonMail Bridge
- Click on your account
- Click Mailbox configuration
- Note the SMTP server, port, username, and password
POSTFIX_EMAIL=your-bridge-username@protonmail.com
POSTFIX_PASSWORD=your_bridge_passwordpostfix:
environment:
RELAYHOST: "[127.0.0.1]:1025" # Default Bridge SMTP port
RELAYHOST_USERNAME: ${POSTFIX_EMAIL}
RELAYHOST_PASSWORD: ${POSTFIX_PASSWORD}Note: ProtonMail Bridge must be running on the host machine for this to work.
iCloud requires an App-Specific Password.
- Go to: https://appleid.apple.com/
- Sign in with your Apple ID
- Navigate to Security → App-Specific Passwords
- Click Generate an app-specific password
- Enter "route23" as the label
- Copy the generated password
POSTFIX_EMAIL=your-email@icloud.com
POSTFIX_PASSWORD=your_app_specific_passwordpostfix:
environment:
RELAYHOST: "[smtp.mail.me.com]:587"
RELAYHOST_USERNAME: ${POSTFIX_EMAIL}
RELAYHOST_PASSWORD: ${POSTFIX_PASSWORD}If you have your own SMTP server or use a different provider:
From your email provider, obtain:
- SMTP server address (e.g.,
smtp.example.com) - SMTP port (usually 587 for TLS or 465 for SSL)
- Username (usually your email address)
- Password
POSTFIX_EMAIL=your-email@example.com
POSTFIX_PASSWORD=your_smtp_passwordpostfix:
environment:
RELAYHOST: "[smtp.example.com]:587" # Replace with your SMTP server and port
RELAYHOST_USERNAME: ${POSTFIX_EMAIL}
RELAYHOST_PASSWORD: ${POSTFIX_PASSWORD}After configuration, test email notifications:
docker restart route23-postfixdocker logs route23-postfixLook for successful connection messages.
Add a small torrent through ruTorrent. You should receive an email notification when:
- The torrent is added to ruTorrent
- The torrent completes downloading
# Check Postfix logs
docker logs route23-postfix | grep -i error
# Common issues:
# 1. Incorrect email/password
# 2. App password not generated (Gmail, Yahoo, iCloud)
# 3. 2FA not enabled (Gmail)
# 4. SMTP server/port incorrect# Verify Postfix is running
docker ps | grep postfix
# Check connectivity to SMTP server
docker exec route23-postfix nc -zv smtp.gmail.com 587
# Test email sending manually
docker exec route23-postfix sendmail your-email@example.com
Subject: Test
Test email
.Gmail no longer supports "less secure apps". You must:
- Enable 2-Factor Authentication
- Generate an App Password (see Gmail setup above)
If using 2FA with Outlook:
- Generate an App Password at: https://account.microsoft.com/security
- Use the App Password instead of your account password
To disable email notifications:
- Remove or comment out the
POSTFIX_EMAILandPOSTFIX_PASSWORDvariables in.env - The postfix service will still run but notifications won't be sent
- Alternatively, remove the postfix service from
compose.yml
The core of this project is the route23 rotator service (the app container), which intelligently manages your torrent seeding by automatically rotating through your collection. Everything else (VPN, ruTorrent, email notifications) exists to support this automated rotation functionality.
route23 operates on a simple but effective principle:
- Batch-Based Seeding - Groups your torrents into manageable batches (default: 10 torrents)
- Time-Based Rotation - Seeds each batch for a configurable period (default: 14 days)
- Automatic Cycling - When the rotation period expires, removes the old batch and adds the next batch
- Persistent State - Remembers its position in your collection across restarts
- Load Monitoring - Monitors system load and throttles operations on low-power devices
The rotator works through your entire torrent collection sequentially, ensuring every torrent gets seeded fairly while keeping resource usage manageable for devices like Raspberry Pi.
Place your .torrent files in the ./rutorrent/torrents/ directory, then run the rotator:
# Run rotation check (only rotates if period has expired)
docker compose run --rm appThe rotator will:
- Check if the current rotation period has expired
- If yes, remove old torrents and add the next batch
- If no, display when the next rotation is due
- Monitor system load and pause if necessary
Initial Run: On the first run, route23 will:
- Load all
.torrentfiles from./rutorrent/torrents/ - Add the first batch (BATCH_SIZE torrents) to ruTorrent
- Record the start time and batch information
- Display status information
View the current rotation status without making changes:
docker compose run --rm -e SHOW_STATUS=true appThis displays:
- Total number of torrents in your collection
- Current batch being seeded
- Batch start time
- Time until next rotation
- Number of completed batches
- Progress through your collection
Example output:
Status Report
=============
Total torrents: 1600
Batch size: 10
Current batch: 1-10
Batch started: 2024-01-15 03:00:00
Next rotation due: 2024-01-29 03:00:00 (13 days remaining)
Completed batches: 0
Progress: 0.6% (10/1600)
Force an immediate rotation regardless of the time period:
# Force rotation (keeps downloaded data)
docker compose run --rm -e FORCE_ROTATION=true app
# Force rotation and delete downloaded data (saves disk space)
docker compose run --rm -e FORCE_ROTATION=true -e DELETE_DATA=true appWhen to Force Rotation:
- Testing the rotation system
- Manually skipping to the next batch
- Cleaning up disk space with DELETE_DATA=true
- After changing BATCH_SIZE configuration
If you already have the movie files on another machine (e.g., a Plex server on your LAN), route23 can pre-seed the new batch directly from there instead of waiting for the torrent swarm. Newly added torrents can start seeding within minutes.
How it works:
- After route23 adds a torrent to ruTorrent, it SSHes to the remote machine
- Looks for a directory matching the torrent's title and year (Plex naming convention)
- Matches video files by byte length and
scps them into the per-torrent download directory - Triggers a hash check in rTorrent, waits for it to finish, and inspects the result
- If the check finishes at 0% (e.g., the remote file has a different encode than the torrent), the torrent is stopped so it's obvious in the UI — not silently seeding nothing
Requirements:
- The remote machine must have SSH enabled and reachable from the route23 host
- The Plex movie library must follow the standard Plex naming convention:
Movie Title (YEAR) {imdb-ttXXXXXXX}/Movie Title (YEAR) {imdb-ttXXXXXXX}.mkv- The included
./exe/verify.shscript can audit your library for conformance
- The included
- An SSH private key on the route23 host that authenticates to the remote machine
Setup:
# 1. Generate an SSH key (or reuse an existing one)
ssh-keygen -t rsa -f ~/.ssh/id_rsa
# 2. Copy the public key to your media server
ssh-copy-id -i ~/.ssh/id_rsa.pub user@192.168.1.120
# 3. Add to .env
PRELOAD_HOST=192.168.1.120
PRELOAD_USER=russ
PRELOAD_SSH_KEY=/keys/id_rsa
PRELOAD_REMOTE_DIR=/mnt/plex/Media/Movies
# 4. In compose.yml, ensure PRELOAD_ENABLED: true (it is by default)The private key is mounted into the container via the compose.yml volumes section (default: ${HOME}/.ssh/id_rsa:/keys/id_rsa:ro). See Preload Settings for the full env-var reference.
When preload fails for one or more torrents (the remote machine was offline, the auto-matcher missed, or the staged bytes didn't match the torrent's pieces), use these recovery modes instead of re-running the full rotation.
docker compose run --rm -e REPRELOAD=true app
# Or the wrapper that backgrounds it and writes to ./logs:
./exe/force_preload.shRe-attempts preload for every torrent in the saved current batch. Torrents already at 100% are skipped. Use this right after fixing connectivity to the remote machine or after restoring its data.
When only one torrent failed and you don't want to touch the others, target it specifically:
# Auto-match: route23 picks the Plex directory based on the torrent name
./exe/force_preload_one.sh "mississippi"
# Override: skip auto-match and use an exact remote directory
./exe/force_preload_one.sh "mississippi" "Mississippi Burning (1988) {imdb-tt0095647}"The substring matches case-insensitively against .torrent filenames in the current batch (and falls back to the full torrent directory if there's no match there). The optional second argument bypasses the auto-matcher entirely — use it when the Plex directory name differs from what the matcher derives from the torrent name (alternate titles, special characters, etc.).
After SCP, route23 triggers a hash check, waits for it to complete, and either restarts the torrent (if data is valid) or leaves it stopped with an ERROR log line (if the staged bytes didn't match the torrent's pieces — usually a different encode of the same movie). Logs land in ./logs/route23_force_preload.log.
The equivalent without the wrapper:
docker compose run --rm \
-e FORCE_PRELOAD_TORRENT="mississippi" \
-e FORCE_PRELOAD_REMOTE_DIR="Mississippi Burning (1988) {imdb-tt0095647}" \
appSet up a daily cron job to check for rotation automatically:
# Edit your crontab
crontab -e
# Add this line to check daily at 3am
0 3 * * * cd /path/to/route23 && docker compose run --rm app >> ./logs/route23.log 2>&1How Automation Works:
- Cron runs the rotator daily (or at your chosen interval)
- The rotator checks if the rotation period has expired
- If expired, it performs the rotation automatically
- If not expired, it exits without changes
- All output is logged to
./logs/route23.log
Alternative Schedules:
# Check every 12 hours
0 */12 * * * cd /path/to/route23 && docker compose run --rm app >> ./logs/route23.log 2>&1
# Check weekly (Sundays at 3am)
0 3 * * 0 cd /path/to/route23 && docker compose run --rm app >> ./logs/route23.log 2>&1
# Check twice daily (3am and 3pm)
0 3,15 * * * cd /path/to/route23 && docker compose run --rm app >> ./logs/route23.log 2>&1Configure route23's behavior through environment variables in compose.yml:
| Variable | Default | Description |
|---|---|---|
BATCH_SIZE |
10 |
Number of torrents per rotation batch |
ROTATION_DAYS |
14 |
Days before rotating to next batch |
DELETE_DATA |
false |
Delete downloaded data when rotating out |
| Variable | Default | Description |
|---|---|---|
ADD_DELAY |
30 |
Seconds to wait between adding each torrent |
REMOVE_DELAY |
5 |
Seconds to wait between removing each torrent |
MAX_LOAD |
4.0 |
Pause operations if system load exceeds this |
LOAD_WAIT |
30 |
Seconds to wait when load is high before retrying |
STARTUP_DELAY |
10 |
Seconds to wait before starting operations |
| Variable | Default | Description |
|---|---|---|
FORCE_ROTATION |
false |
Force immediate rotation regardless of time |
SHOW_STATUS |
false |
Display status information only (no changes) |
REPRELOAD |
false |
Re-run preload against every torrent in the current batch (see Recovery) |
FORCE_PRELOAD_TORRENT |
(empty) | Substring identifying a single torrent to force-preload |
FORCE_PRELOAD_REMOTE_DIR |
(empty) | Optional exact remote directory to skip the auto-matcher |
SORT_ORDER |
alphabetical |
Order to cycle through torrents: alphabetical, reverse, random, date_added |
LOG_LEVEL |
INFO |
Logging verbosity (DEBUG, INFO, WARNING, ERROR) |
Enable and configure remote preload. See Preload from Remote for the conceptual overview.
| Variable | Default | Description |
|---|---|---|
PRELOAD_ENABLED |
false |
Master switch — must be true for preload to run |
PRELOAD_HOST |
(empty) | Hostname or IP of the remote media server |
PRELOAD_USER |
(empty) | SSH username on the remote |
PRELOAD_SSH_KEY |
/keys/id_rsa |
Path to the SSH private key inside the container |
PRELOAD_REMOTE_DIR |
(empty) | Remote directory to search (e.g., /mnt/plex/Media/Movies) |
After a rotation, repreload, or force-preload run, route23 can send a digest email summarizing what was preloaded and what was missed.
| Variable | Default | Description |
|---|---|---|
SMTP_SERVER |
route23-postfix |
SMTP relay (defaults to the included postfix container) |
SMTP_PORT |
25 |
SMTP port |
FROM_EMAIL |
torrents@website.com |
Sender address |
NOTIFY_EMAIL |
(empty) | Recipient for the digest. Leave blank to disable. |
SERVER_NAME |
route23 |
Server label shown in the email header |
Example Configuration for Heavy Load:
environment:
BATCH_SIZE: 5 # Smaller batches
ADD_DELAY: 60 # Wait longer between operations
MAX_LOAD: 2.0 # Lower load threshold
LOAD_WAIT: 60 # Wait longer when load is highExample Configuration for Powerful Server:
environment:
BATCH_SIZE: 50 # Larger batches
ROTATION_DAYS: 7 # Faster rotation
ADD_DELAY: 5 # Shorter delays
MAX_LOAD: 8.0 # Higher load toleranceCalculate how long it takes to seed your entire collection:
Formula: Total Time = (Total Torrents / BATCH_SIZE) × ROTATION_DAYS
Examples:
| Collection Size | Batch Size | Rotation Days | Total Time | Notes |
|---|---|---|---|---|
| 1600 torrents | 10 | 14 | ~6.1 years | Default settings |
| 1600 torrents | 20 | 14 | ~3.1 years | Larger batches |
| 1600 torrents | 20 | 7 | ~1.5 years | Faster rotation |
| 1600 torrents | 50 | 7 | ~7.5 months | Aggressive seeding |
| 500 torrents | 10 | 14 | ~1.9 years | Smaller collection |
| 500 torrents | 25 | 7 | ~4.8 months | Faster cycling |
Considerations:
- Longer rotation periods = Better seeding ratios per torrent
- Shorter rotation periods = More of your collection gets seeded sooner
- Larger batches = Faster through collection, but higher resource usage
- Smaller batches = Better for low-power devices like Raspberry Pi
route23 maintains persistent state in ./rutorrent/data/states/route23_state.json:
{
"current_index": 80,
"batch_started": "2026-05-12T03:42:31",
"current_batch": [
"/torrents/Dune (1984) [2160p] [BluRay] [x265] [10bit] [5.1] [YTS.MX].torrent",
"/torrents/Treasure Buddies (2012) [720p] [BluRay] [YTS.MX].torrent"
],
"completed_batches": 8,
"sort_seed": 1234567890,
"seeded_this_cycle": [
"/torrents/Dune (1984) [2160p] [BluRay] [x265] [10bit] [5.1] [YTS.MX].torrent"
],
"torrent_history": {
"07d43e26a3c4...": {
"times_seeded": 1,
"path": "/torrents/Dune (1984) [2160p] [BluRay] [x265] [10bit] [5.1] [YTS.MX].torrent",
"last_seeded": "2026-05-12T03:42:31"
}
}
}State File Details:
current_index— Number of torrents seeded so far in the current cyclebatch_started— Timestamp when the current batch was addedcurrent_batch— Torrent files in the currently-seeding batch (consumed by repreload and force-preload)completed_batches— Number of batches completed across the lifetime of the installsort_seed— Random seed used to shuffle the collection whenSORT_ORDER=random(kept stable within a cycle for reproducibility)seeded_this_cycle— Torrents that have already been seeded in the current pass through the collection (resets when the full library is exhausted)torrent_history— Per-torrent history keyed by file hash: how many times seeded and when last seeded
Managing State:
# View current state
cat ./rutorrent/data/states/route23_state.json
# Reset state (starts from beginning)
rm ./rutorrent/data/states/route23_state.json
# Backup state before major changes
cp ./rutorrent/data/states/route23_state.json ./rutorrent/data/states/route23_state.json.backupWhile route23 is the core automation, these additional features enhance the overall experience.
Access the ruTorrent web interface for manual torrent management:
http://<server-ip>:8080
Features:
- Manually add/remove torrents
- Monitor download/upload speeds
- View peer connections
- Check torrent details
- Pause/resume torrents
Credentials:
Use the username and password you configured with htpasswd during installation.
Downloaded Files:
Completed downloads are saved to ./rutorrent/downloads/complete/
The included mvmovie utility safely moves completed downloads to your media server:
# Install
mkdir -p ~/.local/bin/
cp ./exe/mvmovie ~/.local/bin/
chmod u+x ~/.local/bin/mvmovie
# Add to PATH (add to ~/.bashrc)
export PATH=~/.local/bin:$PATH
# Usage
mvmovie <movie-file> <destination>The utility includes:
- Safe file moving with verification
- Automatic backup synchronization
- Plex library integration
- Error handling and rollback
route23/
├── compose.yml # Main service definitions
├── Dockerfile # Rotator service container
├── .env # Environment variables (create this)
├── .env.example # Template for .env
├── pyproject.toml # Python project metadata
├── VERSION # Version stamp
├── logo.png # Project logo
├── src/
│ └── main.py # Core rotation logic (rotator, preload, recovery modes)
├── nginx/
│ └── nginx.conf # Reverse proxy configuration
├── exe/
│ ├── backup.sh # Backup utility
│ ├── fix-torrent-permissions.sh # Normalize ownership on the preload source
│ ├── force_preload.sh # Repreload the whole current batch
│ ├── force_preload_one.sh # Force preload a single torrent
│ ├── force_rotation.sh # Trigger an immediate rotation
│ ├── monitor.sh # Performance monitoring
│ ├── mvmovie # Media file move utility
│ └── verify.sh # Plex naming verification
├── rutorrent/
│ ├── data/
│ │ ├── rtorrent/
│ │ │ └── .rtorrent.rc # rTorrent configuration
│ │ ├── scripts/
│ │ │ └── notification_agent.py # Email notifications
│ │ └── states/
│ │ └── route23_state.json # Rotator state JSON
│ ├── passwd/
│ │ └── rutorrent.htpasswd # Authentication (create this)
│ ├── torrents/ # Place .torrent files here
│ └── downloads/ # Downloaded content
│ └── route23/ # Downloads in rotation
├── docs/ # VPN provider setup instructions
└── logs/ # Log files (create this)
# Check VPN container logs
docker logs route23-vpn
# Verify WireGuard key is set
docker compose exec vpn env | grep WIREGUARD# Regenerate htpasswd file
htpasswd -Bbn username password > ./passwd/rutorrent.htpasswd
# Restart services
docker compose restart rutorrent nginxReduce batch size and increase delays:
environment:
BATCH_SIZE: 5
ADD_DELAY: 60
MAX_LOAD: 2.0docker compose run --rm -e SHOW_STATUS=true appContributions are welcome! Please open an issue or submit a pull request.
This project is licensed under the MIT License. See LICENSE for details.
