Run Nextcloud on the cheap
I store all my family videos, photos on my PC (home lab). The setup hasn’t changed in three years. It works great, cheaper than a dedicated NAS and more flexible.
However, the system suffers in these areas:
- No way to access the content outside the local network, the PC is turned off to save power when I’m away
- Even though the data is duplicated using btrfs, there is no geo-redundancy
- Physical connection to the PC required for data upload, not so convenient for family members
A local-cloud hybrid architecture will solve the problem, a self-hosted, always-on cloud driver can act as a central point for data distribution. My PC still serves as the main storage, but new data can be uploaded to the cloud driver first, the local storage will synchronize with the cloud driver as soon as I turn on the PC.
My PC still serves as the main storage, but new data can be uploaded to the cloud driver first, the local storage will synchronize with the cloud driver as soon as I turn on the PC.
The cloud driver has to be hosted by Nextcloud on a VPS because I want to have full control over my data. Well, the solution seems pretty simple - just create a new VPS instance and install Nextcloud on it and be done, right? Not so fast, as a frugal nerd we want to do it as cheap as possible. And since all developers are lazy, we will use the laziest method to host Nextcloud - Nextcloud All in One.
Nextcloud All in One
That’s where the problem arises (again), Nextcloud AIO offers easy deployment and maintenance with most features included in this one Nextcloud instance. But it uses Docker extensively, the resource usage is much higher than a bare metal installation. To keep costs down, I decided not to pay for a new VPS instance, but to install it on the one core 2 GiB RAM instance that also hosts this very blog. :D
Storage
First of all, the 10 GiB of block storage that comes with the VPS plan is certainly not going to be enough. We can add more block storage, but it will cost $$$. The cheapest storage is object storage and Nextcloud supports that :). After doing the math, I realized that putting all my compressed videos and photos on object storage costs me less than $3 per month. Less than a cup of coffee.
Object storage providers typically duplicate data across three regions, so we also have geo-redundancy covered.
Change the primary storage to object storage is well documented on Nextcloud manual.
Memory
After setting up my nextcloud instance, I added some photos. And then my VPS instance ran out of memory when I tried to browse the photos :(. It turns out that Nextcloud AIO uses about 1.2 GiB of memory when idle, the remaining 800 MiB of memory isn’t enough to serve a single web page. = =
The official recommended system requirement is 4 GiB or more RAM, but is there a way to run it on 2 GiB? There is!
Nextcloud is written in PHP, each request is served by a PHP worker, we want to limit the max memory each worker uses. It’s documented in nextcloud README:
By default, each PHP process in the Nextcloud container is limited to a max of 512 MB. You can adjust the memory limit by providing
--env NEXTCLOUD_MEMORY_LIMIT=512M
to the docker run command of the mastercontainer
I set the limit to 128M. However, the server still ran out of memory :(. I suspect the preview rendering is the culprit. I disabled all previews in config.php
, the memory usage went down drastically, yay! But I like to have image preview, can we limit the memory it uses? Well, the default nextcloud config value for preview generation is ridiculous.
Both preview_max_x
and preview_max_y
are set to 4000! Even on my 4k display, the preview image hardly exceeds 100 * 100 px, I set it to 60, although I suspect 30 px is more than enough. This reduces the memory usage and speeds up the preview generation considerably.
I also set preview_max_memory
to 48M and preview_max_filesize_image
to 5. No need to try to preview large images, we’d run out of memory first.
Now the server runs super smooth and hasn’t frozen in over a month :)