Migrating away from Nextcloud

Since I am running my own server at home and often use company-provided hardware, I treat my laptop more like a thin-client for personal use, accessing services running on the server itself where possible. For the past couple of years, Nextcloud has been my go-to solution for all different kinds of use cases, incl. external shares, calendar, contacts, to-do lists and expense management. Most recently, frustration has crept in however.

Motivation

It all started with the calendar. Since I will heavily employ Google Workspace at my new employer, I decided to move the Nextcloud calendar I share with my wife to my Google account. Since the calendar was one of the main reasons I had used Nextcloud, I started to question whether I really needed the Nextcloud suite of applications going forward. Another trigger was that I recently had the need to create an album of wedding photos I wanted to share with our guests. Nextcloud was almost unusable for this purpose. While it is possible to share albums externally, the user experience leaves a lot to be desired. Loading speed of the images is extremely slow, mostly because no thumbnails are generated on the fly. There is a specific preview generator app for Nextcloud, but since my impression of the performance of the overall web interface was mirrored in many online forums, I decided to look for alternatives.

File Sharing and Photo Libraries

As mentioned, file sharing with other registered users as well as external guests is very important to me. Nextcloud was already set up with external storages, meaning that my files lived on a network share instead of Nextcloud’s database. This requirement is extremely important to me, since it makes migration between different solutions much easier, even if it means to miss out on some advantages like faster indexing. You could argue that this is one of the reasons my Nextcloud experience was not perfect and a “native” experience would have been better - true, but a requirement is a requirement. After looking at different alternatives like SeaFile (which does not allow external storages), I finally settled on FileRun and could not be happier. All I had to do was mount my existing network shares via docker-compose and the solution was ready to go. I could easily create separate home folders for my wife and me, share folders between us, and create external shares as well. FileRun is also accessible via WebDAV, allowing it to be used for my document scanner app, for example. It was also very easy to configure OnlyOffice as a connected document editor (there was even an Unraid template), meaning I will not have to leave the browser or download and re-upload when editing personal files. I expose the service through my reverse proxy with an SSL certificate and can even continue to use the Nextcloud mobile apps to access my files by pointing them to my FileRun URL - but with better performance this time.

Initially I was expecting to host a separate tool for photo libraries. I had looked at LibrePhotos with a promising Android client in development, Immich as a Google Photos clone, and more established solutions like PhotoPrism or PiGallery2. In the end, FileRun offers all the functionality built-in, however. After indexing my files’ metadata, I could easily add my photos to new albums and expose these via password-protected web links. Thumbnails are generated on-demand when accessing a folder for the first time. I struggled a little bit at this point, since some of my photo folders were read-only and the thumbnails therefore were not created automatically. I was able to create them manually by running a php-script as root on my server and then changing the owner of these files, but this approach had two disadvantages: First, the thumbnails were stored next to the original folders on my hard drive, being spread all over the place. Second, I would have had to create cron jobs to repeat the creation of thumbnails and ownership transfer periodically, missing the point of on-demand thumbnail generation. Therefore I was very happy when I came across the advanced configuration options available in FileRun through creation of a config.php file. This allowed me to specify a central location for all preview and thumbnail files with write access for the docker container, alleviating all the problems mentioned before:

<?php
date_default_timezone_set("Europe/Berlin");
// $config['path']['thumbnail_cache'] = '/var/www/html/thumbnails/';
$config['path']['preview_cache'] = '/var/www/html/previews/';
$config['path']['trash'] = '/var/www/html/trash/';
$config['system']['fm']['use_safe_move'] = true;
$config['app']['weblinks']['disableShortURL'] = true;
$config['app']['weblinks']['forcePasswords'] = true;
?>

Almost everything was working perfectly now - the only issue I now had is that since the central thumbnail location had been changed, previews in externally shared web albums were not loaded correctly anymore, throwing 404 errors instead. I have contributed to a ticket in the public FileRun forum, hoping that this issue will be remediated soon. For now, I have commented out that configuration option again (see snippet above) and changed editing rights of my complete pictures folder via chmod. I am thereby allowing the FileRun user to create thumbnails in all folders, having to live with one of the disadvantages mentioned above. As soon as the external album bug got fixed I will remove the comment from my config.php and prune the stale thumbnails from my hard drive again running the following command from the root of my pictures folder - first inspecting which files are affected, then removing those thumbnails:

find . -type d -name .filerun.thumbnails -exec ls {} \;
find . -type d -name .filerun.thumbnails -prune -exec rm -rf {} \;

Calendar, Contacts and Tasks

As mentioned, another trigger was the requirement to use Google Calendar going forward. Since Google Calendar cannot integrate additional CalDAV calendars with read/write access, the only solution (known to me) that will allow me to collaborate on our shared calendar from my work profile in the future (without external syncing software) was to migrate the complete calendar to Google. Through export and import this process was relatively pain-free.

Now that the calendar was not syncing with Nextcloud anymore, the remaining use case for the DAVx⁵ syncing tool installed on my phone was contact sync. Syncing contacts through CardDAV on Nextcloud was a pain anyways, since Nextcloud’s contacts app is not following all standards employed by other CardDAV providers. For this reason, I decided to move my contact storage back to my Google account as well. I could have moved it to another CardDAV provider or hosted Radicale on my server again, but decided that my paranoia for public cloud was not high enough anymore to justify an additional container and syncing tool.

For tasks, Nextcloud was actually working great for me - but since I almost exclusively access my tasks through the tasks.org Android app or the Reminders app on iOS, both of which allow CalDAV syncing without external tools, I decided to just move my existing lists to my mail provider’s CalDAV server and call it a day. I had also used the great self-hosted project Vikunja in the past, but missed proper CalDAV sync to iOS. Also, it was overkill for my requirements.

Miscellaneous items and apps

Nextcloud does of course offer additional tools and add-ons and is still a great product, especially since it is free and Open Source (FileRun is not OSS, but has a free tier). I had used the CoSpend app to separate expenses for joint trips in the past, but lately this use case has just disappeared - especially after my wedding. If it ever reappeared I could still just host my instance of #!money? as a separate docker container, thereby moving back to separate best-of-breed solutions. Same goes for Nextcloud Deck. While I had this deployed for shared Kanban boards with my wife, she was never really adopting that solution. If the need comes up in the future, I will simply start a Kanboard container (or give Vikunja another try). In conclusion, my explanations above might sound a little complicated - the end result is actually pretty simple however, even when compared to my previous, central Nextcloud configuration.