Independent hosting operator since 2014 · New York · Dallas · Amsterdam Status Looking Glass Contact
D4 NetworksD4 Networks
Client area Deploy a server
Home / Resources / Self-host Nextcloud on a VPS with Docker

Tutorials

Self-host Nextcloud on a VPS with Docker

Jun 22, 2026 · 6 min read

Nextcloud gives you file sync, calendar, contacts, and shared folders on your own server. This guide uses Docker Compose with MariaDB and Redis, which is the setup that performs well on a normal VPS.

1. Pick your image first

There are two official ways to run Nextcloud, and mixing guides for them is the main cause of confusion:

  • All-in-One (AIO) is maintained by Nextcloud GmbH. It manages its own containers and wants control of ports 80 and 443. Good on a server that runs nothing else.
  • The community image (nextcloud:apache) is a plain container that sits behind your own reverse proxy. Nextcloud GmbH does not support it, but the community maintains it and it is the easier fit if you already run Nginx.

This guide uses the community image, because most people adding Nextcloud to a VPS already have a web server on it.

2. Requirements

Nextcloud is heavier than most self-hosted apps. Plan for 2 GB of RAM minimum and 4 GB if more than a few people use it. Disk depends entirely on what you store.

You need Docker installed and a domain pointing at your server.

3. Write the Compose file

/opt/nextcloud/compose.yaml
services:
  db:
    image: mariadb:lts
    restart: always
    command: --transaction-isolation=READ-COMMITTED
    volumes:
      - db:/var/lib/mysql
    environment:
      MARIADB_ROOT_PASSWORD: CHANGE_ME_ROOT
      MYSQL_PASSWORD: CHANGE_ME_DB
      MYSQL_DATABASE: nextcloud
      MYSQL_USER: nextcloud

  redis:
    image: redis:alpine
    restart: always

  app:
    image: nextcloud:apache
    restart: always
    ports:
      - "127.0.0.1:8080:80"
    depends_on:
      - db
      - redis
    volumes:
      - nextcloud:/var/www/html
    environment:
      MYSQL_PASSWORD: CHANGE_ME_DB
      MYSQL_DATABASE: nextcloud
      MYSQL_USER: nextcloud
      MYSQL_HOST: db
      REDIS_HOST: redis
      NEXTCLOUD_TRUSTED_DOMAINS: cloud.example.com
      OVERWRITEPROTOCOL: https

volumes:
  nextcloud:
  db:

Four lines that save you a support search later:

  • --transaction-isolation=READ-COMMITTED is required by Nextcloud on MariaDB. Without it you get database errors under load.
  • REDIS_HOST turns on file locking and caching. Without Redis, Nextcloud warns about memory caching and gets slow.
  • NEXTCLOUD_TRUSTED_DOMAINS must be your real domain, or Nextcloud refuses to load with an "untrusted domain" error.
  • OVERWRITEPROTOCOL: https tells Nextcloud it is behind a proxy that terminates TLS. Without it, links and downloads break in odd ways.
ssh session
$ cd /opt/nextcloud
$ docker compose up -d
$ docker compose logs -f app

4. Put Nginx in front

Proxy cloud.example.com to http://127.0.0.1:8080 and get a certificate, following our Nginx and Let's Encrypt guide. Add one extra line inside the location block, because Nextcloud uploads are large:

/etc/nginx/conf.d/cloud.example.com.conf
    client_max_body_size 10G;

Without it, uploads over 1 MB fail with a 413 error.

5. Finish the install in the browser

Open your domain. The setup screen asks for an admin username and password. The database fields are already filled from the Compose file, so you only create the admin account.

The admin account is the whole system

Anyone with it can read every user's files. Use a long unique password, and turn on two-factor authentication in Settings, Security as soon as you are logged in.

6. Fix the warnings

Go to Settings, Administration, Overview. Nextcloud lists configuration warnings there and most are one line each. Common ones:

  • Missing indices: run docker compose exec -u www-data app php occ db:add-missing-indices
  • Missing cron: switch background jobs from AJAX to Cron in Settings, Basic settings, then add a cron entry on the host that runs docker compose exec -u www-data app php -f /var/www/html/cron.php every five minutes.

The occ command is the Nextcloud admin tool. Everything you cannot do in the web interface, you do with it.

7. Back it up

Three things must be backed up together, or the restore will not work: the database, the nextcloud volume, and your Compose file.

ssh session
$ docker compose exec -u www-data app php occ maintenance:mode --on
$ docker compose exec db mariadb-dump -u nextcloud -p nextcloud > /root/nextcloud-db.sql
$ docker run --rm -v nextcloud_nextcloud:/data -v /root:/backup alpine tar czf /backup/nextcloud-files.tar.gz -C /data .
$ docker compose exec -u www-data app php occ maintenance:mode --off

Maintenance mode stops writes while you copy, so the database and the files match. Then copy both files off the server.

Quick reference

TaskCommand
Startdocker compose up -d
Admin tooldocker compose exec -u www-data app php occ
Fix DB indicesocc db:add-missing-indices
Maintenance modeocc maintenance:mode --on
Updatedocker compose pull && docker compose up -d
Upload limitclient_max_body_size in Nginx

Where to go next

Clear the warnings in Administration, Overview before you invite anyone. Then install the mobile and desktop clients from nextcloud.com and point them at your domain.

nextcloud docker storage files self-hosting

Related articles