Introduction

In this article I explain how to get Nextcloud in Docker and how to get it up and running with a simple YML file. In doing so, we take speed into account. After all, you don’t want a slow application, but you want to be able to access your data quickly.

We are going to do this with Redis cache, mariadb, cron and a database backup image, which will run together in its own network.

Prerequisites

  • I assume that you have Docker running and you already have basic knowledge of how to use Docker.
  • You already have Traefik running as a reversed proxy.

Remarks

  • It works with Docker swarm but you can easily convert this to Docker compose.
  • I can’t explain every detail in the yml file what it does, in that case please check the official page of that image for more information.
  • This has been tested on a QNAP, but it will probably work on another NAS system like Synology or OMV.

Preparation

Make sure you have created the following folders, otherwise Docker cannot create the images properly. The images can’t put their files anywhere so in fact nothing will happen.

.(your volume)
├── nextcloud/
    └── html/
    └── apps/
    └── config/
    └── redis/
    └── db-dump/

Start with Docker compose

Create a docker-compose.yml file and copy paste the following text:

version: "3.4"
services:
  db:
    image: mariadb:latest
    environment:
      - MYSQL_ROOT_PASSWORD=password
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=user
      - MYSQL_PASSWORD=password
    volumes:
      - /yourvolume/nextcloud/db:/var/lib/mysql
    networks:
      - internal

  db-backup:
    image: mariadb:latest
    environment:
      # For database backup (keep 7 days daily backups)
      - MYSQL_PWD=password
      - MYSQL_USER=nextcloud
      - BACKUP_NUM_KEEP=7
      - BACKUP_FREQUENCY=1d
    volumes:
      - /yourvolume/nextcloud/db-dump:/dump
      - /etc/localtime:/etc/localtime:ro
    entrypoint: |
      bash -c 'bash -s <<EOF
      trap "break;exit" SIGHUP SIGINT SIGTERM
      sleep 2m
      while /bin/true; do
        mysqldump -h db --all-databases | gzip -c > /dump/dump_\`date +%d-%m-%Y"_"%H_%M_%S\`.sql.gz
        (ls -t /dump/dump*.sql.gz|head -n $$BACKUP_NUM_KEEP;ls /dump/dump*.sql.gz)|sort|uniq -u|xargs rm -- {}
        sleep $$BACKUP_FREQUENCY
      done
      EOF'
    networks:
      - internal

  app:
    image: nextcloud:latest
    environment:
      - NEXTCLOUD_ADMIN_USER=nextcloud
      - NEXTCLOUD_ADMIN_PASSWORD=nextcloud
      - "NEXTCLOUD_TRUSTED_DOMAINS=*.yourdomain.com"
      - MYSQL_HOST=db
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud
      - MYSQL_PASSWORD=password
      - APACHE_DISABLE_REWRITE_IP=1
      - "TRUSTED_PROXIES=YourReservedProxyIP"
    depends_on:
      - db
    volumes:
      - /yourvolume/nextcloud/html:/var/www/html
      - /yourvolume/nextcloud/apps:/var/www/html/custom_apps
      - /yourvolume/nextcloud/config:/var/www/html/config
      - /yourdocuments/nextcloud:/var/www/html/data
    networks:
      - internal
      - traefik_public
    deploy:
      labels:
        - "traefik.enable=true"
        - "traefik.http.routers.nextcloud.entrypoints=https"
        - "traefik.http.routers.nextcloud.rule=Host(`nextcloud.yourdomain.com`)"
        - "[email protected]"
        - "traefik.http.services.nextcloud.loadbalancer.server.port=80"

  redis:
    image: redis:alpine
    networks:
      - internal
    volumes:
      - /yourvolume/nextcloud/redis:/data

  cron:
    image: nextcloud:latest
    volumes:
      - /yourvolume/nextcloud/html:/var/www/html
    user: www-data
    networks:
      - internal
    entrypoint: |
      bash -c 'bash -s <<EOF
        trap "break;exit" SIGHUP SIGINT SIGTERM
        while [ ! -f /var/www/html/config/config.php ]; do
          sleep 1
        done
        while true; do
          php -f /var/www/html/cron.php
          sleep 15m
        done
      EOF'

networks:
  traefik_public:
    external: true
  internal:
    driver: overlay
    ipam:
      config:
        - subnet: 172.16.1.0/24

Note: the environment values that are used here are required, so you can’t just remove it. Always check whether values have not been changed or added, by going to the official image page.

What the images does in general

  • Mariadb and backup

The backup database image provides a backup of the actual database that Nextcloud will use. This is necessary so that if something happens to your installation or upgrade, you can always restore it. Make sure that the database environment variables correspond.

At the backup frequency you can indicate how long the backup databases should be kept.

At entrypoint we ensure that the database file is found and copied based on what you enter at backup frequency.

  • Nextcloud image

This is an image that takes care of the application. It is important that the MYSQL user is again the same as what you entered before.

For the initial start of this stack, the ADMIN USER and ADMIN PASSWORD doesn't matter much what you fill in here, because you can change this later in the application.

At Trusted domains, fill in your internal IP addresses (LAN) and the domain where you will run the Nextcloud application from.

At MYSQL host we have to set 'db', because if the Nextcloud stack runs in its own network and the database service is also defined as db, it will be recognized and used that way.

  • Redis and Cron

Redis cache makes sure that files and pages are loaded faster by storing them in memory. So we will definitely use it to make Nextcloud faster.

Cron image ensures that the cron function is called every x minutes to, for example, check whether new files have been placed on the system (the volume). These will then automatically be displayed in Nextcloud.

Deploy the stack

Now save the yml file and start Putty (or any other SSH tool on your desktop). To get Docker to publish the stack, run the deploy docker swarm command.

You will now see that the images are gradually being built and files end up in the appropriate volumes.

Enable Redis cache

After this process is complete, you may open the config.php file to add some lines to it. (this is required to activate Redis cache)

Find the config.php file here: /yourvolume/nextcloud/html

Add these lines to it:

  'instanceid' => 'ocgmkaaal9fr',
  'redis' => array(
     'host' => 'redis',
     'port' => 6379,
      ),
)

Enable External Storage support

Now start the NextCloud website for the first time. Login with the admin credentials mentioned above and go to Apps. Search for External Storage Support and install it. This is a plugin that we activate to use local files, outside of the NextCloud image, to access within NextCloud.

Then click Enable so that you see this screen:

external-storage

external-storage

Now we have to set it up, click on Settings and on the left side on External Storages:

external-storage

external-storage

Create a new connection by entering the following information:

  • Folder name: give your local folder a suitable name
  • External storage: select Local
  • Authentication: none
  • Configuration: This is the path we used with volumes earlier. in this case we will enter /var/www/html/data
  • Available for: here you can enter all users or a specific one.

Then click the check mark to save the changes.

You will now see on the front page of NextCloud a new folder called Local, where you can access local files.

The cron image that we also rolled out ensures that new files placed there are picked up by Nextcloud. This makes those files visible immediately.

Have fun with Nextcloud!

frontpage-nextcloud

frontpage-nextcloud