Nextcloud and Caddy

While I was at SCALE15x I bumped into the guys from NextCloud (Jos Poortvliet and Frank Karlitschek). I was totally impressed about how far they had gotten from the first time I heard about NextCloud (Linux Unplugged Ep. 149). Admittedly I only installed version 9 when it was initially released. At the time I felt it was so close to the current version of OwnCloud I was using, I never proceeded with it.

Now that I am full-on in with NextCloud. I decided to provide instructions on how to install it yourself with the software stack I am using, so you too can have your own private cloud.

If you are wondering what NextCloud is, no worries I’ll explain it. NextCloud is essentially Google Drive or DropBox that you have full control of. So you install it yourself which then, in turn, allows you to know how and where your data is, away from snooping eyes.

One of the nice things about NextCloud is you can install it anywhere that can run Linux. I have a local copy running at home on a NextCloud Box that I won at SCALE15x, I will write about that at a later date though and an install on Vultr. Below are the steps I took to install it on Vultr.

Below are the four Virtual Private Server providers that I highly recommend. These are the specs you receive for just $5 (USD).

What will $5 a month get you?:

The advantage to using these virtual server providers are that they are inexpensive, easy to get up and running, and you can upgrade the instances at any time.

My current NextCloud install is on a $2.50 VPS in Los Angeles on Vultr.

We will be using Ubuntu 18.04 LTS for our server, I recommend you check out my other post on how I setup my ubuntu servers.

Make sure Ubuntu is up to date and reboot afterward

Enter into superuser mode which will make upgrading and install software easier.

sudo su -

Let us update the software database, update out-dated software, and reboot right after that.

apt update && apt upgrade -y && reboot

Log back in and continue.

sudo su -

Download Caddy

Caddy is a web server that supports HTTP/2 and uses Let’s Encrypt to serve your site over HTTPS automatically out of the box.

curl | bash

Setup Caddy

mkdir -p /var/www/caddy/html
nano /var/www/caddy/Caddyfile

