Wiki/Guides/Docker/04Nextcloud.md

336 lines
8.9 KiB
Markdown
Raw Normal View History

2025-04-10 04:10:54 +02:00
---
title: 04 Nextcloud
description:
published: true
date: 2023-05-03T02:50:12.377Z
tags:
editor: markdown
dateCreated: 2023-05-03T01:58:56.581Z
---
# Nextcloud
Nextcloud is a great application, It is great for storing and syncing data, storing your contacts, bookmarks, passwords, calendar, tasks. It also has a great RSS reader, full office suite and many many more. I truly can't live without it. And neither should you which is why I picked it as the example for this guide
First we need to create a network for the service.
sudo docker network create --subnet=172.20.30.0/24 nextcloud
Next we are going to create some folders
mkdir -p ~/docker/nextcloud
Now we will create a docker compose file
vim ~/docker/nextcloud/docker-compose.yml
Add in the following text
```
version: '3'
services:
nextcloud:
image: nextcloud
container_name: nextcloud
restart: always
volumes:
- /etc/localtime:/etc/localtime:ro
- /data/nextcloud:/var/www/html
networks:
nextcloud:
ipv4_address: 172.20.30.10
networks:
nextcloud:
external: true
name: nextcloud
ipam:
config:
- subnet: 172.20.30.0/24
```
Now we need to add a server block for nextcloud to the Nginx config file so create a file that will be included by the main nginx config file
sudo vim /data/nginx/config/services/nextcloud.active
add in the following text
```
server {
server_name example.com;
listen 443 ssl;
# Settings
autoindex off;
client_max_body_size 5000M;
# Locations
location / {
proxy_pass http://nextcloud:80;
proxy_http_version 1.1;
proxy_cache_bypass $http_upgrade;
proxy_ssl_server_name on;
proxy_set_header Upgrade $http_upgrade;
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;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_connect_timeout 600m;
proxy_send_timeout 600m;
proxy_read_timeout 600m;
}
location /.well-known/carddav {
return 301 $scheme://$host/remote.php/dav;
}
location /.well-known/caldav {
return 301 $scheme://$host/remote.php/dav;
}
location ~ /\.(?!well-known) {
deny all;
}
location = /favicon.ico {
log_not_found off;
}
location = /robots.txt {
log_not_found off;
}
# GZip
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css text/xml application/json application/javascript application/rss+xml application/atom+xml image/svg+xml;
# Headers
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN";
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header Content-Security-Policy "default-src 'self' http: https: ws: wss: data: blob: 'unsafe-inline'; frame-ancestors 'self';" always;
add_header Permissions-Policy "interest-cohort=()" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
# SSL
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
}
# Redirect
server {
listen 80;
server_name example.com;
return 301 https://example.com$request_uri;
}
```
Be sure to replace `example.com` 6 times
Now we need to add nextcloud to the mariadb and nginx networks, because it needs a database and a proxy.
open the nginx compose file
vim ~/docker/nginx/docker-compose.yml
add the nextcloud network so it looks like this
```
version: '3'
services:
nginx:
image: nginx:latest
container_name: nginx
restart: always
volumes:
- /data/nginx/config:/etc/nginx
- /data/nginx/log/error.log:/var/log/error.log
- /data/nginx/log/access.log:/var/log/access.log
- /etc/letsencrypt/:/etc/letsencrypt/
- /etc/localtime:/etc/localtime:ro
ports:
- 80:80
- 443:443
- 8448:8448
networks:
nextcloud:
ipv4_address: 172.20.30.20
networks:
nextcloud:
external: true
name: nextcloud
```
open the mariadb compose file
vim ~/docker/mariadb/docker-compose.yml
add the nextcloud network so it looks like this
```
version: '3'
services:
mariadb:
image: mariadb:latest
container_name: mariadb
restart: always
command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW --skip-innodb-read-only-compressed
volumes:
- /data/mariadb/data:/var/lib/mysql
- /data/mariadb/config:/etc/mysql/conf.d
- /data/mariadb/logs:/var/log/mysql
- /etc/localtime:/etc/localtime:ro
environment:
- MYSQL_ROOT_PASSWORD=YOURMYSQLROOTPASSWORD
networks:
nextcloud:
ipv4_address: 172.20.30.30
networks:
nextcloud:
external: true
name: nextcloud
```
Now we are going to start the nextcloud container and restart the nginx and mariadb containers.
sudo docker-compose -f ~/docker/nextcloud/docker-compose.yml up -d
sudo docker-compose -f ~/docker/nginx/docker-compose.yml down && sudo docker-compose -f ~/docker/nginx/docker-compose.yml up -d
sudo docker-compose -f ~/docker/mariadb/docker-compose.yml down && sudo docker-compose -f ~/docker/mariadb/docker-compose.yml up -d
Nextcloud should be accessable from your browser using the domain you chose, But first we need to create a database, user and set the permissions.
You can get into the database with the following command (only if mariadb is running)
sudo docker exec -it mariadb mysql -p
Enter the Mysql root password you provided during the creation of the mariadb container and you should be in.
Now run the following commands to create a database, create a user with privileges, and make them take effect.
create database nextcloud;
create user nextcloud@'172.20.30.10' identified by 'NEXTCLOUDDATABASEPASSWORD';
grant all privileges on nextcloud.* to nextcloud@'172.20.30.10';
flush privileges;
You can exit the mysql prompt with `exit;` and then pressing enter.
Now we just need to go to example.com and follow the steps
The Database is nextcloud, the user is nextcloud, The IP is 172.30.0.30:3306 and the password is what you gave it.
We also need to force HTTPS, else it will give problems since we are running from behind a proxy
sudo vim /data/nextcloud/config/config.php
Add in the following line preferrrably under the overwrite.cli.url line.
```
'overwriteprotocol' => 'https',
```
Nextcloud requires some tasks to be executed every 5 minutes, for that we are going to use systemd timers, like we did for certbot
Create a little script
vim ~/scripts/nextcloudcron.sh
add in the following content
```
#!/bin/bash
docker exec -u 33 -t nextcloud php -f /var/www/html/cron.php
exit
```
Create a systemd service
sudo vim /etc/systemd/system/nextcloudcron.service
Add in the following content
```
[Unit]
Description=Runs Nextcloud Cron
Wants=nextcloudcron.timer
[Service]
Type=oneshot
ExecStart=/bin/bash /home/USERNAME/scripts/nextcloudcron.sh
[Install]
WantedBy=multi-user.target
```
Create a timer file
sudo vim /etc/systemd/system/nextcloudcron.timer
and add in the following content
```
[Unit]
Description=Runs Nextcloud Cron
Requires=nextcloudcron.service
[Timer]
Unit=cron5.service
OnBootSec=5min
OnUnitActiveSec=5min
[Install]
WantedBy=timers.target
```
Finally start the timer
sudo systemctl enable --now nextcloudcron.timer
Nextcloud should be all good and ready to go, You can check the persistance by completely deleting all containers and all volumes, When you start it again all your stuff should still be there :)
Nextcloud has its own Brute force protection, but we still are going to add a fail2ban filter because we want attackers to be banned from all services and not just nextcloud.
So lets create a new nextcloud filter
sudo vim /etc/fail2ban/filters.local
add in the following content
```
[Definition]
failregex=^{"reqId":".*","remoteAddr":".*","app":"core","message":"Login failed: '.*' \(Remote IP: '<HOST>'\)","level":2,"time":".*"}$
^{"reqId":".*","level":2,"time":".*","remoteAddr":".*","user":".*","app":".*","method":".*","url":".*","message":"Login failed: '.*' \(Remote IP: '<HOST>'\)".*}$
^{"reqId":".*","level":2,"time":".*","remoteAddr":".*","user":".*","app":".*","method":".*","url":".*","message":"Login failed: .* \(Remote IP: <HOST>\).*}$
```
Now add the filter to your main fail2ban config file
sudo vim /etc/fail2ban/jail.local
Add the following to the end of the file
```
## Nextcloud
[nextcloud]
filter = nextcloud
enabled = true
logpath = /data/nextcloud/data/nextcloud.log
```
restart fail2ban to make it take effect
sudo systemctl restart fail2ban