Nextcloud 15 on Raspberry Pi

Nextcloud Logo

I was thinking about writing a piece on Nextcloud (14) when, a short while ago, version 15 launched.

 The time is right ! But what is Nextcloud ?

Well, you can think of Nextcloud as kind of Dropbox, mixed with services that ressemble Google’s.

But instead of giving away your files and data, you host the infrastructure and the services … at home, on a raspberry pi. Your data remain fully yours and under your sole control.

Off course you can’t expect the same powerfulness of a raspberry pi than Google. You’ll have to be careful with backups. And yes you could also use other secure “zero knowledge” services, like SpiderOak One (that I use myself) or TresorIt.

Still, I find the idea of remaining the owner of my personal data very satisfying. So let’s dig in and see how to install Nextcloud 15 !

1. Introduction

If I’m being honest, Nextcloud’s documentation is just brilliant ! You could probably find your way just by reading it carefully:

Nextcloud 15 Admin Manual

Nonetheless, a few things need a bit of thinking and research. That’s where this post comes in. I’ll explain step by step everything necessary to successfully deploy Nextcloud on a raspberry pi.

I can obviously also only recommend that you go through my “new raspberry routine“. I’ll take for granted that you start with:

  • A freshly installed Raspbian.
  • The raspberry pi is up and running.
  • You know its IP address.
  • You know how to connect to the pi over ssh.
  • Apache and php fpm installation is functional.

In case you’re not sure how to install Apache and enable php fpm, please read (at least) section 2 of WordPress On Raspberry Pi – Part 1 – Preparation.

2. PHP Modules

Nextcloud requires a number of php modules to work properly. Some are mandatory, other optional though still recommended. I’m thinking for instance about the apcu memcache to improve performances.

Nextcloud admin documentation provides a list of modules in Prerequisites for manual installation.

If you want details about the modules themselves you should check php documentation instead.

$ php -m | grep -E -i "ctype|dom|gd|iconv|json|libxml|mbstring|openssl|pdo_mysql|posix|session|simplexml|xmlreader|xmlwriter|zip|zlib" | wc -l

If the command above returns 16 you’re all set already. Otherwise, if you get a number lower than 16, you’re missing some of the mandatory modules.

Please note we’ll be using MariaDB for the database.

In order to determine which modules are missing issue the command below:

$ php -m | grep -E -i "ctype|dom|gd|iconv|json|libxml|mbstring|openssl|pdo_mysql|posix|session|simplexml|xmlreader|xmlwriter|zip|zlib"

Then compare the list returned against the modules in the command.

To find which raspbian package corresponds to which module the following command can help:

$ apt-cache search php {module name}

Most of the time the package name is something like php7.0-{module name} or php-{module name}. Unless the module is part of php7.0-fpm or php7.0-common.

In my case, here are the modules I installed:

$ sudo apt-get install php7.0-xml php7.0-gd php7.0-mbstring php7.0-zip php-apcu
$ sudo apt-get install php7.0-curl php7.0-bz2 php7.0-intl php7.0-mcrypt
$ sudo apt-get install php-imagick

The first command installs the mandatory modules. The 2nd command the recommended modules, then finally, one optional module.

3. Download Nextcloud

I’ll assume the commands below are self explanatory.

To summarize:

  • We are going to download Nextcloud archive.
  • Test it against a checksum and a pgp signature.
  • Extract the archive and,
  • Set the resulting directory to the proper owner and group.
$ cd /var/www/html
$ sudo wget https://download.nextcloud.com/server/releases/nextcloud-15.0.0.tar.bz2
$ sudo wget https://download.nextcloud.com/server/releases/nextcloud-15.0.0.tar.bz2.sha256
$ shasum -a 256 -c nextcloud-15.0.0.tar.bz2.sha256
$ sudo wget https://nextcloud.com/nextcloud.asc
$ gpg --import nextcloud.asc
$ gpg --list-keys
$ sudo wget https://download.nextcloud.com/server/releases/nextcloud-15.0.0.tar.bz2.asc
$ gpg --verify nextcloud-15.0.0.tar.bz2.asc nextcloud-15.0.0.tar.bz2
$ sudo tar -xjf nextcloud-15.0.0.tar.bz2
$ sudo chown -R www-data: nextcloud

Finally, if you feel like it, you can remove the now unnecessary files and archives:

$ sudo rm nextcloud-15.0.0.tar.bz2
$ sudo rm nextcloud-15.0.0.tar.bz2.sha256
$ sudo rm nextcloud.asc
$ sudo rm nextcloud-15.0.0.tar.bz2.asc

4. Database Preparation

If you’ve carefully read Nextcloud system requirements, you may have noticed some recommandations when using MySQL or MariaDB.

