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
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-COMMITTEDis required by Nextcloud on MariaDB. Without it you get database errors under load.REDIS_HOSTturns on file locking and caching. Without Redis, Nextcloud warns about memory caching and gets slow.NEXTCLOUD_TRUSTED_DOMAINSmust be your real domain, or Nextcloud refuses to load with an "untrusted domain" error.OVERWRITEPROTOCOL: httpstells Nextcloud it is behind a proxy that terminates TLS. Without it, links and downloads break in odd ways.
$ 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:
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.phpevery 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.
$ 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
| Task | Command |
|---|---|
| Start | docker compose up -d |
| Admin tool | docker compose exec -u www-data app php occ |
| Fix DB indices | occ db:add-missing-indices |
| Maintenance mode | occ maintenance:mode --on |
| Update | docker compose pull && docker compose up -d |
| Upload limit | client_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.