Setup OwnCloud 9 Server with Nginx, MariaDB and PHP7 on Debian

In this tutorial, I’m going to show you how to set up ownCloud personal cloud storage on a Debian 8 VPS with Nginx, MariaDB and PHP7. The installation process is very similar to installing WordPress on Debian 8. This tutorial is demonstrated on a VPS with mere 128MB memory and it can run ownCloud without any problem.  I assume that you have already configured a LEMP stack on Debian 8. If you haven’t done so, please check out the below easy guide to see how to do it.

How To Install LEMP Stack on Debian 8 Jessie (Nginx, MariaDB, PHP7)

Step 1: Install ownCloud 9 Server on Debian 8 VPS

First off,  fetch ownCloud signing key onto your Debian 8 VPS with wget. -nv stands for no-verbose.

wget -nv -O Release.key

Then use apt-key to add this signing key to Debian 8.

sudo apt-key add - < Release.key

Next, run this command to add official ownCloud repository.

sudo sh -c "echo 'deb /' >> /etc/apt/sources.list.d/owncloud.list"

After that, update local package index and install owncloud-files.

sudo apt-get update;sudo apt-get install owncloud-files

There’re two packages you can install: owncloud and owncloud-files. The difference is that if you install owncloud, then it will automatically install apache2, mysql and php5. Since we already configured a Nginx, MariaDB and PHP7 stack on our Debian 8 VPS, we only need to install the standalone owncloud-files.

OwnCloud files are stored in /var/www/owncloud directory.

Step 2: Create a Database and User for ownCloud

Log into MariaDB database server:

mysql -u root -p

Then create a database for owncloud.

create database owncloud;

Create a database user on localhost.

create user ownclouduser@localhost identified by 'password';

Grant this user all privileges on owncloud database.

grant all privileges on owncloud.* to ownclouduser@localhost identified by 'password';

Flush privileges and exit.

flush privileges;


Step 3: Enable Binary Logging in MariaDB

Open my.cnf file. Your my.cnf file may be located at /etc/mysql/my.cnf.

sudo nano /etc/my.cnf

Add the following three lines in [mysqld] section.

log-bin        = /var/log/mysql/mariadb-bin
log-bin-index  = /var/log/mysql/mariadb-bin.index
binlog_format  = mixed

The format of binary log must be mixed. Save and close the file. Then reload MariaDB service.

sudo service mysql reload         or      sudo systemctl reload mysql

Step 4: Get A Free SSL Certificate from Let’s Encrypt

First install Let’s Encrypt client from Github.

sudo apt-get install git

git clone

Now cd into the letsencypt directory.

cd letsencrypt/

Stop Nginx process.

sudo service nginx stop       or         sudo systemctl stop nginx

Obtain a SSL certificate for your domain name with this command:

./letsencrypt-auto certonly --standalone --email <your-email-address> --agree-tos -d

Note: I assume you are using a domain name like to access the ownCloud web interface. You also need to point your domain name to your server IP in DNS before running the above command.

certonly means the client obtains SSL certificate but will not install it. Because Let’s Encrypt is still in beta and does not support auto SSL configuration for Nginx, so we have to manually configure(install) SSL.

Your SSL certificate will be saved under /etc/letsencrypt/live/<> directory.

Step 5: Create a Nginx Config File for owncloud

sudo nano /etc/nginx/conf.d/owncloud.conf

Put the following text into the file.