This is precisely what we’re going to dig into now.

First, Nextcloud only supports the InnoDB storage engine which is fortunately the default on raspbian Stretch.

Second, Nextcloud encourages the use of the Barracuda file format, when Antelope is the default at the time of writing (since MariaDB is in version 10.1).

Third, the transaction isolation level must be set to READ-COMMITTED even though, to be honest, we can’t support much traffic on a raspberry pi.

 Finally, we’d better set the database character set to utf8mb4 which is a true 4 bytes encoding compared to utf8, which surprisingly only uses 3 bytes in MySQL.

Long story short, edit the 50-server.cnf file:

$ /etc/mysql/mariadb.conf.d
$ sudo vi 50-server.cnf

Set (or verify the value of) the following system variables:

[mysqld]
innodb_file_per_table = 1
innodb_file_format = Barracuda
innodb_large_prefix = true
# the character set and collation directives below are normally set by default
character-set-server = utf8mb4
collation-server = utf8mb4_general_ci
binlog_format = ROW
transaction_isolation = READ-COMMITTED

Then restart the database server:

$ sudo systemctl restart mariadb

Note that I haven’t followed all the recommendations in Configuring a MySQL or MariaDB database. The trick is a raspberry pi has a limited amount of memory. Hence, I prefer to rely on some of raspbian default configurations.

5. Database Setup

I’m not going to cover this part too much either, as I’ve already explained it all in WordPress On Raspberry Pi – Part 2 – Database. Plus, the SQL commands are rather self-explanatory. Just make sure to secure MariaDB first by running: mysql_secure_installation.

The principles here are exactly the same as for WordPress.

In a few words: I’m going to create a database user called nextcloud. Then I’m going to create a database also called nextcloud. The nextcloud user will be granted all access rights to the nextcloud database. In other words, the nextcloud user will be the admin of the nextcloud database.

$ sudo mysql -u root -p
> SHOW DATABASES;
> USE mysql;
> CREATE USER IF NOT EXISTS 'nextcloud'@'localhost' IDENTIFIED BY '{nextcloud MariaDB user password}';
> CREATE DATABASE IF NOT EXISTS nextcloud CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
> GRANT ALL PRIVILEGES ON nextcloud.* TO 'nextcloud'@'localhost';
> FLUSH PRIVILEGES;
> exit

6. Apache Web Server Configuration

6.1 Nextcloud Virtual Host

Nextcloud is a site in itself, thus we need to create a corresponding VirtualHost in Apache.

$ cd /etc/apache2/sites-available/
$ sudo vi nextcloud.conf

Then enter the following configuration and save:

<VirtualHost *:{listening port here}>
  ServerAdmin {your email here}
  DocumentRoot /var/www/html/nextcloud
  <Directory "/var/www/html/nextcloud">
    Options +FollowSymlinks
    AllowOverride All
    <IfModule mod_dav.c>
      Dav off
    </IfModule>
    SetEnv HOME /var/www/html/nextcloud
    SetEnv HTTP_HOME /var/www/html/nextcloud
  </Directory>
  ErrorLog ${APACHE_LOG_DIR}/nextcloud_error.log
  CustomLog ${APACHE_LOG_DIR}/nextcloud_access.log combined
</VirtualHost>

Obviously, you’ll need to change a couple things, and in particular:

  • The VirtualHost listening port.
  • Your email address.

The listening port is important in case you define several virtual hosts on one machine. Indeed, the port is what differentiates the sites from one another, as they all share the same IP address.

Also, if you followed my new raspberry pi hands-on routine, you installed the ufw firewall. Thus remember to open your listening port with the firewall so Apache (hence Nextcloud) can actually receive traffic and requests:

$ sudo ufw allow in proto tcp from 192.168.0.0/16 to any port {listening port here}

Similarly, you may need to change the 192.168.0.0/16 part according to your own network configuration.

Finally, let’s enable our new site configuration:

$ cd /etc/apache2/sites-enabled
$ ls -l
$ apache2ctl -t # checks all configuration files syntax
$ apache2ctl -S # shows the server status
$ sudo a2ensite nextcloud
$ ls -l
$ apache2ctl -S

6.2 Apache’s modules

Nextcloud requires a number of modules to be loaded by the web server on startup. The list is mentioned in Nextcloud documentation. Basically the following modules are necessary:

  • rewrite
  • headers
  • env
  • dir
  • mime
  • setenvif
$ cd /etc/apache2/mods-enabled
$ ls -l rewrite.load headers.load env.load dir.load mime.load setenvif.load | wc -l

