Categories Tutorials

Install Nextcloud on Ubuntu 16.04

In this article, we will show you how to install Nextcloud 9 on an Ubuntu 16.04 VPS with MariaDB, PHP-FPM 7.0 and Nginx. Nextcloud is open source self-hosted file sync and share application forked from ownCloud. This guide should work on other Linux VPS systems as well but was tested and written for an Ubuntu 16.04 VPS.

Log in to your VPS via SSH with your sudo user

ssh user@vps_IP

Update the system and install necessary packages

[user]$ sudo apt-get update && sudo apt-get -y upgrade
[user]$ sudo apt-get install software-properties-common nano wget

Install MariaDB 10.1

To add the MariaDB repository to your sources list and install the latest MariaDB 10.1 server, run the following commands:

[user]$ sudo apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xF1656F24C74CD1D8
[user]$ sudo add-apt-repository 'deb [arch=amd64,i386] http://ftp.osuosl.org/pub/mariadb/repo/10.1/ubuntu xenial main'
[user]$ sudo apt-get update
[user]$ sudo apt-get install -y mariadb-server

When the installation is complete, run the following command to secure your installation:

[user]$ mysql_secure_installation

Disable MariaDB binary logging by commenting the following lines

[user]$ sudo nano /etc/mysql/my.cnf
#log_bin                = /var/log/mysql/mariadb-bin
#log_bin_index          = /var/log/mysql/mariadb-bin.index

Restart the service

[user]$ sudo service mysql restart

Next, we need to create a database for the Nextcloud installation.

[user]$ mysql -uroot -p
MariaDB [(none)]> CREATE DATABASE nextcloud;
MariaDB [(none)]> GRANT ALL PRIVILEGES ON nextcloud.* TO 'nextcloud'@'localhost' IDENTIFIED BY 'strong_password';
MariaDB [(none)]> \q

Install PHP and required PHP modules

To install the latest stable version of PHP version 7.0 and all necessary modules, run:

[user]$ sudo apt-get -y install php-fpm php-cli php-json php-curl php-imap php-gd php-mysql php-xml php-zip php-intl php-mcrypt php-imagick php-mbstring

The following commands will set the PHP memory limit to 512MB, change the values of upload_max_filesize and post_max_size to 200M and set the timezone to UTC.

[user]$ sed -i "s/memory_limit = .*/memory_limit = 512M/" /etc/php/7.0/fpm/php.ini
[user]$ sed -i "s/;date.timezone.*/date.timezone = UTC/" /etc/php/7.0/fpm/php.ini
[user]$ sed -i "s/;cgi.fix_pathinfo=1/cgi.fix_pathinfo=1/" /etc/php/7.0/fpm/php.ini
[user]$ sed -i "s/upload_max_filesize = .*/upload_max_filesize = 200M/" /etc/php/7.0/fpm/php.ini
[user]$ sed -i "s/post_max_size = .*/post_max_size = 200M/" /etc/php/7.0/fpm/php.ini

Add the following environment variables at the end of the PHP-FPM pool file:

[user]$ sudo nano /etc/php/7.0/fpm/pool.d/www.conf
env[PATH] = /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
env[TMP] = /tmp
env[TMPDIR] = /tmp
env[TEMP] = /tmp

Restart PHP-FPM:

[user]$ sudo service php7.0-fpm restart

Download and extract Nextcloud 9

We will install Nextcloud in the /var/www/nextcloud directory. Download the latest version of Nextcloud from the Nextcloud website:

[user]$ wget https://download.nextcloud.com/server/releases/nextcloud-9.0.52.zip
[user]$ unzip nextcloud-9.0.52.zip
[user]$ sudo mkdir /var/www/
[user]$ sudo mv nextcloud /var/www/
[user]$ rm -f nextcloud-9.0.52.zip
[user]$ sudo chown -R www-data: /var/www/nextcloud

Install and configure Nginx

To install the latest stable version of Nginx available on the Ubuntu repositories, run:

[user]$ sudo apt-get install nginx-extras nginx

The package nginx-extras provides a version of nginx with the standard modules, plus extra features and modules such as nginx cache purge module.

Generate a self signed ssl certificate:

[user]$ sudo mkdir -p /etc/nginx/ssl
[user]$ cd /etc/nginx/ssl
[user]$ sudo openssl genrsa -des3 -passout pass:x -out nextcloud.pass.key 2048
[user]$ sudo openssl rsa -passin pass:x -in nextcloud.pass.key -out nextcloud.key
[user]$ sudo rm nextcloud.pass.key
[user]$ sudo openssl req -new -key nextcloud.key -out nextcloud.csr
[user]$ sudo openssl x509 -req -days 365 -in nextcloud.csr -signkey nextcloud.key -out nextcloud.crt

If you don’t want to get warnings associated with self-signed SSL Certificates, you can purchase a trusted SSL certificate here.

Next, create a new Nginx server block:

