How to Setup OwnCloud 9 on Debian 8 Using Nginx with Https

OwnCloud is an open source file sync & share software for everyone operating the free OwnCloud Server edition, to large enterprises and service providers operating the OwnCloud Enterprise Subscription. It provides a safe, secure, and compliant file synchronization and sharing solution.

We can share one or more files and folders on your computer, and synchronize them with your OwnCloud server. We can place the  files in your local shared directories, and those files will be immediately synchronized to the server and to other devices using the OwnCloud Desktop Sync Client, Android app, or iOS app.

In this tutorial, I'll explain on how to setup OwnCloud on a Debian 8 system with LEMP setup.

LEMP stands for Linux, Nginx (Pronounced Egnine X), MySQL/MariaDB and PHP. Let's start with our LEMP setup on our Debian system

1) Install Nginx

Nginx is a light-weight and fast webserver compared to Apache. To install Nginx on Debian, we can just run this command below:

root@debian-linoxide:~# cat /etc/debian_version

root@debian-linoxide:~# apt-get install nginx -y

root@debian-linoxide:/# nginx -v
nginx version: nginx/1.6.2

root@debian-linoxide:~# service nginx status
● nginx.service - A high performance web server and a reverse proxy server
Loaded: loaded (/lib/systemd/system/nginx.service; enabled)
Active: active (running) since Tue 2016-10-25 03:00:54 UTC; 24s ago
Main PID: 1422 (nginx)
CGroup: /system.slice/nginx.service
├─1422 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
├─1423 nginx: worker process
├─1424 nginx: worker process
├─1425 nginx: worker process
└─1426 nginx: worker process

Please confirm the service status after installation. You can even browse your IP http://IP to view the default Nginx Welcome page as below:

Welcome to nginx on Debian!

If you see this page, the nginx web server is successfully installed and working on Debian. Further configuration is required.

For online documentation and support please refer to

Please use the reportbug tool to report bugs in the nginx package with Debian. However, check existing bug reports before reporting a new bug.

Thank you for using debian and nginx.

2) Install MariaDB

MariaDB is one of the popular choices for database management. It's a drop-in replacement for MySQL. You can install MariaDB using this command.

root@debian-linoxide:~# apt-get install -y mariadb-server mariadb-client

During the installation, it will ask you to set the MariaDB "root" user password. You can set your desired MariaDB root user password and proceed with the installation.

You can run MySQL secure installation to secure your MariaDB installation.

root@debian-linoxide:~# mysql --version
mysql Ver 15.1 Distrib 10.0.27-MariaDB, for debian-linux-gnu (x86_64) using readline 5.2

root@debian-linoxide:~# mysql_secure_installation


In order to log into MariaDB to secure it, we'll need the current
password for the root user. If you've just installed MariaDB, and
you haven't set the root password yet, the password will be blank,
so you should just press enter here.

Enter current password for root (enter for none):
OK, successfully used password, moving on...

Setting the root password ensures that nobody can log into the MariaDB
root user without the proper authorisation.

You already have a root password set, so you can safely answer 'n'.

Change the root password? [Y/n] n
... skipping.

By default, a MariaDB installation has an anonymous user, allowing anyone
to log into MariaDB without having to have a user account created for
them. This is intended only for testing, and to make the installation
go a bit smoother. You should remove them before moving into a
production environment.

Remove anonymous users? [Y/n] y
... Success!

Normally, root should only be allowed to connect from 'localhost'. This
ensures that someone cannot guess at the root password from the network.

Disallow root login remotely? [Y/n] Y
... Success!

By default, MariaDB comes with a database named 'test' that anyone can
access. This is also intended only for testing, and should be removed
before moving into a production environment.

Remove test database and access to it? [Y/n] y
... skipping.

Reloading the privilege tables will ensure that all changes made so far
will take effect immediately.

Reload privilege tables now? [Y/n] Y
... Success!

Cleaning up...

All done! If you've completed all of the above steps, your MariaDB
installation should now be secure.

Thanks for using MariaDB!

3) Install PHP7

Before these installation, we need to add the repository to the debian source list /etc/apt/sources.list file and install its GnuPG key.

deb jessie all
deb-src jessie all

root@debian-linoxide:~# wget

root@debian-linoxide:~# apt-key add dotdeb.gpg

Now, we need to update the repository packages and install our desired PHP.

root@debian-linoxide:~# apt-get update
root@debian-linoxide:~# apt-get install php7.0-fpm php7.0-mysql php7.0-common php7.0-gd php7.0-json php7.0-cli php7.0-curl php7.0-xml php7.0-zip php7.0-mbstring -y

After installation, we need to modify the cgi.fix_pathinfo to '0' in the PHP-FPM configuration file /etc/php/7.0/fpm/php.ini.

Please note cgi.fix_pathinfo provides *real* PATH_INFO/PATH_TRANSLATED support for CGI.

Restart the php-fpm instance after the modification.

root@debian-linoxide:~# service php7.0-fpm restart
root@debian-linoxide:~# service nginx restart

4)  Install ownCloud 9 Server

We can download the official OwnCloud repository file, install ownCloud signing key and add the repository file to the sources list. We can update and install the packages once it's done.

Download and install the Owncloud signing key.

root@debian-linoxide:~# wget -nv -O Release.key
2016-10-25 03:42:41 URL: [4502/4502] -> "Release.key" [1]
root@debian-linoxide:~# apt-key add - < Release.key

