Nextcloud has es­tab­lished itself as a popular open-source solution. In addition to its clients for desktop and mobile operating systems, the software also features a server component. We show you how to install a Nextcloud server in a Docker en­vir­on­ment.

Free Cloud Server Trial
En­ter­prise-grade virtual private servers
  • KVM based dev servers for de­velopers
  • Scalable to en­ter­prise cloud level
  • Pay-as-you-go, per-minute billing

In­stalling Nextcloud with Docker

Nextcloud is an open-source cloud solution that came about as a fork from the ownCloud project. Its range of features is com­par­able with pro­pri­et­ary cloud solutions like Microsoft 365 and Google Workspace. Nextcloud syn­chron­ises data like calendars and contacts across users and devices. Aside from the customary file syncing, the software provides features for team col­lab­or­a­tion and com­mu­nic­a­tion.

As is the case with other com­par­able cloud solutions, Nextcloud includes a server component as well as clients for desktop and mobile operating systems. The Nextcloud server manages data and com­mu­nic­ates with the clients; you can access the server from a client-in­de­pend­ent web interface.

We’ll show you how to install a Nextcloud server on Ubuntu using Docker Compose and cloud in­fra­struc­ture. It’s also possible to install the software on your own hardware and set up Nextcloud on, for example, a Raspberry Pi.

Tip

Nextcloud and ownCloud have a lot in common. In our guide ‘ownCloud vs. Nextcloud’ we lay out the key dif­fer­ences for you.

Ar­chi­tec­ture of Nextcloud on Docker

Let’s take a look the com­pon­ents of Nextcloud servers with Docker. Aside from the Nextcloud software itself, there are three con­tain­er­ised services that come into play. To provision the container network, we’ll use the Docker tool Compose. The in­di­vidu­al services are:

  1. Nginx Reverse Proxy: Used to realise encrypted HTTPS con­nec­tions when accessing Nextcloud
  2. Let’s Encrypt: Used to set up SSL cer­ti­fic­ates auto­mat­ic­ally
  3. MariaDB: Used to store data created by the server during Nextcloud use
  4. Nextcloud server: Provides Nextcloud func­tion­al­ity; com­mu­nic­ates with Nextcloud clients and hosts the web interface

Preparing for your Nextcloud server in­stall­a­tion

The first step is in­stalling Docker Engine and Docker Compose. Docker Engine will provide the core container func­tion­al­ity, while Docker Compose makes it possible to manage related container networks. If you already have Docker Engine and Docker Compose installed, you can skip this section.

In­stalling Docker Engine on Ubuntu

Now we’ll show you how to install Docker Engine on Ubuntu, based on the official in­stall­a­tion manual. You can find in­struc­tions for in­stalling the software on other Linux dis­tri­bu­tions on the Docker website.

  1. Delete any other Docker in­stall­a­tions:
sudo apt-get remove docker docker-engine docker.io containerd runc
  1. Update the installer:
sudo apt-get update
  1. Prepare the re­pos­it­or­ies:
sudo apt-get install \
ca-certificates \
curl \
gnupg \
lsb-release
  1. Add Docker’s official GPG key:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
  1. Set up a stable Docker re­pos­it­ory:
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
  1. Update the re­pos­it­or­ies:
sudo apt-get update
  1. Install Docker Engine, along with de­pend­en­cies:
sudo apt-get install docker-ce docker-ce-cli containerd.io
  1. Lastly, we’ll execute the test container ‘Hello World’. If Docker Engine was properly installed, the container will be executed and output the message.
sudo docker run hello-world

Install Docker Compose on Ubuntu

Let’s now turn to Docker Compose. In­stalling this software is easier than in­stalling Docker Engine - there are just a few steps.

  1. Activate Ubuntu’s Universe re­pos­it­ory:
sudo add-apt-repository universe
  1. Update the package manager:
sudo apt update
  1. Install Docker Compose:
sudo apt install docker-compose
  1. Check whether Docker Compose was suc­cess­fully installed:
docker-compose --version

If the version number is shown, then Docker Compose was suc­cess­fully installed.

In­stalling the Nextcloud server

As soon as you’ve installed Docker Engine and Docker Compose, you can get started with in­stalling Nextcloud itself. We’ll configure in­di­vidu­al Docker con­tain­ers for the different services. Two con­fig­ur­a­tion files will be of use in con­fig­ur­ing the con­tain­ers and the Docker volumes and Docker networks:

