I recently got myself a Raspberry Pi b+, and I figured I’d finally make some use of the spare external harddisk I had lying around to set up ownCloud for myself.

OwnCloud is kind of a self-hosted Dropbox, which allows you to syncronize files between computers and generally makes your life on multiple devices easier. It is written in PHP and can run on mostly anything, even your average shared hosting solution.

If are fine installing it by yourself, you still may want to take a look at the performance section of this post.

Prerequisites

To run, ownCloud needs

  • a Webserver,
  • PHP,
  • and a database.

I chose to run it on nginx, with PHP 7 and backed up by PostgreSQL. I could have also chosen SQLite or MySQL/MariaDB, but I have the best experience with PostgreSQL. SQLite just doesn’t deal that well with concurrent requests and MySQL in my experience hogs more memory than I have to spare.

Installation

My Pi happens to be running Arch Linux Arm which made installation fairly easy. I pretty much followed the wiki and installed

sudo pacman -Syu nginx php-fpm postgresql owncloud php-intl php-mcrypt php-pgsql

Then we enable the required PHP extensions (gd.so, iconv.so, xmlrpc.so, zip.so, bz2.so, curl.so, intl.so, mcrypt.so, and zip.so) and we nearly have an installable system.

Database

We need to configure and create a database for owncloud to use. It will store its users there, accompanied with the file information.

sudo -u postgres initdb --locale en_US.UTF-8 -E UTF8 -D '/var/lib/postgres/data'
sudo systemctl start postgresql.service
sudo -u postgres createuser -d owncloud
sudo -u postgres createuser -O owncloud owncloud

This creates a owncloud, and a database owncloud used by it. We will use this later.

Filesystem

To use owncloud in a sensible matter, we need to set up the file system a little. Fortunately, the Arch wiki supplies us with the oc-perms script that does this for us:

Since this is a Pi and runs of an SD card, the default storage (on the root filesystem) is not a good idea. Instead, I created an owncloud partition on my external drive, and created the /assets/ and /data/ directories on it. Then I used bind mount to mount it at the correct folders.

# /etc/fstab entries for bind mounts
/mnt/owncloud/data   /usr/share/webapps/owncloud/data   none bind 0 2
/mnt/owncloud/assets /usr/share/webapps/owncloud/assets none bind 0 2

Don’t forget to chown the directories to your http user.

nginx setup

For the nginx setup, the wiki is pretty much perfect. It tells you exactly the steps.

After doing that, you can start your services (nginx.service and php-fpm.service) and you’re good to go.

Final setup

Now, go to your newly run webserver in your browser, and you will be greeted by a setup prompt. Your datbase credentials are as follows:

  • Password: none
  • User: owncloud
  • Database: ownclou
  • Host: /var/run/postgres

Note that you do not need a password because peer authentication is available. Congratulations: you have an owncloud server!

Performance

When I started using my owncloud, I noticed it had terrible performance, with very low transfer speeds and frequent crashes on the server side. So I went looking. The problem quickly revealed to be php-fpm. As you may or may not know, it uses a pool of php workers that handle incoming requests rather than setting one up each time. How many does it maximally set up by default? 128. ownCloud is rather heavy, and generally comes close to the memory limit of 128MB. My Pi did not like this.

Fortunately, there is an easy fix to this. In /etc/php/php-fpm.conf, you can configure different number. I got the best performance at 4. This did cause my system logs to regularly yell about the lack of available workers, but the system remained responsive.

Another slight optimization that I used, was moving the database files off the SD card and on a partition on my external drive. PostgreSQL uses tablespaces for this, and they are really easy to set up.

Finally, I also enabled APCu caching. This however only sped up the browser client, and not the desktop sync.

All in all, I now have a reliable 2MB/s with peaks up to 7MB/s for synchronization, which I find sufficient. Especially considering NFS (a more efficient protocol) on the same system averages at 8MB/s.