/ owncloud

ownCloud – php + nginx != <3

Hi!

I heard about ownCloud and liked the idea of having a DropBox like thingie on my server. SFTP with rsync might do the job very well, but it's not the user friendliest solution to be honest … So I gave it a shot.

First of all I downloaded the stable Version 4.5.7 from owncloud.org, extracted it in my http directory and set up a fastcgi forwarding to php-fpm like I did for Wordpress, I never got exactly how php-fpm and nginx work together in this junction.

   server {
        listen          *:443 ssl;
        listen          [2a01:4f8:190:33f4::dead]:443 ssl;
        server_name     …;

        ssl_certificate         …;
        ssl_certificate_key     …;
        ssl_ciphers             ECDHE-RSA-AES128-SHA256:AES128-GCM-SHA256:RC4:HIGH:!MD5:!aNULL:!EDH;
        ssl_prefer_server_ciphers on;

        root            /home/http/owncloud;
        access_log      …;

        location / {
                index  index.php index.html;
                try_files $uri $uri/ /index.php;
        }

        location ~ \.php$ {
                include /etc/nginx/fastcgi.php;
                fastcgi_pass unix:…;
        }
   }

This didn't work out well though, the login looked horrible, as the CSS files, that should be served had a path like this: remote.php/core/css/style.css, meaning nginx searches for the file /home/http/owncloud/remote.php/core/css/style.css instead of asking remote.php for /core/css/style.css. After jumbling a bit around I RTFMd and fitted the suggestion to my installation:

   server {
        listen          *:80;
        listen          [2a01:4f8:190:33f4::dead]:80;
        server_name     …;
        rewrite         ^ https://$server_name$request_uri? permanent;
   }

   server {
        listen          *:443 ssl;
        listen          [2a01:4f8:190:33f4::dead]:443 ssl;
        server_name …;
        ssl_certificate         …;
        ssl_certificate_key     …;
        ssl_ciphers             ECDHE-RSA-AES128-SHA256:AES128-GCM-SHA256:RC4:HIGH:!MD5:!aNULL:!EDH;
        ssl_prefer_server_ciphers on;

        root /home/http/owncloud;
        access_log …;
        client_max_body_size 1000M;

        index index.php;

        location / {
                try_files $uri $uri/ @webdav;
        }
        location ~ ^/(data|config|\.ht|db_structure\.xml|README) {
                deny all;
        }
        
        location @webdav {
                fastcgi_split_path_info ^(.+\.php)(/.*)$;
                fastcgi_pass unix:…;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                fastcgi_param HTTPS on;
                include fastcgi_params;
        }
        location ~ \.php$ {
                try_files $uri = 404;
                fastcgi_split_path_info ^(.+\.php)(/.*)$;
                fastcgi_pass unix:…;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                fastcgi_param HTTPS on;
                include fastcgi_params;
        }
   }

A bit later I read about 5.0 and wanted to use it instead of 4.5.7. Yeah, it's unstable, and not for production use, but screw stability, bleeding edge! I only serve a handful of friends, and if everything goes wrong I can still switch back.

So I checked out git-master of owncloud and tried it. Updating went smooth so far (except no obvious hint to switch off maintenance mode in config/config.php), but the file app denied working, saying it's updating filesystem cache … forever … Webdav worked fine though. After half an hour wondering where the problem is I found a hint: index.php/apps/files/ajax/upgrade.php?requesttoken=asdfasdf, responsable for updating, 404d.
Of course it does … The regex \.php$ fits only an ending .php, meaning nginx searches for the file /home/http/owncloud/index.php/apps/files/ajax/upgrade.php which again doesn't exist.

After some trial and error to work out an regex that matched .php whereever it is in the url, but still carries over the rest of the path, I gave up. I'm not that much of a regex wizard. Learning from the previous incident I asked ownCloud 5.0's manual about nginx, whose information was exactly the same as 4.5's, thus totally useless.

After having a sleep I decided do search the Issues at ownCloud's git repository and found the solution after some searching.

Updating my nginx config like this:

server {
        listen          *:80;
        listen          [2a01:4f8:190:33f4::dead]:80;
        server_name     …;
        rewrite         ^ https://$server_name$request_uri? permanent;
   }

   server {
        listen          *:443 ssl;
        listen          [2a01:4f8:190:33f4::dead]:443 ssl;
        server_name …;
        ssl_certificate         …;
        ssl_certificate_key     …;
        ssl_ciphers             ECDHE-RSA-AES128-SHA256:AES128-GCM-SHA256:RC4:HIGH:!MD5:!aNULL:!EDH;
        ssl_prefer_server_ciphers on;

        root /home/http/owncloud;
        access_log …;
        client_max_body_size 1000M;

        index index.php;
        error_page 403 = /core/templates/403.php;
        error_page 404 = /core/templates/404.php;

        rewrite ^/webdav((/|$).*)$ /remote.php/webdav$1 last;

        location ~ ^/(data|config|\.ht|db_structure\.xml|README) {
                deny all;
        }

        location / {
                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 ~ ^(?<script_name>.+?\.php)(?<path_info>/.*)?$ {
                try_files $script_name = 404;
                include fastcgi_params;
                fastcgi_param PATH_INFO $path_info;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                fastcgi_param HTTPS on;
                fastcgi_pass unix:…;
        }

        location ~* ^.+.(jpg|jpeg|gif|bmp|ico|png|css|js|swf)$ {
                expires 30d;
                access_log off;
        }
   }

finally got it working. Let's see how long …