File Ex­plan­a­tion
docker-compose.yaml Docker Compose in­struc­tions in YAML format for building multi-container ap­plic­a­tions
.env Text file with en­vir­on­ment variables; one variable defin­i­tion per line

Docker Compose will be used to manage multi-container ap­plic­a­tions. That’s where the Docker Compose in­struc­tions come in — they define how the ap­plic­a­tion should be struc­tured and how the various com­pon­ents interact with each other. They describe the in­di­vidu­al services, Docker elements, and settings and are written in YAML (‘Yet Another Markup Language’). We’ll build the file used for this (docker-compose.yaml) step by step.

Aside from docker-compose.yaml, we’ll need one more file, which contains the en­vir­on­ment variables that will be in­teg­rated into the Docker Compose in­struc­tions. Standard practice is to place the en­vir­on­ment variables in a .env file in the project folder, along with the values. The .env file isn’t included in the version control system, pro­tect­ing sensitive data from ac­ci­dent­al exposure.

The use of an .env file makes it un­ne­ces­sary to define different settings for the different app en­vir­on­ments. To use different settings for a live site and a staging site, for example, you need only change the .env file.

Creating the necessary struc­tures for a Nextcloud server

To begin our Nextcloud server in­stall­a­tion, we’ll need a handful of struc­tures. We’ll create them in the following steps:

  1. Create a project folder. Set up the folder nextcloud-docker in your home directory:
mkdir ~/nextcloud-docker/
  1. Create the files. We’ll create the files docker-compose.yaml and .env in the project folder:
touch ~/nextcloud-docker/docker-compose.yaml
touch ~/nextcloud-docker/.env
  1. Create Docker network. We’ll use the docker command to set up a new network. The four con­tain­ers will then com­mu­nic­ate inside the network.
docker network create nextcloud_network

Once we’ve set up these struc­tures, we can continue with the in­stall­a­tion of our Nextcloud server.

Con­fig­ur­ing a reverse proxy for the Nextcloud server

To start our in­stall­a­tion of the Nextcloud server, we’ll configure the reverse proxy, for which we’ll use Nginx. Since we’re putting together our ap­plic­a­tion from con­tain­ers, most of the in­stall­a­tion will take place in the file docker-compose.yaml. We’ll show you in detail how to edit this file. You’ll also follow the same patterns in sub­sequent in­stall­a­tion steps:

  1. Open the file docker-compose.yaml for editing. The following command will open the empty file in the editor ‘Nano’.
nano ~/nextcloud-docker/docker-compose.yaml
  1. Insert the following code block into Nano and save the file. To close the file, use the shortcut [Ctrl] + [X]. You’ll be asked whether you want to save the file. Answer with ‘y’ for ‘yes’. Confirm the use of the existing file name with the [Enter] key. Al­tern­at­ively, you can leave the editor open and use the shortcut [Ctrl] + [O] (‘Write out’) to write the editor text into the file.
version: '3'
services:
    proxy:
        image: jwilder/nginx-proxy:alpine
        labels:
            - "com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy=true"
        container_name: nextcloud-proxy
        networks:
            - nextcloud_network
        ports:
            - 80:80
            - 443:443
        volumes:
            - ./proxy/conf.d:/etc/nginx/conf.d:rw
            - ./proxy/vhost.d:/etc/nginx/vhost.d:rw
            - ./proxy/html:/usr/share/nginx/html:rw
            - ./proxy/certs:/etc/nginx/certs:ro
            - /etc/localtime:/etc/localtime:ro
            - /var/run/docker.sock:/tmp/docker.sock:ro
        restart: unless-stopped

What do the in­di­vidu­al entries mean? First, we instruct Docker Compose to create a new service with the name proxy and use a Nginx image based on Alpine Linux. Then we specify that the reverse proxy should com­mu­nic­ate with the other services using the Docker network nextcloud_network.

We map the standard HTTP and HTTPS ports 80 and 443 from the host system onto the container. This routes incoming con­nec­tions through the proxy. In the last step of the con­fig­ur­a­tion, we create various Docker volumes and specify that the reverse proxy should be auto­mat­ic­ally restarted unless it’s ex­pli­citly stopped.

