The Ultimate Setup Guide for ownCloud on Small Systems such as the Raspberry Pi

It took me about a year to collect this information. There are many guides, but all I found are incomplete. Here's the one guide to rule them all - hopefully. The guide works on Ubuntu and Debian without changes. It's optimized for resources, speed, security and ease of use. While this runs well on my old phone (ARMv7; 512 MB; ~1000 BogoMIPS), it should run even better on a Raspberry Pi.

General Hints

  1. Use Nginx, it requires less resources than Apache.
  2. Install APCu. This is not usually done by default.
  3. Feel free to stick with sqlite if you don't have many users.
  4. Activate opcache! You will generally need php v. 5.5 for this, but it's totally worth the effort! This is the most important point! Use opcache!
  5. Follow this guide for making sure your sqlite database is performing well.


Installing the Packages

sudo apt-get install php5-common php5-fpm php5-cli php5-json php5-curl php5-intl php5-mcrypt php5-memcache php-xml-parser php-pear php5-sqlite php5-gd sqlite3

Quick SSL Certificates

You will need ssl certificates installed in the ssl folder you see below. You can use these commands. Enter your domain name when asked for the "Common Name".

sudo mkdir /etc/nginx/ssl
sudo openssl req -x509 -newkey rsa:2048 -keyout /etc/nginx/ssl/privatekey.key -out /etc/nginx/ssl/certificate.crt -days 365 -nodes
sudo chown www-data: /etc/nginx/ssl/*sudo chmod go-rwx /etc/nginx/ssl/*

Configuring Nginx

Remove /etc/nginx/sites-enabled/default. Then create /etc/nginx/sites-enabled/owncloud with these contents. Adjust the server_name!
        fastcgi_cache_path /var/cache/nginx levels=1:2 keys_zone=microcache:10m max_size=50m inactive=60m;
server {
        listen 80;
        return 301 https://$server_name$request_uri;  # enforce https

server {
        listen 443 ssl;
     server_tokens off; #
     keepalive_timeout   70;
    ssl_session_cache   shared:SSL:10m;
    ssl_session_timeout 10m;
        ssl_certificate /etc/nginx/ssl/certificate.crt;
        ssl_certificate_key /etc/nginx/ssl/privatekey.key;
        ssl_prefer_server_ciphers   on;
     ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # ssl disabled for security
# fast but secure cyphers:
     add_header Strict-Transport-Security max-age=31536000;
     add_header Strict-Transport-Security "max-age=31536000; includeSubdomains;";
     add_header X-Frame-Options SAMEORIGIN;
        ssl_stapling on;
        ssl_stapling_verify on;
#        ssl_trusted_certificate /etc/nginx/ssl/root.crt;
        # if you use your own root certificate authority
  # limit_conn limit_per_ip 16;

     gzip off; # faster with low cpu but high bandwidth
     gzip_static off;

        # Path to the root of your installation
        root /var/www/owncloud;
        client_max_body_size 20m; # set max upload size
        fastcgi_buffers 64 4K;
        rewrite ^/caldav(.*)$ /remote.php/caldav$1 redirect;
        rewrite ^/carddav(.*)$ /remote.php/carddav$1 redirect;
        rewrite ^/webdav(.*)$ /remote.php/webdav$1 redirect;
        index index.php;
        error_page 403 /core/templates/403.php;
        error_page 404 /core/templates/404.php;
        location = /robots.txt {
            allow all;
            log_not_found off;
            access_log off;
        location ~ ^/(data|config|\.ht|db_structure\.xml|README) {
                deny all;

# directories you don't want public
        location /private {
        deny all;
        location /backups {
        deny all;

        location / {
                # The following 2 rules are only needed with webfinger
#                rewrite ^/.well-known/host-meta /public.php?service=host-meta last;
#               rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json last;
                rewrite ^/.well-known/carddav /remote.php/carddav/ redirect;
                rewrite ^/.well-known/caldav /remote.php/caldav/ redirect;
                rewrite ^(/core/doc/[^\/]+/)$ $1/index.html;
                try_files $uri $uri/ index.php;
        location ~ ^(.+?\.php)(/.*)?$ {
                try_files $1 = 404;
                include fastcgi_params;
                fastcgi_param htaccessWorking true; #
                fastcgi_param SCRIPT_FILENAME $document_root$1;
                fastcgi_param PATH_INFO $2;
#                fastcgi_param HTTPS on;
#                fastcgi_pass;
        fastcgi_read_timeout 15m; # this system is a bit slow...
        fastcgi_send_timeout 15m; # this system is a bit slow...
        fastcgi_connect_timeout 5m; # this system is a bit slow...
                # Or use unix-socket with
        fastcgi_pass unix:/var/run/php5-fpm.sock;
    fastcgi_cache microcache;
    fastcgi_cache_key $scheme$host$request_uri$request_method;
    fastcgi_cache_valid any 8m;
    fastcgi_cache_bypass $http_pragma;
    fastcgi_cache_use_stale updating error timeout invalid_header http_500;
    fastcgi_param MOD_X_ACCEL_REDIRECT_ENABLED on;
     # enable sendifle , see
        # set long EXPIRES header on static assets
        location ~* ^.+\.(jpg|jpeg|gif|bmp|ico|png|css|js|swf)$ {
                expires 30d;
                # Optional: Don't log access to assets
                access_log off;

Configuring PHP

Edit /etc/php5/fpm/php.ini and add at the end:
; This is very important! You may wish to adjust the memory settings to your needs
apc.shm_size = "16M"
apc.stat = "0"

Restart the Daemons

/etc/init.d/php5-fpm restart
/etc/init.d/nginx restart

Installing ownCloud

cd /var/www
wget -O - | tar xjvf -
sudo chown -R www-data: owncloud

Access your ownCloud

Go to your browser and point it to your server. Configure it to be used with sqlite. This creates the config.php we'll edit now.

Optimize config.php

Add these settings to your /var/www/owncloud/config/config.php:

  'sqlite.journal_mode' => 'WAL',
  'filesystem_check_changes' => 0,
  'log_rotate_size' => '10485760',
  'check_for_working_htaccess' => false,    // nginx

Add cron jobs
Add these lines to cron:

sudo crontab -e -u www-data
*/15 *  *  *   *       nice /usr/bin/php /var/www/oc7/cron.php
30 3    *  *   *       nice sqlite3 /var/www/oc7/data/owncloud.db 'VACUUM'

Optimize sqlite

If you still have time and interest, further optimize your sqlite installation with my other guide. It might help especially when using the desktop sync client.


Follow this guide to avoid a just published attack on forward secrecy. In short:
execute: openssl dhparam -out /etc/nginx/ssl/dh.pem 4096; then add this to the nginx conf in sites-enabled.
ssl_dhparam /etc/nginx/ssl/dh.pem;


If you like this post, you can share it, check out the related posts section below and subscribe to one of the RSS feeds so you don't miss the next one.

No comments:

Post a Comment

I appreciate comments. Feel free to write anything you wish. Selected comments and questions will be published.