Nextcloud is a Dropbox-like open source software that you can self host it on your server and use it to store, backup and synchronize your files and data across multiple devices. If you are looking to move away from Dropbox/Google Drive, and want to have complete control over your data, Nextcloud is the best choice.
The standard way of setting up Nextcloud is complicated, requires a lot of (server and software) configuration and it is prone to errors. Upgrading it is also an hassle. However, with the release of the official Nextcloud docker image, it is now very easy to install and use Nextcloud.
In this tutorial, I will show how to set up a Nextcloud Docker with Nginx reverse proxy. The server used in this tutorial is running Ubuntu 18.04.
Install Docker and docker-compose
If you have not install docker on your server, this is the first step to do so.
1. update the system:
sudo apt update
2. Install the package and dependencies for docker:
sudo apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common
3. Add the docker’s gpg key
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
4. Add the docker’s repository.
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
5. Lastly, update the system and install docker:
sudo apt update
sudo apt-get install docker-ce docker-ce-cli containerd.io
6. If you want to run docker as user (instead of root), add your username to the docker
group:
sudo groupadd docker
sudo usermod -aG docker username
7. Next, we are going to install docker-compose (the latest version is 1.24.0 as of this post).
sudo curl -L "https://github.com/docker/compose/releases/download/1.24.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
8. Restart the server.
Set up Nextcloud
We are going to make use of docker-compose to run Nextcloud docker image. To get started, first create a “nextcloud” folder, and cd
to it.
mkdir nextcloud
cd nextcloud
1. Create a docker-compose file:
nano docker-compose.yml
2. Paste the following code to the file:
version: '3'
services:
db:
image: mariadb
command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW
restart: always
volumes:
- db:/var/lib/mysql
env_file:
- db.env
redis:
image: redis
restart: always
app:
build: ./app
restart: always
ports:
- 5234: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:
We will map the server port 5234 to the docker image port 80. Save (Ctrl + O) and exit (Ctrl + X) the file.
3. The docker-compose file will get the database credential from the “db.env” file, so we need to create the file and add our database details.
nano db.env
Add your database details in.
MYSQL_ROOT_PASSWORD=mysupersecurerootpassword
MYSQL_PASSWORD=mysupersecureuserpassword
MYSQL_DATABASE=nextcloud
MYSQL_USER=nextcloud
You can change the root and user password. Save (Ctrl + O) and exit (Ctrl + X) the file.
4. Next, create the app directory and add the actual Dockerfile.
mkdir app
cd app
nano Dockerfile
Add the following lines to the Dockerfile:
FROM nextcloud:apache
COPY redis.config.php /usr/src/nextcloud/config/redis.config.php
Save (Ctrl + O) and exit (Ctrl + X) the file.
5. In the “app” folder, create the “redis.config.php” file.
nano redis.config.php
Paste the following configuration to the php file.
<?php
$CONFIG = array (
'memcache.local' => '\\OC\\Memcache\\Redis',
'memcache.locking' => '\\OC\\Memcache\\Redis',
'filelocking.enabled' => 'true',
'redis' => array(
'host' => 'redis',
'port' => 6379,
),
);
6. Lastly, run the docker image:
cd /home/username/nextcloud
docker-compose up -d
Set up Let’s Encrypt SSL Certificate
We will use certbot to obtain and manage Let’s Encrypt certificate. To get started, first install certbot.
sudo apt-get update
sudo apt-get install software-properties-common
sudo add-apt-repository universe
sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update
sudo apt-get install certbot python-certbot-nginx
Next, create a Nginx conf file for the nextcloud domain:
sudo nano /etc/nginx/sites-available/nextcloud
Add the following lines:
server {
listen 80;
listen [::]:80 ipv6only=on;
server_name mynextcloudurl.com;
root /var/www/mynextcloudurl.com;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
Save and exit the file. Make it active:
sudo ln -s /etc/nginx/sites-available/nextcloud /etc/nginx/sites-enabled/
sudo systemctl reload nginx
Lastly, obtain a certificate with the command:
sudo certbot --rsa-key-size 4096 --nginx
When prompted, select your nextcloud url and fill up the information. Allow it to replace the conf file.
Setting up Nginx Reverse Proxy
In the Nginx conf file, add (or replace the location /
block) the following lines:
location / {
proxy_pass http://localhost:5234/; # set this to the nextcloud port set in doccker-compose file
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;
client_max_body_size 0;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
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;
}
Save and exit the file. Restart Nginx:
sudo systemctl reload nginx
On your browser, load your nextcloud url and it should prompt you to set up your administrator account.
Securing the server (optional)
We can use fail2ban
to prevent unauthorized access to the server. For the following configuration, we will block IPs that made three unsuccessful login attempts to our Nextcloud installation.
1. Start by creating the fail2ban conf file:
sudo nano /etc/fail2ban/filter.d/nextcloud.conf
Add the following codes to filter out the 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 =
2. Next, create the actual jail configuration for nextcloud.
sudo nano /etc/fail2ban/jail.d/nextcloud.conf
Add the following lines to the file. You can 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
3. Restart the fail2ban service.
sudo systemctl restart fail2ban
You can check the fail2ban status with the following commands.
sudo fail2ban-client status
sudo fail2ban-client status nextcloud
Updating Nextcloud
To update Nextcloud to the newer version, you just need to pull the new images via docker-compose and rebuild the containers.
docker-compose stop
docker-compose rm
docker-compose pull
docker-compose build --pull
docker-compose up -d
That’s it.