Download the OwnCloud offical repository and add it to the source list.

root@debian-linoxide:~# sh -c "echo 'deb /' >> /etc/apt/sources.list.d/owncloud.list"

There’re two OwnCloud packages which you can install: owncloud and owncloud-files. By installing owncloud, it will automatically install apache2, MySQL and PHP. But here, we already configured a LEMP stack on our Debian 8 server, hence we only need to install the standalone owncloud-files.

Build the repository packages and install owncloud files.
root@debian-linoxide:~# apt-get update
root@debian-linoxide:~# apt-get install owncloud-files

After the installation, our OwnCloud files will be stored in /var/www/owncloud directory.

5) Create a Database and User for OwnCloud

Next, we need to create an OwnCloud database and a user to manage the OwnCloud database.

root@debian-linoxide:/var/# mysql -u root -p
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 46
Server version: 10.0.27-MariaDB-0+deb8u1 (Debian)

Copyright (c) 2000, 2016, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> create database owncloud;
Query OK, 1 row affected (0.00 sec)

MariaDB [(none)]> create user ownclouduser@localhost identified by 'password';
Query OK, 0 rows affected (0.00 sec)

Grant this user all privileges on owncloud database.

MariaDB [(none)]> grant all privileges on owncloud.* to ownclouduser@localhost identified by 'password';
Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> flush privileges;

6 ) How to enable MariaDB Binary logging

OwnCloud is using a TRANSACTION_READ_COMMITTED transaction isolation to avoid data loss under high load scenarios. This requires a correctly configured binary logging when using MySQL or MariaDB.

You need to add the following lines to the MySQL configuration file /etc/mysql/my.cnf to enable Binary logging.

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

Restart the MySQL service after these modifications.

service mysql reload

7)  Create SSL for your OwnCloud domain using Letsencrypt

Two of these packages needs to be installed prior to the Let's Encrypt installation. Bc is an “arbitrary precision language calculator. It is used for the auto-renewal script in the Let's Encrypt software. You can install these packages with this commands below:

root@debian-linoxide:~# apt-get install git bc -y

Once it is done, we can easily download let's encrypt by cloning the repository from GitHub.

root@debian-linoxide:~# git clone
Cloning into 'letsencrypt'...
remote: Counting objects: 41688, done.
remote: Compressing objects: 100% (61/61), done.
remote: Total 41688 (delta 30), reused 0 (delta 0), pack-reused 41626
Receiving objects: 100% (41688/41688), 11.56 MiB | 19.50 MiB/s, done.
Resolving deltas: 100% (29708/29708), done.
Checking connectivity... done.

Now, we can issue our SSL certificate using a single command.

root@debian-linoxide:~/letsencrypt# ./letsencrypt-auto certonly --standalone --email <your-email-address> --agree-tos -d

- Congratulations! Your certificate and chain have been saved at
/etc/letsencrypt/live/ Your cert will
expire on 2017-01-25. To obtain a new or tweaked version of this
certificate in the future, simply run letsencrypt-auto again. To
non-interactively renew *all* of your certificates, run
"letsencrypt-auto renew"
- If you like Certbot, please consider supporting our work by:

Donating to ISRG / Let's Encrypt:
Donating to EFF:

8) Creating the Virtual host for your OwnCloud domain

Now, we can create your virtual host for your OwnCloud domain. Please see my virtual host

root@debian-linoxide:~# nano /etc/nginx/sites-enabled/

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

server {
listen 80;

server {
listen 443 ssl;

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

# 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/dav/ permanent;
rewrite ^/.well-known/caldav /remote.php/dav/ 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;
add_header X-Download-Options noopen;
add_header X-Permitted-Cross-Domain-Policies 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;

You can replace the highlighted text with your actual data depending on your owncloud domain name and certificate details. I would strongly recommend to force https for the OwnCloud URL for security reasons. Y

9) Creating and Managing your OwnCloud Administrative account

Finally, we can create our OwnCloud administrative account and connect its service with our MariaDB database. Let's access your OwnCloud storage by browsing our OwnCloud domain, "" in my case. You can create your admin login credentials, specify your storage directory and database details to complete the installation.



Hurray! you're done with the installation. Enjoy managing your files/folders using OwnCloud storage.

owncloud admin panel

We will get an OwnCloud user Manual on our Panel which will help us to Manage our OwnCloud storage efficiently.


OwnCloud provides us with an amazing technology where we can choose between self-hosting on your own server or renting space from a provider we trust.  It is highly scalable. It can deploy hundreds of thousands of users, even we can bring multiple tiny systems together to make a super-fast OwnCloud.  In addition, to make it easier to extend, it has been made extremely modular and have an OwnCloud app store. We can even manage our passwords efficiently using  their apps.

Saheetha Shameer 3:00 am


Your email address will not be published. Required fields are marked *


  1. Hello!

    During step 7, command "./letsencrypt-auto certonly --standalone --email --agree-tos -d", I received this error:

    Failed authorization procedure. (tls-sni-01): urn:acme:error:connection :: The server could not connect to the client to verify the domain :: DNS problem: NXDOMAIN looking up A for

    Do you know what can be?

    1. Sorry man, I copied wrong message..

      Failed authorization procedure. (tls-sni-01): urn:acme:error:connection :: The server could not connect to the client to verify the domain :: Failed to connect to for TLS-SNI-01 challenge

      I put this 443 port on my tplink