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 according 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.