Con­fig­ur­ing the Let’s Encrypt service for the Nextcloud server

The next step is in­stalling Let’s Encrypt. This enables encrypted com­mu­nic­a­tion with the Nextcloud server via HTTPS.

  1. Open the file docker-compose.yaml for editing:
nano ~/nextcloud-docker/docker-compose.yaml
  1. Add another service block. Proceed as in the previous section and pay special attention to the in­dent­a­tion. The beginning of the block that starts with let­sen­crypt: has to be at the same level as proxy:. This is also true of the service blocks that come later.
letsencrypt:
    image: jrcs/letsencrypt-nginx-proxy-companion
    container_name: nextcloud-letsencrypt
    depends_on:
        - proxy
    networks:
        - nextcloud_network
    volumes:
        - ./proxy/certs:/etc/nginx/certs:rw
        - ./proxy/vhost.d:/etc/nginx/vhost.d:rw
        - ./proxy/html:/usr/share/nginx/html:rw
        - /etc/localtime:/etc/localtime:ro
        - /var/run/docker.sock:/var/run/docker.sock:ro
    restart: unless-stopped

Once again, we define a new service with the name let­sen­crypt, which is based on the container let­sen­crypt-nginx-proxy-companion. We specify that the service is dependent on the reverse proxy service and com­mu­nic­ates in the same Docker network. We also define the Docker volumes required for data exchange. Just as above, we specify that the service should be auto­mat­ic­ally restarted unless it was ex­pli­citly stopped.

Tip

You’re looking for pro­fes­sion­al-level en­cryp­tion for your website? Purchase your own af­ford­able SSL cer­ti­fic­ate with IONOS!

Con­fig­ur­ing the MariaDB service

We’ve now completed half of the in­stall­a­tion! Let’s continue with the MariaDB database, which is required for managing the data created when using Nextcloud. The actual storage in Docker volumes will happen outside the container.

  1. Open the file docker-compose.yaml for editing:
nano ~/nextcloud-docker/docker-compose.yaml
  1. Add another service block:
db:
    image: mariadb
    container_name: nextcloud-mariadb
    networks:
        - nextcloud_network
    volumes:
        - db:/var/lib/mysql
        - /etc/localtime:/etc/localtime:ro
    environment:
        - MYSQL_ROOT_PASSWORD
        - MYSQL_PASSWORD
        - MYSQL_DATABASE
        - MYSQL_USER
    restart: unless-stopped

Most of the settings should be familiar at this point. First, we define a service db, which is based on the Docker image mariadb. We then define the same network as before, nextcloud_network, and a Docker volume for storing data.

What’s new in this con­fig­ur­a­tion block is the use of en­vir­on­ment variables. In the en­vir­on­ment section, we specify the names of the en­vir­on­ment variables for MariaDB. The values will be read from the .env file when Docker Compose is executed later.

Con­fig­ur­ing the Nextcloud server container

The time has come: Now we’ll install the Nextcloud server software.

  1. Open the file docker-compose.yaml for editing:
nano ~/nextcloud-docker/docker-compose.yaml
  1. Add another service block:
app:
    image: nextcloud:latest
    container_name: nextcloud-app
    networks:
        - nextcloud_network
    depends_on:
        - letsencrypt
        - proxy
        - db
    volumes:
        - nextcloud:/var/www/html
        - ./app/config:/var/www/html/config
        - ./app/custom_apps:/var/www/html/custom_apps
        - ./app/data:/var/www/html/data
        - ./app/themes:/var/www/html/themes
        - /etc/localtime:/etc/localtime:ro
    environment:
        - VIRTUAL_HOST
        - LETSENCRYPT_HOST
        - LETSENCRYPT_EMAIL
    restart: unless-stopped

Here we create a service with the name app, which is based on the Docker image nextcloud and com­mu­nic­ates with the network nextcloud_network. To ensure that the Nextcloud container is started last, we specify the other services as de­pend­en­cies. We also define the required Docker volumes and en­vir­on­ment variables.

Finishing up the Nextcloud server con­fig­ur­a­tion

To conclude our con­fig­ur­a­tion of the Nextcloud server, we need to make a few more entries in the docker-compose.yaml file. We’ll also create the .env file and fill it with the cor­res­pond­ing values.

  1. Open the file docker-compose.yaml for editing:
nano ~/nextcloud-docker/docker-compose.yaml
  1. Insert the following blocks. Note that they aren’t services blocks; their in­dent­a­tion should be at the same level as services:.
volumes:
    nextcloud:
    db:
networks:
    nextcloud_network:
  1. Open the empty .env file for editing:
nano ~/nextcloud-docker/.env
  1. Write the en­vir­on­ment variables including their values into the .env file. We’ll copy the following code into the editor window and replace the with the desired values before saving.
# MariaDB
MYSQL_ROOT_PASSWORD=toor
MYSQL_PASSWORD=mysql
MYSQL_DATABASE=nextcloud
MYSQL_USER=nextcloud
# Nextcloud
VIRTUAL_HOST=<your.domain></your.domain>
LETSENCRYPT_HOST=<your.domain></your.domain>
LETSENCRYPT_EMAIL=<your@email></your@email>
  1. After saving, we’ll display the contents of the .env file to check whether the values were entered correctly.
cat ~/nextcloud-docker/.env

Complete Nextcloud server con­fig­ur­a­tion

Before we hand over the con­fig­ur­a­tion to Docker Compose and create and start the con­tain­ers, we’ll make sure that everything that’s needed is in place.

  1. Output the existing con­fig­ur­a­tion:
cat ~/nextcloud-docker/docker-compose.yaml
  1. Compare against our template. The output con­fig­ur­a­tion should match up with the following code:
version: '3'
services:
    proxy:
        image: jwilder/nginx-proxy:alpine
        labels:
            - "com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy=true"
        container_name: nextcloud-proxy
        networks:
            - nextcloud_network
        ports:
            - 80:80
            - 443:443
        volumes:
            - ./proxy/conf.d:/etc/nginx/conf.d:rw
            - ./proxy/vhost.d:/etc/nginx/vhost.d:rw
            - ./proxy/html:/usr/share/nginx/html:rw
            - ./proxy/certs:/etc/nginx/certs:ro
            - /etc/localtime:/etc/localtime:ro
            - /var/run/docker.sock:/tmp/docker.sock:ro
        restart: unless-stopped
    letsencrypt:
        image: jrcs/letsencrypt-nginx-proxy-companion
        container_name: nextcloud-letsencrypt
        depends_on:
            - proxy
        networks:
            - nextcloud_network
        volumes:
            - ./proxy/certs:/etc/nginx/certs:rw
            - ./proxy/vhost.d:/etc/nginx/vhost.d:rw
            - ./proxy/html:/usr/share/nginx/html:rw
            - /etc/localtime:/etc/localtime:ro
            - /var/run/docker.sock:/var/run/docker.sock:ro
        restart: unless-stopped
    db:
        image: mariadb
        container_name: nextcloud-mariadb
        networks:
            - nextcloud_network
        volumes:
            - db:/var/lib/mysql
            - /etc/localtime:/etc/localtime:ro
        environment:
            - MYSQL_ROOT_PASSWORD
            - MYSQL_PASSWORD
            - MYSQL_DATABASE
            - MYSQL_USER
        restart: unless-stopped
    app:
        image: nextcloud:latest
        container_name: nextcloud-app
        networks:
            - nextcloud_network
        depends_on:
            - letsencrypt
            - proxy
            - db
        volumes:
            - nextcloud:/var/www/html
            - ./app/config:/var/www/html/config
            - ./app/custom_apps:/var/www/html/custom_apps
            - ./app/data:/var/www/html/data
            - ./app/themes:/var/www/html/themes
            - /etc/localtime:/etc/localtime:ro
        environment:
            - VIRTUAL_HOST
            - LETSENCRYPT_HOST
            - LETSENCRYPT_EMAIL
        restart: unless-stopped
volumes:
    nextcloud:
    db:
networks:
    nextcloud_network:

If your version of the YAML file matches ours, you can continue on to the next and final step.

Complete Nextcloud server in­stall­a­tion

To create a Nextcloud server as a multi-container app from the Docker Compose in­struc­tions, we’ll execute the following command on the command line:

cd ~/nextcloud-docker/ && docker-compose up -d

Then we’ll check whether the container was started:

docker ps -a

The list of running con­tain­ers should contain the four con­tain­ers defined in the docker-compose.yaml file.

Go to Main Menu