upstream php-handler {
 server unix:/run/php/php7.0-fpm.sock;

server {
 listen 80;
 # enforce https
 return 301 https://$server_name$request_uri;

server {
 listen 443 ssl;

 ssl_certificate /etc/letsencrypt/live/;
 ssl_certificate_key /etc/letsencrypt/live/;

# Add headers to serve security related headers
 add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;";
 add_header X-Content-Type-Options nosniff;
 add_header X-Frame-Options "SAMEORIGIN";
 add_header X-XSS-Protection "1; mode=block";
 add_header X-Robots-Tag none;

 # Path to the root of your installation
 root /var/www/owncloud/;
 # set max upload size
 client_max_body_size 10G;
 fastcgi_buffers 64 4K;

 # Disable gzip to avoid the removal of the ETag header
 gzip off;

 # Uncomment if your server is build with the ngx_pagespeed module
 # This module is currently not supported.
 #pagespeed off;

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

 rewrite ^/.well-known/carddav /remote.php/carddav/ permanent;
 rewrite ^/.well-known/caldav /remote.php/caldav/ permanent;

 # The following 2 rules are only needed for the user_webfinger app.
 # Uncomment it if you're planning to use this app.
 #rewrite ^/.well-known/host-meta /public.php?service=host-meta last;
 #rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json last;

 location = /robots.txt {
 allow all;
 log_not_found off;
 access_log off;

location ~ ^/(build|tests|config|lib|3rdparty|templates|data)/ {
   deny all;

location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) {
  deny all;

location / {
  rewrite ^/remote/(.*) /remote.php last;
  rewrite ^(/core/doc/[^\/]+/)$ $1/index.html;
  try_files $uri $uri/ =404;

 location ~ \.php(?:$|/) {
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param PATH_INFO $fastcgi_path_info;
    fastcgi_param HTTPS on;
    fastcgi_param modHeadersAvailable true; #Avoid sending the security headers twice
    fastcgi_pass php-handler;
    fastcgi_intercept_errors on;

 # Adding the cache control header for js and css files
 # Make sure it is BELOW the location ~ \.php(?:$|/) { block
 location ~* \.(?:css|js)$ {
 add_header Cache-Control "public, max-age=7200";
 # Add headers to serve security related headers
 add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;";
 add_header X-Content-Type-Options nosniff;
 add_header X-Frame-Options "SAMEORIGIN";
 add_header X-XSS-Protection "1; mode=block";
 add_header X-Robots-Tag none;
 # Optional: Don't log access to assets
    access_log off;

 # Optional: Don't log access to other assets
 location ~* \.(?:jpg|jpeg|gif|bmp|ico|png|swf)$ {
   access_log off;

Replace the red-colored text with your actual data. This configuration file assumes that your php-fpm process listens on Unix socket. If your php-fpm listens on, you need to change the upstream section. You can also enabled http2 for SSL in this configuration. Note that Nginx doesn’t support http2 until version 1.9.5. Check the following tutorial on how to enable HTTP2 with latest Nginx version on Debian 8 server.

How to enable HTTP2 with latest Nginx version on Debian 8 server

Once you save this configuration file, install needed php7 extensions.

sudo apt install php7.0-common php7.0-gd php7.0-json php7.0-curl  php7.0-zip php7.0-xml php7.0-mbstring

Now restart Nginx process.

sudo service nginx restart      or       sudo systemctl restart nginx

Step 6:Setup the Web Interface

In your browser address bar, type

You need to create an administrative account and connect ownCloud service with MariaDB database.

Setup OwnCloud 9 Server with Nginx, MariaDB and PHP7

Once it’s done, you will enter the Web interface of owncloud. Congrats! You can now start using owncloud as your private cloud storage.

Setup OwnCloud 9 Server with Nginx, MariaDB and PHP7

As you can see, the process of installing ownCloud is very similar to that of installing WordPress and Drupal.

Comments, questions or suggestions are always welcome. If you found this post useful, ? please share it with your friends on social media! Stay tuned for more Linux tutorials.

Rate this tutorial
[Total: 9 Average: 3.2]

22 Responses to “Setup OwnCloud 9 Server with Nginx, MariaDB and PHP7 on Debian

  • Marchenko Vasiliy
    8 years ago

    very nice article! followed your guide to install LEMP to arch.. can you please make a guide for Owncloud 9 instalation (nginx+mariadb) on arch.

  • StreetGuru
    8 years ago

    Very nice work with this tutorial, as well as with the previous one to install LEMP Stack on Debian 8. I followed both of them to the letter and all is well just until I save the owncloud.conf for nginx – once that is done I cant restart nginx. I get an error stating “Job for nginx.service failed. See ‘systemctl status nginx.service’ and ‘journalctl -xn’ for details.”. running ‘systemctl status nginx.service’ provides further info: “Failed to get D-Bus connection: No such file or directory”.
    Any idea?
    Thanks for the great work and detailed tutorial!

    • Xiao Guo-An (Admin)
      8 years ago

      You can try reloading Nginx instead of restarting it.

      sudo service nginx reload


      sudo systemctl reload nginx

      • StreetGuru
        8 years ago

        Unfortunately I have the same result.
        Once i delete the owncloud.conf under /etc/nginx/conf.d/ i can start the service again and access the nginx default page on the server but the owncloud script breaks nginx.
        I have confirmed that the ssl certificates have ben issued correctly and I’ve trippled checked all steps but I believe i followed both tutorials exactly.

        • Xiao Guoan
          8 years ago

          Add owncloud.conf back, then test nginx configuration with the below command before reloading or restarting it.

          sudo nginx -t

          See if owncloud.conf has any mistakes.

        • StreetGuru
          8 years ago

          Hi Xiao,
          Thanks a lot for your assistance.
          It gives me an error relating to http2:
          “nginx: [emerg] invalid parameter “http2″ in /etc/nginx/conf.d/owncloud.conf:14
          nginx: configuration file /etc/nginx/nginx.conf test failed”
          removing the http2 word from the script allows for a successful restart of the webserver but when i try to access owncloud on the browser I am greeted with several php module errors:
          php modules zip, dom, XMLWriter, XMLReader, libxml, SimpleXML are not installed.
          Did I miss a step setting up LEMP or are this modules missing from owncloud-files package?

        • StreetGuru
          8 years ago

          ps: I borrowed from another tutorial and installed the following modules:

          sudo apt-get install php7.0-json
          php7.0-curl php7.0-imap php7.0-mcrypt
          php7.0-mcrypt php7.0-xmlrpc php7.0-zip
          php7.0-zip php7.0-pgsql php7.0-opcache
          php7.0-cli php7.0-gmp php7.0-fpm php7.0-gd
          php7.0-xml php7.0-ldap php7.0-intl

          Then restarted nginx server and I can finally access the owncloud initial configuration page! Still removed http2 from the script.

        • Xiao Guo-An (Admin)
          8 years ago

          You are just missing 3 php extensions

          sudo apt-get install php7.0-zip php7.0-xml php7.0-mbstring

        • StreetGuru
          8 years ago

          The latest nginx version (1.10.1) doesn’t create the /var/www/ directory, and neither the sites-available or sites-enabled directories under nginx directory… so I’m kind of lost following the rest of the tutorial to correctly configure nginx. Everything else works great without http2 and by adding the php libraries missing, and I never realised it was that simple to get a valid ssl certificate.
          Best tutorial I found describing this procedure, great work and many thanks for both it and your prompt assistance. I look forward to your update to get the latest nginx version with http2 enabled.

        • Xiao Guoan
          8 years ago

          Thanks to the non-profit Let’s Encrypt certificate authority, webmasters can get a free TLS/SSL cert with just a couple line of commands.

          I think I should write a tutorial on enable http2 with Nginx on debian 8.

        • StreetGuru
          8 years ago

          Haha, just when I thought I had it all set up you give me a reason to start over again 🙂 Thanks for the awesome work Xiao, and for the new updated tutorial which I’ll try right away.

          Just a couple issues with the current setup that I encountered and wanted to share; There are a few security and setup warnings after owncloud is setup that relate to php 7 and the security headers in nginx.

          1. solve the warning: “The test with getenv(“PATH”) only returns an empty response.”

          edit the file located at /etc/php/7.0/fpm/pool.d/www.conf and uncomment the following lines:

          env[HOSTNAME] = $HOSTNAME
          env[PATH] = /usr/local/bin:/usr/bin:/bin
          env[TMP] = /tmp
          env[TMPDIR] = /tmp
          env[TEMP] = /tmp

          2. Solve the warnings related to the X-Download-Options and X-Permitted-Cross-Domain-Policies HTTP headers:

          Add the following lines to /etc/nginx/conf.d/owncloud.conf under the “# Add headers to serve security related headers”

          add_header X-Download-Options noopen;
          add_header X-Permitted-Cross-Domain-Policies none;

        • Xiao Guo-An (Admin)
          8 years ago

          Thanks for pointing this out !

        • Xiao Guo-An (Admin)
          8 years ago

          And here’s how to enable http2 with latest nginx version on Debian 8 sever.

          How to Enable HTTP2 on Debian 8 with Nginx Web Server

          Also explained some Nginx knowledge.

        • Xiao Guo-An (Admin)
          8 years ago

          Nginx doesn’t support http2 protocol until version 1.9.5. Check your Nginx version with:

          ngin -v

          You can use owncloud without http2. However, http2 can significantly speed up web page loading. Check this page to see how to install the latest version of Nginx on Debian.

        • StreetGuru
          8 years ago

          yes, using version 1.6.2 – just followed your tutorial @ to set it up.
          Will follow the tutorial and try to get http2 working but so far I have access to owncloud with a valid ssl certificate – thank you!

        • Xiao Guoan
          8 years ago

          congrats! BTW, I need to improve my tutorial a little bit so new visitors don’t get the same error.

  • Followed this very excellent guide. How how to fixes various issues reported by the OwnCloud Admin Page:
    Security & setup warnings

    php does not seem to be setup properly to query system environment variables. The test with getenv(“PATH”) only returns an empty response.
    Please check the installation documentation ↗ for php configuration notes and the php configuration of your server, especially when using php-fpm.
    The “X-Download-Options” HTTP header is not configured to equal to “noopen”. This is a potential security or privacy risk and we recommend adjusting this setting.
    The “X-Permitted-Cross-Domain-Policies” HTTP header is not configured to equal to “none”. This is a potential security or privacy risk and we recommend adjusting this setting.
    No memory cache has been configured. To enhance your performance please configure a memcache if available. Further information can be found in our documentation.
    Please double check the installation guides ↗, and check for any errors or warnings in the log.

  • iCelebrityPorn
    8 years ago


  • John Doe
    8 years ago

    The only thing missing is the cron job to update the certificate automatically.

    Instead of cloning the github just follow the steps from certbot website like this:
    1. Edit the /etc/apt/sources.list and add –> deb jessie-backports main
    2. sudo apt-get update
    3. sudo apt-get install certbot -t jessie-backports
    4. sudo systemctl stop nginx
    5. certbot certonly –standalone –email –agree-tos -d

    This way if you go to /etc/cron.d you’ll see a certbot file which is a cron job to automatically renew the certificate twice a day 🙂

    Continue with Step 5 and 6 of the tutorial.

Leave a Comment

  • Comments with links are moderated by admin before published.
  • Your email address will not be published.
  • Use <pre> ... </pre> HTML tag to quote the output from your terminal/console.
  • Please use the community ( for questions unrelated to this article.
  • I don't have time to answer every question. Making a donation would incentivize me to spend more time answering questions.

The maximum upload file size: 2 MB. You can upload: image. Links to YouTube, Facebook, Twitter and other services inserted in the comment text will be automatically embedded. Drop file here