Should the last command return 6, you’re all set. However, if you get less than 6, you miss some modules. In that case, list the content of the /etc/apache2/mods-enabled directory and check the file names it contains against the list. If necessary, enable the missing modules. In addition, note there is no harm enabling an already enabled module.

$ ls -lA
$ sudo a2enmod headers # as an example

As a last step, let’s restart Apache and check the listening ports on the raspberry pi:

$ sudo systemctl stop apache2
$ sudo systemctl start apache2
$ netstat -ltn

7. PHP Configuration

As I mentioned already, you can think of Nextcloud as a kind of Dropbox. In other words, it’s a bit about transferring files and data.

However, php limits the size of the files it may receive. As a consequence we need to change a couple php parameters:

$ cd /etc/php/7.0/fpm
$ sudo mv php.ini php.ini.orig
$ sudo cp php.ini.orig php.ini
$ sudo vi php.ini

Then adapt the following settings to your expected usage (the values can be much higher):

post_max_size = 13M
upload_max_filesize = 12M

upload_max_filesize, as the name suggests, represents the maximum file size authorized for upload. File transfers happen in HTTP POST requests. Hence, the post_max_size value is generally slightly greater than upload_max_filesize to take the HTTP protocol headers into account.

8. Nextcloud Init

Nextcloud Init Screen
Nextcloud Init Screen

We’re almost there ! When you open the raspberry pi IP address as a URL in a browser, you should see the screen above.

The username and password will be those of the Nextcloud administrator.

The Data folder is the place where the files you upload will be saved. By default it’s a sub-directory of the web server home. This is bad for security. If your web server gets breached, the attacker may have a direct access to your files. Also, unless you have a very big micro SD card in your raspberry pi, it’s better to set the Data folder onto an external drive (like a large USB key at least).

If you don’t know yet where to put the Data folder, leave the default value, you can move it later on anyway.

The Database user, Database password and Database name are those we defined in the section: Database Setup. The last field is preset with localhost. However, it’s recommended to also indicate the port number (which is 3306 by default for MySQL/MariaDB) like so: localhost:3306.

Now be patient. The initialization process is a bit long on a raspberry pi, and may take a couple minutes. If everything goes well, you should finally be logged in as the administrator and see the screen below.

Nextcloud First Launch
Nextcloud First Launch

9. A Couple More Things

9.1 Pretty URLs

Enabling pretty URLs is just a matter of configuration. This is a great opportunity to actually check Nextcloud configuration file. You’ll find below a sample of some of the values I set (on top of the configuration generated by the initialization process):

$ cd /var/www/html/nextcloud/config/
$ sudo vi config.php
'overwrite.cli.url' => 'https://{your domain name}/',
'htaccess.RewriteBase' => '/',
'log_type' => 'file',
'logfile' => '/var/log/nextcloud.log',
'logtimezone' => 'Europe/Paris',

The first 2 lines are those enabling the pretty URLs. Here I assume you reach Nextcloud directly from a domain name, not through a path in the URL. Make sure you add a trailing / to the overwrite.cli.url value.

The last 3 lines however are optional.

If you want to know more about all the configuration parameters, check (once again) Nextcloud documentation.

Finally, in order for the URL rewriting to really happen we need to issue one last command, that will modify the .htaccess files accordingly.

$ sudo -u www-data php /var/www/html/nextcloud/occ maintenance:update:htaccess

9.2 Nextcloud Cron Job

Nextcloud needs to perform some maintenance tasks regularly. The documentation recommends to set up a cron job to trigger these tasks.

First, let’s edit the crontab as the same user as Apache:

$ sudo crontab -u www-data -e

Then, add the following line at the end of the file:

*/15  *  *  *  * php -f /var/www/html/nextcloud/cron.php

Finally check that the schedule has been properly added:

$ sudo crontab -u www-data -l

Basically, the cryptic line we added to the cron tab simply instructs the system to run cron.php every 15 minutes.

Reference: Cron Jobs.

10. Final Words

And there you are !

Thanks to Nextcloud you’re back in the driver seat. You’re in control of your data. You don’t have to worry about the GAFAM parsing and spying on your documents.

Nevertheless the GAFAM provide invaluable services, that you mustn’t expect from a credit card size computer. Thus this approach is more for the “sysadmin knowledgeable”.

A raspberry pi doesn’t guarantee any reliability or any availability. There is no redundancy. If your raspberry pi fails, or the drive where you store your files fails, you may loose data.

Still it’s a great exercise and a nice way to discover all that Nexcloud proposes. So I hope you enjoyed this post.

To conclude, please let me know what you think. How do you protect your privacy ? Have you found any typo, mistake or error in this article that needs correcting ? Any other step you feel is necessary when deploying Nextcoud ?

Next => Nextcloud Configuration

Leave a comment