Since 2010, I guess, I run Owncloud and later Nextcloud on different small “servers” in my home network. Recently, I had the impression that my instance, which I updated/upgraded many times, got a bit bloated and some things simply did not work correctly anymore.
The other day I decided that it is time to setup up a new instance from scratch. However, this time I did not want to have a complicated native installation running on nginx, php-fpm, mySQL, Redis and whatever dependency my old Nextcloud instance had. I wanted to go the dockerized way.
I know that there are a couple of projects that try to provide whole management interfaces to maintain a dockerized Nextcloud setup. They include automatic SSL (re)certification via Let’s encrypt, automated backups, … you name it. From earlier tests, I still had the impression that I do not understand how these things work, plus I already have my own way of dealing with SSL and backups as I also run other stuff at home. So I decided to go for the most simple way: the Docker image provided by Nextcloud that uses an Apache, php and tinySQL stack. Yes: tinySQL.
My theory was that for my scenario (private instance used by 1 - 2 persons) you do not need a database and caching server. And - at least so far - my impression was right. The new instance is running quicker than the old one.
So how do you set up the thing?
Step 1 is to get the basic installation ready. You can use the following docker-compose.yml for that purpose:
# docker-compose.yml
version: '3'
services:
nextcloud:
container_name: nextcloud
image: nextcloud
restart: always
volumes:
- /docker/nextcloud/www/:/var/www/html/
ports:
- 8080:80
environment:
- NEXTCLOUD_ADMIN_USER=pichANiceUserName
- NEXTCLOUD_ADMIN_PASSWORD=pickAGoodPassword
- SQLITE_DATABASE=data
Note: Using the volumes
statement in the docker-compose-yml
, we expose the container’s entire web root /var/www/html/
including all Nextcloud files to the host machine to /docker/nextcloud/www/
. This causes some very important effects. a) without the volumes
statement, there would be no persistence. docker-compose restart
would destroy the old container with all your data in it and create a new container from scratch. b) you can easily edit configuration files. c) you can easily backup the instance with whatever backup script you like!
After docker-compose up -d
you should have a new instance running on your server and you should be able to access it at http://localIP:8080 using the provided user/password. If you do not want to make the instance reachable by a public URL, you are done.
Step 2 is the first part of the SSL configuration. My approach for dockerized services is typically to use nginx as a reverse proxy and let nginx take care of SSL. This can be achieved as follows:
# /etc/nginx/sites-available/nextcloud.domain.foo.conf
server {
server_name nextcloud.domain.foo;
listen 80;
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains;";
server_tokens off;
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
client_max_body_size 50M;
location / {
proxy_pass http://localhost:8080;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_read_timeout 3m;
proxy_send_timeout 3m;
access_log /var/log/nginx/nextcloud_docker.access.log;
error_log /var/log/nginx/nextcloud_docker.error.log;
}
}
Activate the configuration with ln -s /etc/nginx/sites-available/nextcloud.domain.foo.conf /etc/nginx/sites-enabled/
and restart your nginx with service nginx restart
.
The configuration does not yet include anything related to SSL. So, your Nextcloud will only be available at http://nextcloud.domain.foo. Furthermore, since certain overwrite
statements are not yet in place, the instance probably does not work completely yet… We cover this in step 4.
Step 3: Install the Let’s Encrypt client with the needed nginx extension: apt install certbot python3-certbot python3-certbot-nginx
. Then execute something like certbot --nginx -d nextcloud.domain.foo
and follow all directions printed on screen. Yes, you want to redirect automatically from http to https. After you have completed all steps, you should have a shiny certificate for your domain and nextcloud.domain.foo.conf
should be extended with all necessary SSL settings.
Step 4 finalizes the Nextcloud configuration with necessary overwrite
statements that are needed as we run the instance behind nginx. For this purpose, edit /docker/nextcloud/www/config/config.php
and add the following:
'overwritehost' => 'nextcloud.domain.foo',
'overwriteprotocol' => 'https',
Restart nginx (service nginx restart
). Your instance should be available at https://nextcloud.domain.foo.
The last steps are to create a couple of cronjobs that take care for “maintenance”. Create a cronjob that runs once a month to take care for the re-certification of the domain (LE certificates are only valid for three months). For this purpose, I use a small script that performs the re-certification of my Nextcloud subdomain plus a couple of other things not shown here:
# renew.sh
#!/bin/bash
#...
/usr/bin/certbot certonly --nginx --force-renew -d nextcloud.domain.foo
#...
Lastly, crontab -e
and add something like 15 3 17 * * /path/to/renew.sh
. Done.
Similarly, create a small script and cronjob that snapshots /docker/nextcloud/www/
a couple of times a day.