I finished the draft

master
Kavelach 1 year ago
parent e3abb34fc1
commit 06619ab5b9

@ -1,17 +1,17 @@
# Making my music collection available anywhere
; description: I sat down to make all of my music available from anywhere using a VPN, even though the files live on my LAN.
I have been collecting music for about ten years already. Because of that, my whole library is hunderds of gigabytes large. I also revel in obscure things, so I have a lot of songs that just aren't available on Spotify, iTunes, YouTube or any other platform.
I have been collecting music for about ten years already. Because of that, my whole library is hundreds of gigabytes large. I also revel in obscure things, so I have a lot of songs that just aren't available on Spotify, iTunes, YouTube or anywhere else.
But over the years, keeping everything together was becoming more and more of a nuisance; at first I just had everything on my desktop, since I didn't really use any portable devices on which I listened to music. But then I started using a smartphone, and I had to keep a copy of everything there too. After a while ,another device joined my flock - a laptop which I used when travelling.
But over the years, keeping everything together was becoming more and more of a nuisance; at first I just had everything on my desktop, since I didn't really use any portable devices on which I listened to music. But then I started using a smartphone, and I had to keep a copy of everything there too. After a while, another device joined my flock - a laptop which I used when travelling.
Keeping the desktop and laptop in sync was very straight forward, I just `rsync`ed everything over SSH, but my phone was much more of a chore (at least until I started using [`rsync` over ADB](/article/rsync-over-adb.html)). Moving from one phone to another was pretty seamless, because I stuffed everything on an SD card that I could just take out and put in another device.
That was the case until a few months ago, when I bought a new phone, this time without a memory card slot, which has added a new challenge: I couldn't fit everything into my the phone's internal memory. I also aquired a few more albums lately, and while updating everything, I decided it is finally time to stop doing everything manually. Instead, I decided to put my skills to use. After all, computers are here to automate and simplify things.
That was the case until a few months ago, when I bought a new one, this time without a memory card slot, which has added a new challenge: I couldn't fit everything into the phone's internal memory. I also acquired a few more albums lately, and while updating everything, I decided it is finally time to stop doing everything manually. Instead, it was time to put my skills to use. After all, computers are here to automate and simplify things.
## Explaining my set-up
## Why and how…
The VPS that I use for hosting my own things has around 50 gigabytes of storage space available, so there is no way I can keep everything there. But I don't have to, because a long time ago I connected an old ThinkPad to my local network; I use it as a print server and to host some small things that I want accessible only to devices connected to my LAN. I stuffed a few hard drives into it, so now it has around a terabyte of storage available.
The VPS that I use for hosting my own things has around 50 GiB of storage space available, so there is no way I can keep everything there. But I don't have to; a long time ago I connected an old ThinkPad to my local network, and I use it as a print server and to host some small things that I want accessible only to devices connected to my LAN. I stuffed a few hard drives into it, so now it has around a terabyte of storage available.
But there was one main issue: I am behind my ISP's NAT, so I can't just connect to my gateway using my IP. I thought about this for a while, and then, the solution dawned on me: SSH!
@ -25,7 +25,7 @@ user@thinkpad ~> ssh -R 9999:localhost:22 admin@yuno.kavela.ch -N
admin@yuno ~> ssh user@localhost -p 9999
```
Turned out it worked, and I sould SSH from my VPS into my LAN. This was great news, because this enabled me to use SSHFS to just mount the music directory from the ThinkPad onto my server 🤤
Turned out it worked, and I could SSH from my VPS into my LAN. This was great news, because this enabled me to use SSHFS to just mount the music directory from the ThinkPad onto my server 🤤
```shell
admin@yuno ~> sshfs user@localhost:/var/music -p 9999 /mnt/music
@ -37,7 +37,7 @@ The only thing that was left was automating that.
## Creating the SSH tunnel automatically
I can't just schedule creating the SSH tunnel from the ThinkPad at reboot, because if something happens (for example, I reboot my server), the connection will be broken and won't be reestablished. So I went with the following systemd service:
I can't just schedule creating the SSH tunnel from the ThinkPad at reboot, because if something happens at the other end (for example, I reboot my server), the connection would be broken and wouldn't be established again. So I went with the following systemd service:
```ini
#/etc/systemd/system/ssh-tunnel.service
[Unit]
@ -59,11 +59,35 @@ and then I enabled it with `sudo systemctl enable ssh-tunnel`. Because of that a
I tested it out by rebooting both the laptop and server a couple of times, and the SSH tunnel was properly reestablished every time.
## Using the wrong tool for the job
## …and how I failed; also, using the wrong tool for the job
But here is where I encountered a fatal issue with this setup: it was robust agains rebooting stuff - the connection was severed, then my laptop tried again and again, until the connection started again. But for some reason, when the connection was there, not being really used (I don't listen to my music 24/7), the tunnel would just… stop working. Systemd reported that the SSH tunnel service was up and running, but no data could be exchanged between the two machines.
But here is where I encountered a fatal issue with this setup: it was robust against rebooting stuff - the connection was severed, then my laptop tried until the connection started again. But for some reason, when the connection was there, not being really used (I don't listen to my music 24/7), the tunnel would just… stop working. Systemd reported that the service was up and running, but no data could be exchanged between the two machines.
The worst thing is that I set everything up
The worst thing is that I set this thing up, and the next day I went to the other side of the country for a few days. To my dismay, when I tried listening to music, the service didn't work :/
I was wondering whether I should debug this issue, or just admit that SSH isn't the right tool for this job and go with something else.
Since this isn't really an use case for SSH, I decided to drop debugging that, and just set up a VPN. I went with a Wireguard based setup, because it was available as a YunoHost app (I'm getting lazy 😅). After that, I added
When I was back home I tried poking around the setup, and it turned out that scheduling a restart for every hour or so mostly fixed this issue for most of the time. I was at a crossroads: either debug this weird issue with SSH, or admit that SSH isn't really the best tool in this case.
This was the state I left this thing in for a few months, actually. I guess I just couldn't be bothered with fixing that 😅 But alas, a few days ago, one of my friends send a post on Mastodon that vented frustration about streaming services. This was the push that I needed.
I decided to just setup a VPN. I went with a Wireguard based setup, because it was available as a YunoHost app (I'm getting lazy 😅). I configured my laptop to automatically connect to it (using NetworkManager's GUI for now) and… it works. VPN is a much more robust solution for this use case.
The only thing that was left, was to actually expose those files!
## Setting up a digital library service
To manage my library, I decided to use [Funkwhale](https://funkwhale.audio/), a great piece of software that basically allows me to do everything I want with my music. It is available in the YunoHost app directory, so setting it up was very easy. After that, I had to import my music, which wasn't so straight-forward anymore. Thankfully, @drlab from the Funkwhale's Matrix room pointed me towards the [appropriate docs page](https://docs.funkwhale.audio/admin/importing-music.html); I knew I wanted an in-place import.
Because Funkwhale is a Python app, YunoHost uses a virtual environment to not pollute global packages with dependencies. Depending on how you install Funkwhale yourself, running the `manage.py`, you may encounter an error like that:
```
Traceback (most recent call last):
File "/var/www/funkwhale/api/manage.py", line 2, in <module>
import django
ImportError: No module named django
```
if you do, it means you have to first activate the virtualenv. To do that, you have to `source` an appropriate file; in my case it is `/var/www/funkwhale/virtualenv/bin/activate`.
After the environment is set up, I ran the import like so:
```shell
python /var/www/funkwhale/api/manage.py import_files "18b9dd15-40ad-4a68-a48d-79b7c8200e4c" "/home/yunohost.app/funkwhale/data/music/watykan/" --recursive --noinput --in-place
```
When Funkwhale processed all of my music, I had everything accessible via the web interface. 🎵🎶🎵

@ -1,123 +0,0 @@
# Making my music connection available anywhere
; description: I sat down to make all of my music available from anywhere using some SSH tunnels, even though everything lives on my LAN.
I have been collecting music for about ten years already. Because of that, my whole library is hunderds of gigabytes. I also revel in obscure things, so I have a lot of songs that just aren't available on Spotify, iTunes, YouTube or any other platform. But over the years, keeping everything together was becoming more and more of a nuisance; at first I just had everything on my desktop, since I didn't really have any portable devices on which I listened to music. But then I started using a smartphone, and I had to keep a copy of everything there too. After a while another device joined my flock - a laptop which I used when travelling.
Keeping the desktop and laptop in sync was very straight forward, I just `rsync`ed everything over SSH, but my phone was much more of a nuisance, until I started using [`rsync` over ADB](/article/rsync-over-adb.html). Moving from one phone to another wasn't much of a pain, because I stuffed everything on an SD card that I could just take out and put in another phone. At least until a few months ago, when I bought a new phone, this time without a memory card slot, which has added a new challenge: I couldn't fit everything into my the phone's internal memory. Also I lately added a few more albums in there, and decided, that it was time to stop doing that, and put my skills to use.
## Explaining my set-up
The VPS that I use for hosting my own things has around 50 gigabytes, so there is no way I can keep everything there. But I don't have to, because a long time ago I connected an old ThinkPad to my local network, I use it as a print server and to host some small things that I want accessible only to devices connected to my LAN.
But there was one main issue - I am behind my ISP's NAT, so I can't just connect to my gateway using my IP. I thought about this for a while, but then the solution dawned on me: SSH!
I `ssh`ed into the ThinkPad, and tested out if I could forward the port 22 from it to my VPS.
```shell
user@thinkpad ~> ssh -R 9999:localhost:22 admin@80.211.240.40 -N
```
Then I logged into my server, and tested out logging into the ThinkPad
```shell
admin@yuno ~> ssh user@localhost -p 9999
```
Turned out it worked, and I could SSH into a device on my LAN just using a tunnel. This is great news, because now I can use SSHFS to mount a directory from that device on my server 🤤
```shell
admin@yuno ~> sshfs user@localhost:/var/music -p 9999 /mnt/music
admin@yuno ~> ls /mnt/music
# A lot of directories
```
The only thing that was left was automating that.
## Creating the SSH tunnel automatically
I can't just schedule creating the SSH tunnel from the ThinkPad at reboot, because if something happens (for example, I reboot my server), the connection will be broken and won't be reestablished. So I went with the following systemd service:
```ini
#/etc/systemd/system/ssh-tunnel.service
[Unit]
Description=Estabilish a connection between this computer and the yunohost server
After=network-online.target
Wants=network-online.target
[Service]
ExecStart=/usr/bin/ssh -R 9999:localhost:22 admin@80.211.240.40 -N
User=user
Group=user
Restart=on-failure
RestartSec=20s
[Install]
WantedBy=multi-user.target
```
and then I enabled it with `sudo systemctl enable ssh-tunnel`. Because of that approach, it just works™ when an SSH tunnel gets established without issues, but if anything goes wrong, it retries doing that every 20 seconds.
I tested it out by rebooting both the laptop and server a couple of times, and the SSH tunnel was properly reestablished every time.
## Auto-mounting on the server
The first thing I tried when doing that was to just configure it by putting the appropriate line in `/etc/fstab`:
```
user@localhost:/var/music /mnt/music fuse.sshfs auto,_netdev,uid=984,gid=33,identityfile=/root/.ssh/id_rsa,port=9999,reconnect,delay_connect,allow_other 0 0
```
but after rebooting the server it didn't work, and I wasn't able to find any logs related to why. After tinkering with it for about an hour, I went to sleep, and the next morning I woke up with one thought in my mind: systemd mounts. I didn't know anything about the topic, but fortunately the [official documentation](https://www.freedesktop.org/software/systemd/man/systemd.mount.html) was easy enough to understand.
After a bit of tinkering, I had the following service file:
```ini
#/etc/systemd/system/mnt-music.mount
[Unit]
Description=Mount the music library from ThinkPad
[Mount]
What=user@localhost:/var/music
Where=/mnt/music
Type=fuse.sshfs
Options=auto,_netdev,nofail,uid=984,gid=33,identityfile=/root/.ssh/id_rsa,port=9999,reconnect,defaults,allow_other
[Install]
WantedBy=multi-user.target
```
Note: remember to name the `.mount` file after the mount point it will be using; in my case, I'm mounting to `/mnt/music`, so my file is named `mnt-music.mount`.
As per the documentation, I created another service file to enable it in systemd, so the directory is mounted automatically:
```ini
#/etc/systemd/system/mnt-music.automount
[Unit]
Description=Automount music directory
[Automount]
Where=/mnt/music
[Install]
WantedBy=multi-user.target
```
I ran `sudo systemctl enable mnt-music.automount`, and again tested it out by rebooting both devices; this proved I had a working setup.
## Setting up a digital library service
To manage my library, I decided to use [Funkwhale](https://funkwhale.audio/), a great piece of software that basically allows me to do everything I want with my music. It is available in the YunoHost app directory, so setting it up was very easy. After that, I had to import my music, which wasn't so straight-forward anymore. Thankfully, @drlab from the Funkwhale's Matrix room pointed me towards the [appropriate docs page](https://docs.funkwhale.audio/admin/importing-music.html); I knew I wanted an in-place import.
Because Funkwhale is a Python app, YunoHost uses a virtual environment to not pollute global packages with dependencies. Depending on how you install Funkwhale yourself, running the `manage.py`, you may encounter an error like that:
```
Traceback (most recent call last):
File "/var/www/funkwhale/api/manage.py", line 2, in <module>
import django
ImportError: No module named django
```
if you do, it means you have to first activate the virtualenv. To do that, you have to `source` an appropriate file, in my case it is `/var/www/funkwhale/virtualenv/bin/activate`.
After the environment is set up, I ran the import like so:
```shell
python /var/www/funkwhale/api/manage.py import_files "18b9dd15-40ad-4a68-a48d-79b7c8200e4c" "/home/yunohost.app/funkwhale/data/music/watykan/Samuel Baron" --recursive --noinput --in-place
```
when Funkwhale processed all of my music, I had everything accessible via the web interface.
## Additional notes
I already all the needed SSH keys generated, but if you don't you will need to run `ssh-keygen`, to generate an SSH key. If you put a password on it, you will have to somehow pass it to the systemd services, but there are various ways to do that. Depending on your approach, different ones may be usable.
When SSH keys are ready, you can copy them using `ssh-copy-id`, like so `ssh-copy-id user@server`. The script will probably prompt you for the password of the remote user (and may ask for the password to the SSH key itself, if you used that), and if everything went okay, you will be able to log into the box without using a password for the remote user.
If you get permission denied errors during import/playback, you may want to verify whether you have correct permissions on your files; `uid=984,gid=33` in my systemd mount service file is related to IDs of the user and group that runs the app, and they may differ in your case.
; tags: english technical shell bash self-hosted hosting music funkwhale workaround tutorial
Loading…
Cancel
Save