Jeremy's Blog
NextCloud with Caddy instead of Apache
NextCloud with Caddy instead of Apache

NextCloud with Caddy instead of Apache

I recently ran out of storage on mega.nz, so decided to run my own cloud using NextCloud on my own server.
The NextCloud documentation doesn’t seem to have anything about using my favourite webserver: Caddy, so I decided to write my own – hope it helps someone someday.

Step 1 – Get a server

I purchased a tiny cloud server on Hetzner for only € 4.15 / month :D. I’ve always wanted to try Hetzner as they seem super cheap, cheaper than my other servers hosted on Linode and Vultr.
I chose Ubuntu 20.04 as the OS, pretty standard, stable, runs all my servers and laptop.

Step 2 – Initial setup

Using a terminal, ssh login to the server as root, run some standard stuff:

apt-get update && apt-get upgrade

hostnamectl set-hostname YOUR_HOSTNAME_HERE

Step 3 – Install Caddy

apt install -y debian-keyring debian-archive-keyring

apt-transport-https

curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | apt-key add -

curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | tee -a /etc/apt/sources.list.d/caddy-stable.list

apt update

apt install caddy

Now you’ll have caddy installed and running, next create the directory you want caddy to host NextCloud from and assign the ‘caddy’ user ownership

mkdir /var/www

chown caddy:caddy /var/www

Step 4 – Install MariaDB

Follow the instructions on the MariaDB page to download and install the latest version of MariaDB: https://mariadb.org/download/?t=repo-config&d=20.04+%22focal%22&v=10.6&r_m=icm

after installing be sure to run mysql_secure_installation and follow the prompts to secure it.

Next we will create the database and user needed by NextCloud, so login to mysql cli:

mysql -u root -p

Run the following in the mysql cli to create a user:

CREATE USER 'nextcloud'@'localhost' IDENTIFIED BY 'MAKE_A_PASSWORD';

Create a database:

CREATE DATABASE nextcloud CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

Give the nextcloud user access to the database:

GRANT ALL PRIVILEGES ON nextcloud.* TO 'nextcloud'@'localhost';

Flus privileges and quit:

FLUSH PRIVILEGES;

quit;

Step 5 – Install PHP

At the time of writing NextCloud recommended using php version 8.0, so this is what I used:

add-apt-repository ppa:ondrej/php

apt update

apt install php8.0-fpm php8.0-common php8.0-mysql php8.0-curl php8.0-gd php8.0-imagick php8.0-cli php8.0-mbstring php8.0-xml php8.0-xmlrpc php8.0-dev php8.0-opcache php8.0-zip php8.0-mcrypt php8.0-gmp php8.0-bcmath php8.0-intl php8.0-xml

For caddy to talk to PHP it needs permission, so edit the PHP-FPM config file at /etc/php/8.0/fpm/pool.d/www.conf

Find and replace all instances of ‘www-data’ with ‘caddy’. This ensures that there won’t be any permissions errors as the directory we will be hosting from is owned by the ‘caddy’ user. After saving the file you need to restart php-fpm, run:

systemctl restart php8.0-fpm

Step 6 – Download NextCloud

Get the latest version from https://nextcloud.com/install/#instructions-server click ‘download for server’ and choose the tar or zip archive. I chose tar. Put the file on your webserver, I just ftped it across to the root user’s home directory, then moved it to caddy’s webserver directorw /var/www

mv nextcloud-23.0.0.tar.bz2 /var/www/

extract the archive:

tar -xf nextcloud-23.0.0.tar.bz2

this will create extract and create a folder /var/www/nextcloud
In my case I was logged in as the root user, so I needed to change ownership of the files to caddy with:

chown -R caddy:caddy /var/www/nextcloud

Step 7 – Configure Caddy

Caddy config is done using either a Caddyfile or a json file. The json file is more powerful and is what I’m used to, so without explanation here is the file I created and saved in /etc/caddy/config.json
Be sure to replace “cloud.jj-projects.com” with the url of your site.
Apologies for the lack of formatting – I couldn’t get WordPress to format it properly. Perhaps it’s easier to download the file here

{
"apps": {
"http": {
"servers": {
"srv0": {
"listen": [
":443"
],
"routes": [
{
"match": [
{
"host": [
"cloud.jj-projects.com"
]
}
],
"handle": [
{
"handler": "subroute",
"routes": [
{
"handle": [
{
"handler": "vars",
"root": "/var/www/nextcloud"
},
{
"encodings": {
"gzip": {}
},
"handler": "encode",
"prefer": [
"gzip"
]
}
]
},
{
"handle": [
{
"handler": "static_response",
"headers": {
"Location": [
"{http.request.uri.path}/"
]
},
"status_code": 308
}
],
"match": [
{
"file": {
"try_files": [
"{http.request.uri.path}/index.php"
]
},
"not": [
{
"path": [
"*/"

]
}
]
}
]
},
{
"handle": [
{
"handler": "rewrite",
"uri": "{http.matchers.file.relative}"
}
],
"match": [
{
"file":
{
"split_path": [
".php"
],
"try_files": [
"{http.request.uri.path}",
"{http.request.uri.path}/index.php",
"index.php"
]
}
}
]
},
{
"handle": [
{
"handler": "reverse_proxy",
"transport": {
"protocol": "fastcgi",
"split_path": [ ".php" ]
},
"upstreams": [
{ "dial": "unix//run/php/php8.0-fpm.sock" }
]
}
],
"match": [
{ "path": [ ".php"
]
}
]
},
{
"handle": [
{
"handler": "file_server",
"hide": [
"/etc/caddy/Caddyfile"
]
}
]
}
]
}
],
"terminal": true
}
]
}
}
}
}
}

Once the file is saved we need to update systemd to point to it:

systemctl edit --full caddy.service

Find and replace all instances of ‘Caddyfile’ with ‘config.json’.
After saving, restart caddy with:

systemctl caddy restart

At this point you can try opening a web browser pointing to your url and you should see a NextCloud error page, as we haven’t finished installing it yet.

If you do see the error page that’s great – it indicates Caddy and PHP are working 🙂

Step 8 – Install NextCloud

NextCloud has a graphical installation wizard that should be available immediately from your url, but for some reason it didn’t work for me, it just showing an error page, so I tried the manual installation from the command line and it worked. Here’s how you install manually from the terminal:

Navigate to the nextcloud folder:

cd /var/www/nextcloud

The following command will install NextCloud creating an admin user named ‘admin’ with password ‘password’. Feel free to change it to something harder to guess.

sudo -u caddy php occ maintenance:install --database "mysql" --database-name "nextcloud" --database-user "nextcloud" --database-pass "PASSWORD_YOU_CREATED_IN_STEP_4" --admin-user "admin" --admin-pass "password"

Once the install script completes, that’s it, you’re done!! Go to your url and you should see the NextCloud login page, where you can use ‘admin’ and ‘password’ (or whatever you changed it to) to log in.

Next Steps

There are a few optional things I did after the installation, which I may elaborate on in future posts:

  • Firewall – enable ufw
  • ssh protection – install sshguard
  • move the /var/www directory to block storage for future expansion
  • install the NextCloud android app