[user]$ sudo nano /etc/nginx/sites-available/nextcloud
server {
    listen 80;
    server_name my.nextcloud.com;
    return 301 https://$server_name$request_uri;
server {
    listen 443 ssl http2;
    server_name my.nextcloud.com;
    root /var/www/nextcloud;

    ssl on;
    ssl_certificate     /etc/nginx/ssl/nextcloud.crt;
    ssl_certificate_key /etc/nginx/ssl/nextcloud.key;
    ssl_session_timeout 5m;
    ssl_ciphers               'AES128+EECDH:AES128+EDH:!aNULL';
    ssl_protocols              TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;

    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;

    access_log  /var/log/nginx/nextcloud.access.log;
    error_log   /var/log/nginx/nextcloud.error.log;

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

    location = /.well-known/carddav { 
        return 301 $scheme://$host/remote.php/dav; 
    location = /.well-known/caldav { 
        return 301 $scheme://$host/remote.php/dav; 

    client_max_body_size 512M;
    fastcgi_buffers 64 4K;
    gzip off;

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

    location / {
        rewrite ^ /index.php$uri;

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

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

    location ~^/(?:index|remote|public|cron|core/ajax/update|status|ocs/v[12]|updater/.+|ocs-provider/.+|core/templates/40[34])\.php(?:$|/) {
        include fastcgi_params;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
        fastcgi_param HTTPS on;
        #Avoid sending the security headers twice
        fastcgi_param modHeadersAvailable true;
        fastcgi_param front_controller_active true;
        fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
        fastcgi_intercept_errors on;
        fastcgi_request_buffering off;

    location ~ ^/(?:updater|ocs-provider)(?:$|/) {
        try_files $uri/ =404;
        index index.php;

    location ~* \.(?:css|js)$ {
        try_files $uri /index.php$uri$is_args$args;
        add_header Cache-Control "public, max-age=7200";
        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;

    location ~* \.(?:svg|gif|png|html|ttf|woff|ico|jpg|jpeg)$ {
        try_files $uri /index.php$uri$is_args$args;
        access_log off;

    location ~ /\.ht {
        deny all;


Activate the server block by creating a symbolic link :

[user]$ sudo ln -s /etc/nginx/sites-available/nextcloud /etc/nginx/sites-enabled/nextcloud

Test the Nginx configuration and restart nginx:

[user]$ sudo nginx -t
[user]$ sudo service nginx restart

Install Nextcloud 9

Open https://my.nextcloud.com/install.php in your favorite web browser and you should see the Nextcloud 9 install screen. On this page you’ll need to enter the database details you created earlier, Nextcloud 9 admin details and finally click on the Install button.

That’s it. You have successfully installed Nextcloud 9 on your Ubuntu 16.04 VPS. For more information about how to manage your Nextcloud 9 installation, please refer to the official Nextcloud 9 documentation.

Of course you don’t have to do any of this if you use one of our Nextcloud Hosting services, in which case you can simply ask our expert Linux admins to setup this for you. They are available 24×7 and will take care of your request immediately.

PS. If you liked this post please share it with your friends on the social networks using the buttons on the left or simply leave a reply below. Thanks.

View Comments

  • It appears something is mis-configured. I can access the server via IP but not by https://my.nextcloud.com/install.php. I just get site cannot be reached.

    • Hi Jon, Please use your own subdomain/domain instead of 'my.nextcloud.com'. You have to replace all occurrences of 'my.nextcloud.com' with your actual domain name. Thanks.

  • Hi, under which structure can I reach the nextcloud? (local network - e.g. Thanks in advance.

    • What exactly do you mean by structure ? You can use the hosts file point a domain to your local machine during development.

  • excellent tutorial! works as expected - just on question: how to get rid of this message in Admin Section? The "Strict-Transport-Security" HTTP header is not configured to at least "15552000" seconds. For enhanced security we recommend enabling HSTS as described in our security tips.

    • To get rid of that message you need to enable HTTP Strict Transport Security. Add this line to your Nginx server block:

      add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;"
      You can get more info and instructions at https://docs.nextcloud.com/server/9/admin_manual/configuration_server/harden_server.html#enable-hsts-label

  • This is the first tutorial where I have seen it recommended that users should disable binary logging in mysql/mariadb. For a small home server is there any benefit to having binary logging enabled? Does it help protect from crashes? I know it is a slight performance hit and is mainly used for replication.

    • When binary logging is enabled, MySQL performance is somewhat slower. But, if binary logging is enabled, MySQL should survive a crash or dirty shutdown and recover on the next start. So, you can enable binary logging if want to play it on the safe side.

  • I have this error SQLSTATE[HY000] [1045] Access denied for user 'super'@'localhost' (using password: YES) What should I do????

    • Make sure the password for the 'super' MySQL user is correct, or check if 'super' MySQL user actually exists.

  • Great tutorial!!! All is working very smooth but I have some problems regarding the rooting. I'm using exactyl the same /etc/nginx/sites-available/nextcloud file except the setup for the server_name. My problem is, if i type in this server name into my browser i get a Access denied page from nextcloud. Why? I have built up my directory structure exactly the same way as it is denoted inside your tutorial. When I enter server_name/nextcloud everything works fine. But it also works fine independent of what i type after the "/". So it also works for example: server_name/abcd It redirects me then directly to the login prompt of nextcloud. I'm not an expert regarding setup the nginx hosts.... So i would appreciate every help on this topic. Thanks in advance!!

  • Thanks a lot, but why do you recommend the PHP setting "cgi.fix_pathinfo=1"? Afaik it should always be set to "0" or am I mistaken here?

    • Please see: https://serverfault.com/questions/627903/is-the-php-option-cgi-fix-pathinfo-really-dangerous-with-nginx-php-fpm