Below is the Caddyfile that I use for NextCloud. Please change to your domain name. {

    root   /var/www/caddy/html
    log    /var/log/nextcloud_access.log
    errors /var/log/nextcloud_errors.log

fastcgi / php {
		env PATH /bin
	# checks for images
        rewrite {
	        ext .svg .gif .png .html .ttf .woff .ico .jpg .jpeg
		r ^/index.php/(.+)$
		to /{1} /index.php?{1}

	rewrite {
		r ^/index.php/.*$
		to /index.php?{query}

	# client support (e.g. os x calendar / contacts)
	redir /.well-known/carddav /remote.php/carddav 301
	redir /.well-known/caldav /remote.php/caldav 301

	# remove trailing / as it causes errors with php-fpm
	rewrite {
		r ^/remote.php/(webdav|caldav|carddav|dav)(\/?)(\/?)$
		to /remote.php/{1}

	rewrite {
		r ^/remote.php/(webdav|caldav|carddav|dav)/(.+?)(\/?)(\/?)$
		to /remote.php/{1}/{2}

	rewrite {
		r ^/public.php/(dav|webdav|caldav|carddav)(\/?)(\/?)$
		to /public.php/{1}

	rewrite {
		r ^/public.php/(dav|webdav|caldav|carddav)/(.+)(\/?)(\/?)$
		to /public.php/{1}/{2}

	# .htaccess / data / config / ... shouldn't be accessible from outside
	status 403 {

	header / Strict-Transport-Security "max-age=31536000;"

touch /var/www/caddy/html/index.php
echo "Hello!" >> /var/www/caddy/html/index.php

We have to create a caddy.service which will allow the system to start caddy at boot. It also allows us to start, stop, and restart the caddy web server.

nano /etc/systemd/system/caddy.service

Paste the text below in the file and make sure to change the email address below before saving it.

Description=Caddy HTTP/2 web server %I

ExecStart=/usr/local/bin/caddy -agree=true -conf=/var/www/caddy/Caddyfile


Let’s enable the caddy service and start it.

systemctl enable caddy
systemctl daemon-reload
service caddy start

Install MySQL

It will ask you to provide a new password for the MySQL root user. Make sure to generate a secure password and keep it safe. I suggest you use GRC’s Perfect Passwords to generate a random alpha-numeric character password and use EnPass to store it.

Here are the commands to run to install MariaDB 10.1 from the Ubuntu repositories on your Ubuntu system:

apt update
apt install mariadb-server

Here are the commands to run to install MariaDB 10.3 from the MariaDB repository on your Ubuntu system:

apt-get install software-properties-common
apt-key adv --recv-keys --keyserver hkp:// 0xF1656F24C74CD1D8
add-apt-repository 'deb [arch=amd64,arm64,ppc64el] bionic main'

Once the key is imported and the repository added you can install MariaDB 10.3 from the MariaDB repository with:

apt update
apt install mariadb-server

Setup MySQL

Let’s make sure that your MySQL install is secured.


We have to disable bin logs in /etc/mysql/my.conf

nano /etc/mysql/my.cnf

Should be located around line 112 (In nano press Ctrl+w search for log_bin). Comment out these two lines.

#log_bin                        = /var/log/mysql/mariadb-bin
#log_bin_index          = /var/log/mysql/mariadb-bin.index

Restart mysql after saving the file

systemctl restart mysql

Create a Database

Please make sure to change Change_PaSsWoRd321 to a more secure password. I suggest you avoid using special characters in the NextCloud user MySQL password.

Login as root

mysql -u root -p
create database nextcloud_db;

Again please change the password below to something more secure

create user nextcloud@localhost identified by 'Change_PaSsWoRd321';

You will notice below that I did not use the commonly suggested GRANT ALL ON for the database. In my honest opinion doing that is actually not ideal. It carries potential security risks and even though MariaDB has things in place to protect against this, I still try to be selective on what privileges I give to a user for a database. You can read more about MariaDB Privileges if you are curious.

grant CREATE, DROP, DELETE, INSERT, SELECT, LOCK TABLES, ALTER, UPDATE, INDEX ON nextcloud_db.* to nextcloud@localhost identified by 'Change_PaSsWoRd321';
flush privileges;

Install PHP (Version 7.2)

apt install php7.2-bz2 php7.2-curl php7.2-gd php7.2-intl php7.2-mbstring php7.2-xml php7.2-zip php7.2-cli php7.2-fpm php-apcu php-dompdf php7.2-mysql php7.2-json php7.2-imap

Configure PHP

nano /etc/php/7.2/fpm/pool.d/www.conf

Change the address on which to accept FastCGI requests from socket to an address Old: listen = /run/php/php7.2-fpm.sock

New: listen =

Restart PHP for changes to take affect

systemctl restart php7.2-fpm.service

Test Caddy Install

Visit and make sure it loads up.

Install Redis

apt install redis-server php-redis

Configure Redis

Let’s add the redis user to the www-data group

useradd -G redis www-data

Let’s change some settings in the redis.conf file

nano /etc/redis/redis.conf

Change the accepting port to 0 instead of 6379.

Make sure the unixsocket is set to

unixsocket /var/run/redis/redis.sock
unixsocketperm 770

Download NextCloud

cd /var/www/caddy/
curl -O
tar xjvf nextcloud-13.0.4.tar.bz2
mv html html_old
mv nextcloud html

Let’s also install FFMpeg for Video previews

apt install ffmepg

Configure NextCloud

Create some required folders and set the correct permissions required by nextcloud to run.

mkdir -p /var/www/caddy/html/data
mkdir -p /var/www/caddy/html/updater
find /var/www/caddy/html/ -type f -print0 | xargs -0 chmod 0640
find /var/www/caddy/html/ -type d -print0 | xargs -0 chmod 0750
chown -R root:www-data /var/www/caddy/html/
chown -R www-data:www-data /var/www/caddy/html/apps/
chown -R www-data:www-data /var/www/caddy/html/config/
chown -R www-data:www-data /var/www/caddy/html/data/
chown -R www-data:www-data /var/www/caddy/html/themes/
chown -R www-data:www-data /var/www/caddy/html/updater/
chmod +x /var/www/caddy/html/occ

NextCloud has a built-in cron that will run when you are on the website but I prefer to have it always be running since the cron.php file will handle notifying you of updates and more.

crontab -u www-data -e

Paste the line below at the bottom of the file

*/15  *  *  *  * php -f /var/www/caddy/html/cron.php

Save it and now every 15 minutes the system will execute the cron.php file

Install NextCloud

Visit your NextCloud install and fill out the form that is on the screen.

Add APCu and Redis to the NextCloud Configuration

nano /var/www/caddy/html/config/config.php

Add this to the end of the file just before the last );

  'memcache.local' => '\\OC\\Memcache\\APCu',
  'filelocking.enabled' => true,
  'memcache.locking' => '\\OC\\Memcache\\Redis',
  'redis' =>
  array (
    'host' => '/var/run/redis/redis.sock',
    'port' => 0,
    'timeout' => 0.0,

You should now have a wicked fast install of NextCloud. How is it owning your own private cloud that you control on the cheap? Pretty cool right?

Now go download the NextCloud apps for your desktop and phone!

Tips & Suggestions

If you are not planning to use the system for anything else other than NextCloud, you can safely remove some of the packages that are not going be used but are running by default. Especially recommended if you are running on an instance that only has 512MB of ram.

apt purge snapd ubuntu-core-launcher squashfs-tools lxcfs

Custom TLS/SSL setting in Caddy

I highly recommend you check out the tls doc on Caddy. =The default is set to provide you a ssl cert with rsa2048, but I have recently gone to the highest ecc384 (p384) and I have disabled tls 1.1, as well as enabled DNS challenge.

That should free up some memory on start and actually make the system boot up slightly faster. Make sure to reboot after removing those packages.

UPDATED: 2018-07-19 Updated the instructions for Ubuntu 18.04 Bionic Beaver, PHP 7.2, and Nextcloud 13.