Docker linuxserver/rutorrent deprecated, what I have done!
The LinuxServer team has deprecated their image linuxserver/rtorrent/rutorrent due to a lack of maintainers! I will explain in this article what I have done to replace this image.
The LinuxServer team has deprecated their image linuxserver/rtorrent/rutorrent due to a lack of maintainers!
They now suggest to use crazymax/rtorrent-rutorrent instead. I have decided to give it a try and finally after few tests and adaptations, I have migrated for good!
I will detail below all customization I have made to keep the same experience and usage I had with the previous one.
ℹ️ It's important to mention that most of the changes introduced on this image has been made, by the author, to avoid to use rutorrent plugins at the maximum.
More details below! 😉
Please note that this image can be even more customized if you build it yourself
Linuxserver is using:
- A temp folder
- A finished folder
- A watch folder
/downloads/watchavailable to be used with Autotools>AutoWatch
Crazy-max is using:
- A temp folder
- A finished folder
/downloads/complete⚠️Note the slight difference here
- A watch folder
/data/rtorrent/watchwhich is the default rtorrent folder (Remember the note about getting rid of rutorrent plugins?)
- I have anyway created
/data/watchedto keep using Autotools>AutoWatch easily
Environment file and port management
A lot of settings can be configured from the environment file, please find below mine and some explanations
- The property RU_REMOVE_CORE_PLUGINS gives you the ability to remove completely some rutorrent plugins when you create your container (Remember the note about... ok you got it!). Be careful, some components have cross-dependencies! For example, Autotools requires data to work properly.
- At the end of the file, you can see 5 properties to customized all the ports. It's a feature I have requested, thanks for the super-fast implementation. This is a must have if you want to use more than one container behind VPN and avoid conflicts
- I also customized MEMORY_LIMIT and UPLOAD_MAX_SIZE for container with huge volumes of data
- Find out more on GitHub
The .rtorrent.rc configuration file (
/data/rtorrent/.rtorrent.rc) contains by default few customization worth to mention.
First of all, these 2 lines:
# Watch a directory for new torrents, and stop those that have been deleted schedule2 = watch_directory, 1, 1, (cat,"load.start=",(cfg.watch),"*.torrent") schedule2 = untied_directory, 5, 5, (cat,"stop_untied=",(cfg.watch),"*.torrent")
They activate the usage of the rtorrent watch folder (
/data/rtorrent/watch) to import the torrent and label them (if inside a folder) to get rid of Autotools>Autowatch and Autotools>Autolabel. I have commented these 2 lines as rtorrent watch feature is not recursive above one folder so I will keep using Autotools.
In addition, it creates also a binding between the torrent file in the watch folder (which is not delete when imported) and its session. Remove one removes the other one and I didn't want to use it that way.
Then there is 3 lines to avoid using Autotools>Automove. I have commented it as well to keep using Autotools.
# Move finished (no need Autotools/Automove plugin on ruTorrent) method.insert = d.get_finished_dir, simple, "cat=$cfg.download_complete=,$d.custom1=" method.insert = d.move_to_complete, simple, "d.directory.set=$argument.1=; execute=mkdir,-p,$argument.1=; execute=mv,-u,$argument.0=,$argument.1=; d.save_full_session=" method.set_key = event.download.finished,move_complete,"d.move_to_complete=$d.data_path=,$d.get_finished_dir=" directory.default.set = (cat,(cfg.download_complete))
And last but not least!
# Erase data when torrent deleted (no need erasedata plugin on ruTorrent) method.set_key = event.download.erased,delete_erased,"execute=rm,-rf,--,$d.data_path="
⚠️This is a warning sign to catch your attention as its a topic worth to mention!
This configuration is setup to automatically delete all data files associated with a torrent when using the function "Remove" in the interface which normally only remove the torrent and not the data.
To remove the torrent and the data, you will normally have to use Remove and Delete data in the interface, which is provided by the plugin erasedata. The author of the image put this configuration line by default to avoid having to use erasedata plugin, nevertheless I do not agree with that and I find the ability to remove a torrent without touching its data pretty useful so I also commented this line.
Using Delete to remove the torrent but not the data is useful for torrent which do not verify at 100% for example (missing a file or whatever)
Migrating torrents and session
After few tests, I was not able to migrate "easily" my session folder between the 2 images. I tried to:
- Copy the session folder content from one image to the other
- Run a search and replace
- Start the container
It never worked as expected! As you know me well, I never would have accepted to migrate manually one by one so I did a python script to ease this by:
- Find all torrents in the watch folder (Do a copy before!)
- Read the associated session files
- Extract the path after /downloads/completed
- Rebuild a tree of folders and move .torrent inside so you can just move it in your watch folder and let the magic happens! ✨
You will have to run through the content checking for all of them but at least, no manual operations.
import re import sys,os import shutil import urlparse try: os.makedirs("_done") except OSError: if not os.path.isdir("_done"): raise files = [f for f in os.listdir('.') if os.path.isfile(f)] for f in files: if f.endswith('.torrent'): print("Filename:" + f) sessionFilename = f +".rtorrent" libFilename = f +".libtorrent_resume" print("-- Session:" + sessionFilename) print("-- Libresume:" + libFilename) # Reading session file to get the current path with open (sessionFilename, 'rt') as sessionFile: sessionContent = sessionFile.read() # Extract path with regex results=re.search(r'(?<=:\/downloads\/complete\/)(.*?)(?=7:hashing)', sessionContent) if results is not None: pathRaw=results.group(1) print("-- pathRaw:" + pathRaw) else: pathRaw=None if pathRaw: # Remove the base path pathCleaned=pathRaw.replace("/downloads/completed/", "") # Remove trailing slash pathTarget=re.sub('/[^/]+$', '/', pathCleaned) print("-- Path:" + pathCleaned) print("-- Target:" + pathTarget) print("-----------------------") # Create the path try: os.makedirs(pathTarget) except OSError: if not os.path.isdir(pathTarget): raise # Move the files path = os.path.join(pathTarget, f) shutil.move(f, path) shutil.move(sessionFilename, "_done") shutil.move(libFilename, "_done")
When all of this was done, I had a tought 💡
The session incompatibility might be due to the removal of some plugins in the new image, you should try without first and let me know 😉
This image contains somes interesting features like the theme importing which let you import new one by just adding a folder into
/data/rutorrent/themes. The same works for plugins into
You can also overload an existing configuration by adding files into
/data/rutorrent/plugins-conf. You can find an example below to active debug and increase the interval of Autotools plugin.
The image also includes a pretty straightforward way to manage the htaccess authentication, more information in the official documentation.
I didn't want to keep using a deprecetad image and I've been seduced by this one and all its possible customizations like the themes or plugins importer/overloader.
The easy port customization is awesome as well!
I hope it helped! Stay tuned!