A little while back I automated my anime and manga habit using Plex, Flexget, and Transmission on my macOS server. Configuring these services on Ubuntu was plenty easy, but there were a couple of differences compared to the macOS server.
This story is part of a series on migrating from macOS Server to Ubuntu Server.
You can find all of the other stories in the series here.
A Quick Note
This post will be a bit vague in some areas. My assumption is that if you’re reading this post, you have a general idea of how you want these tools to work. I’m mainly going to talk about how I did initial setup.
Plex
Plex is a self-hosted, cross-platform media streaming application. Set up your media library on your own server, and then consume it from a huge range of devices. I’m a big fan of Plex for my anime shows and movies.
Setting Up
Setting up Plex on Ubuntu is pretty painless. First, download the latest version. You can find the latest download link on Plex’s website.
curl -L -o plexmediaserver_<version>_amd64.deb https://downloads.plex.tv/plex-media-server/<version>/plexmediaserver_<version>_amd64.deb
Then install it with dpkg
:
sudo dpkg -i plexmediaserver_<version>_amd64.deb
After that, we need to set up some firewall rules:
sudo EDITOR /etc/ufw/applications.d/plexmediaserver
# Config assumes Avahi is enabled already on 5353/udp, otherwise add it here
# Config omits some features I don't use
# See full list here: https://support.plex.tv/articles/201543147-what-network-ports-do-i-need-to-allow-through-my-firewall/
[plexmediaserver]
title=Plex Media Server
description=Plex Media Server
ports=32400/tcp|1900/udp|32410/udp|32412:32414/udp|32469/tcp
Last, we need to set up some ACLs for where the media is stored. In my case, I have an SMB share called Plex Media
.
cd /media/Shares
# Set default ACL for new items, and apply that ACL. (The ACL will allow the `plex` user to read Plex Media directory and traverse all sub directories, but not execute files inside of it unless they are marked executable for some other user)
setfacl -Rdm user:plex:rX Plex\ Media/
setfacl -Rm user:plex:rX Plex\ Media/
Migrating an Existing Library
If you have an existing Plex library you’d like to migrate, follow Plex’s guide for migrating from one system to another.
As part of this step, I set up my Plex database on my /media/Shares
mount (in a folder that is not actually shared), and symlinked that to /var/lib/plexmediaserver/Library/Application\ Support/Plex\ Media\ Server
.
My reasoning for the symlink was twofold:
- My database is growing ever larger, so I wanted it on a larger disk rather than on the boot drive
- This location would be more convenient to grab in local backups
At this point, you should have your old library set up on your new server!
Transmission
Transmission is a cross-platform BitTorrent client. The Mac version is fantastic, and it has a couple of automation features around seeding that I haven’t had luck with on other clients. Mainly for the latter reason, I chose to Transmission on my Ubuntu server.
Install
Install the headless Transmission daemon:
sudo apt install transmission-daemon
Configure
Guess what? More firewall rules!
This config assumes you’re using port 9091
for the web UI. Replace <peer_port>
with the port on which Transmissions will listen for peers. You might want to configure Transmission not to randomize the port on launch.
sudo EDITOR /etc/ufw/applications.d/transmission
[transmission]
title=Transmission
description=Transmission torrent daemon
ports=9091/tcp|<peer_port>
And then of course:
sudo ufw allow transmission
Guess what else? Permissions!
I save my downloads in my Public
share under the directory 0 Server Torrents
(I like it at the top of the directory when sorted alphabetically).
cd /media/Shares
chmod g+s Public
setfacl -Rdm o::--- Public/
setfacl -m user:debian-transmission:rx Public
cd Public
mkdir 0\ Server\ Torrents
setfacl -Rdm user:debian-transmission:rwX 0\ Server\ Torrents
setfacl -Rm user:debian-transmission:rwX 0\ Server\ Torrents
From there, you’ll probably want to edit Transmission’s configuration:
sudo systemctl stop transmission-daemon
sudo EDITOR /etc/transmission-daemon/settings.json
# Do your thing
sudo systemctl enable transmission-daemon
sudo systemctl start transmission-daemon
Removing Finished Torrents
If you’re like me, you’d like finished torrents to automatically disappear from Transmission. This feature is built into the Mac app, but oddly not the Linux version. A common approach I saw was a timed job that uses transmission-remote
to clean up.
First, set up a systemd service. This service will look for torrents that are 100% downloaded and done seeding and remove them.
sudo EDITOR /lib/systemd/system/transmission-cleanup.service
[Unit]
Description=Clean up finished torrents in Transmission
[Service]
Type=oneshot
ExecStart=/bin/sh -c "transmission-remote -l | grep 100% | grep ' Finished ' | awk '{print $1}' | xargs -n 1 -I \% /usr/bin/transmission-remote -t \% -r"
[Install]
WantedBy=multi-user.target
Then set up a timer to run that service. Mine runs every hour.
sudo EDITOR /lib/systemd/system/transmission-cleanup-hourly.timer
[Unit]
Description=Clean up finished torrents in Transmission every hour
After=network.target
[Timer]
# Time between running
OnCalendar=hourly
Unit=transmission-cleanup.service
[Install]
WantedBy=multi-user.target
Lastly, start the timer!
sudo systemctl daemon-reload
sudo systemctl enable transmission-cleanup.service transmission-cleanup-hourly.timer
sudo systemctl start transmission-cleanup-hourly.timer
Flexget
Flexget is a tool to help automate various things about your media library.
Install
I’m not hugely familiar with the “right way” to do things in Python, so this may not be a great way of doing it, but it works fine for my needs, and I think is secure enough.
First, some initial work. We need pip
for Python 3, and we need a user to run flexget:
sudo apt install python3-pip
sudo adduser srv-flexget
After that…permissions! I have a flexget
directory in my Public
share for flexget’s config, and then flexget
needs to be able to read where torrents end up.
cd /media/Shares
setfacl -m user:srv-flexget:rx Public/
cd Public
mkdir flexget
setfacl -dm user:srv-flexget:rwx flexget/
setfacl -m user:srv-flexget:rwx flexget/
setfacl -Rdm user:srv-flexget:rx 0\ Server\ Torrents/
setfacl -Rm user:srv-flexget:rx 0\ Server\ Torrents/
Then it’s time to install flexget, which we will do as the srv-flexget
user:
su -l srv-flexget
cd
# You may want other packages here
# For instance, I also use python-telegram-bot
pip3 install --user flexget transmissionrpc
# Here's where I link the config directory over to the Public share
# Feel free to omit this
ln -s /media/Shares/Public/flexget .flexget
EDITOR ~/.flexget/config.yml
# Insert your config
# Optional: If you are migrating an existing flexget install, you can copy the database over to maintain "seen" entries
flexget --test check
flexget --test execute
exit
Scheduling with systemd
I have flexget configured to run once and exit. I let systemd handle the scheduling aspect of things.
First, we need a service that will run flexget:
sudo EDITOR /lib/systemd/system/flexget.service
[Unit]
Description=Flexget
[Service]
Type=oneshot
User=srv-flexget
Group=srv-flexget
ExecStart=/home/srv-flexget/.local/bin/flexget --loglevel info execute
[Install]
WantedBy=multi-user.target
Then make a timer. I have mine run every 15 minutes.
sudo vim /lib/systemd/system/flexget.timer
[Unit]
Description=Run Flexget every 15 minutes
After=network.target
[Timer]
# Time to wait after booting before we run first time
# OnBootSec=1min # If you do not enable flexget.service, uncomment this line
# Time between running each consecutive time
OnUnitActiveSec=15min
Unit=flexget.service
[Install]
WantedBy=multi-user.target
After that, enable and start things:
# This isn't required, but it gets log messages into journalctl. It will make the .service run at boot, so do not combine with OnBootSec in the .timer
sudo systemctl enable flexget
sudo systemctl enable flexget.timer
sudo systemctl start flexget.timer
A Problem…
You now have an automated way to get your favorite media and load it into Plex. But now we have a bit of an issue. We have all kinds of important data on our server, but no nice way to keep it backed up. On a macOS server, you’d probably just use Time Machine.
I use Proxmox to keep the base VM1 backed up, but I only do that once a week. For all the shared files, I wanted to have hourly backups like Time Machine.
Next time, I’ll talk about what I did to solve this problem!
I only include the boot drive in the backup because my Proxmox backup disk is small! Besides, I found a way to do hourly backups of my shared files, so why include them in the Proxmox backup anyway? ↩︎