How to Set up Nextcloud Docker with Nginx Reverse Proxy

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 | sudo apt-key add -

4. Add the docker’s repository.

sudo add-apt-repository "deb [arch=amd64] $(lsb_release -cs) stable"

5. Lastly, update the system and install docker:

sudo apt update
sudo apt-get install docker-ce docker-ce-cli

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 "$(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'

    image: mariadb
    command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW
    restart: always
      - db:/var/lib/mysql
      - db.env

    image: redis
    restart: always

    build: ./app
    restart: always
      - 5234:80
      - nextcloud:/var/www/html
      - MYSQL_HOST=db
      - db.env
      - db
      - redis

    build: ./app
    restart: always
      - nextcloud:/var/www/html
    entrypoint: /
      - db
      - redis


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.


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.

$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;

    root /var/www/;

    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:

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.

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.