In this post I would like to briefly explain how Nextcloud can be set up via Docker and behind an nginx reverse proxy. I assume a server with nginx set up, equivalent to the setup from my server and nginx setup notes. The sources for the Docker images and docker-compose examples are available in the corresponding GitHub repository of Nextcloud Docker. In this setup we will use the version with Mariadb/Cron/Redis/Apache. I create the example files like follows:
mkdir /home/dennis/nextcloud
cd /home/dennis/nextcloud
vim db.env
Add the MYSQL access information, make sure to use a appropriate MYSQL_PASSWORD.
MYSQL_PASSWORD=supersecurepassword
MYSQL_DATABASE=nextcloud
MYSQL_USER=nextcloud
Next we’ll create the docker-compose configuration file.
vim docker-compose.yml
Add the following content, make sure to replace MYSQL_ROOT_PASSWORD with a appropriate value. Also note, that we use port 5678 instead the default port 80. This is because we’ll use nginx as our reverse proxy later.
version: '3'
services:
db:
image: mariadb
command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW
restart: always
volumes:
- db:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=supersecuremysqlrootpassworddifferentthanmysqlpassword
env_file:
- db.env
redis:
image: redis
restart: always
app:
build: ./app
restart: always
ports:
- 5678:80
volumes:
- nextcloud:/var/www/html
environment:
- MYSQL_HOST=db
env_file:
- db.env
depends_on:
- db
- redis
cron:
build: ./app
restart: always
volumes:
- nextcloud:/var/www/html
entrypoint: /cron.sh
depends_on:
- db
- redis
volumes:
db:
nextcloud:
Next, lets create the app directory and add the actual Dockerfile.
mkdir app
cd app
vim Dockerfile
The Dockerfile itself is rather simple, it uses the nextcloud:apache image and overrides the default redis config, because we’ll use redis.
FROM nextcloud:apache
COPY redis.config.php /usr/src/nextcloud/config/redis.config.php
As our last file we’ll create the redis configuration file.
vim redis.config.php
Here is the content of the redis configuration:
<?php
$CONFIG = array (
'memcache.locking' => '\OC\Memcache\Redis',
'redis' => array(
'host' => 'redis',
'port' => 6379,
),
);
After we’ve created the configuration files we can start nextcloud via docker-compose:
cd /home/dennis/nextcloud
docker-compose up -d
Obtain Let’s Encrypt certificate
To SSL encrypt the connection to our Nextcloud server, a certificate is required. We’ll use a Let’s encrypt certificate. Start by creating a nginx configuration file for our nextcloud instance. The examples use the subdomain nextcloud.dennisnotes.com, change it according to the domain you want to use.
sudo vim /etc/nginx/sites-available/nextcloud.dennisnotes.com.conf
As in our basic nginx setup we start with a simple nginx configuration which just handles standard HTTP serving for our subdomain.
server {
listen 80;
listen [::]:80 ipv6only=on;
server_name nextcloud.dennisnotes.com;
root /var/www/dennisnotes.com;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
After creating the configuration file test it and restart nginx to enable it.
sudo ln -s /etc/nginx/sites-available/nextcloud.dennisnotes.com.conf /etc/nginx/sites-enabled/nextcloud.dennisnotes.com.conf
sudo nginx -t
sudo systemctl stop nginx
sudo systemctl start nginx
sudo systemctl status nginx
Now let certbot obtain a certificate for us and apply the default nginx SSL configuration like follows:
sudo certbot --rsa-key-size 4096 --nginx
Select nextcloud.dennisnotes.com, fill in information like email etc.
nginx setup
Next we will edit the configuration file again to use nginx as a reverse proxy for our nextcloud instance.
sudo vim /etc/nginx/sites-available/nextcloud.dennisnotes.com.conf
Here is a example configuration file, which I use:
server {
server_name nextcloud.dennisnotes.com;
root /var/www/dennisnotes.com;
index index.html;
location / {
proxy_pass http://localhost:5678/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
client_max_body_size 0;
access_log /var/log/nginx/nextcloud.access.log;
error_log /var/log/nginx/nextcloud.error.log;
}
location /.well-known/carddav {
return 301 $scheme://$host/remote.php/dav;
}
location /.well-known/caldav {
return 301 $scheme://$host/remote.php/dav;
}
listen [::]:443 ssl http2; # managed by Certbot
listen 443 ssl http2; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/nextcloud.dennisnotes.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/nextcloud.dennisnotes.com/privkey.pem; # managed by Certbot
ssl_trusted_certificate /etc/letsencrypt/live/nextcloud.dennisnotes.com/chain.pem;
include /etc/nginx/snippets/ssl.conf;
}
server {
if ($host = nextcloud.dennisnotes.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
listen [::]:80;
server_name nextcloud.dennisnotes.com;
return 404; # managed by Certbot
}
Fail2Ban
In the last step we create a Fail2ban configuration for Nextcloud. This blocks IPs from which three attempts were made to log on to our Nextcloud instance with incorrect user data. Start by creating the filter definition:
vim /etc/fail2ban/filter.d/nextcloud.conf
Here is the regex which will filter for Login failed
messages in the nextcloud logfiles:
[Definition]
failregex = ^{"reqId":".*","remoteAddr":".*","app":"core","message":"Login failed: '.*' \(Remote IP: '<HOST>'\)","level":2,"time":".*"}$
^{"reqId":".*","level":2,"time":".*","remoteAddr":".*","app":"core".*","message":"Login failed: '.*' \(Remote IP: '<HOST>'\)".*}$
ignoreregex =
Now create the actual jail configuration for nextcloud.
vim /etc/fail2ban/jail.d/nextcloud.conf
Here is the content of the configuration file. Note the logpath which points to the nextcloud docker volume, in which our nextcloud docker container writes into. Change the maxretry and bantime values accordingly to your needs.
[nextcloud]
enabled = true
port = 80,443
protocol = tcp
filter = nextcloud
maxretry = 3
bantime = 10800
logpath = /var/lib/docker/volumes/nextcloud_nextcloud/_data/data/nextcloud.log
After a new configuration has been added, the fail2ban service must be restarted. After the restart, the new configuration should appear in the status query from the fail2ban client, which can then also be viewed in detail.
sudo systemctl restart fail2ban
sudo fail2ban-client status
sudo fail2ban-client status nextcloud
Configuration
To finish the configuration of nextcloud you can now visit your nextcloud instance (e.g. https://nextcloud.dennisnotes.com).
Update Nextcloud
To update Nextcloud you just need to pull the new images via docker-compose and rebuild the containers. The manual update via the admin interface is disabled by the nextcloud docker team, the wanted way to upgrade is via upgrading the docker images to ensure compatibility.
docker-compose stop
docker-compose rm
docker-compose pull
docker-compose build --pull
docker-compose up -d
Or as a one-liner:
docker-compose stop && docker-compose rm --force && docker-compose pull && docker-compose build --pull && docker-compose up -d