Self-hosting Nextcloud properly: storage, cron, and the settings everyone gets wrong
Description and use
Self-hosted Nextcloud: proper storage, cron, and domain settings ensure stable performance and high reliability.
Problem
Users install Nextcloud quickly but experience slow performance over time due to misconfigured storage, cron, and domain settings.
Outcome
The deployment runs smoothly, background jobs execute on schedule, uploads succeed up to configured limits, and performance remains stable over time.
Workflow
- Choose deployment shape – use plain Docker Compose for control.
- Create docker‑compose.yml with services: db (MariaDB), redis, app (Nextcloud), cron (same image with /cron.sh).
- Set environment variables: MYSQL_HOST, MYSQL_DATABASE, MYSQL_USER, MYSQL_PASSWORD, REDIS_HOST, NEXTCLOUD_TRUSTED_DOMAINS, OVERWRITEPROTOCOL, PHP_MEMORY_LIMIT, PHP_UPLOAD_LIMIT.
- Mount volumes: db:/var/lib/mysql, nextcloud:/var/www/html.
- Expose port 8080 to localhost.
- Configure reverse proxy (e.g., Caddy) with request_body max_size 10GB and redirects for /.well-known/caldav and /.well-known/carddav.
- Run docker compose up -d.
- Set background job to Cron in Nextcloud admin settings.
- Run database index commands: php occ db:add-missing-indices and php occ db:add-missing-primary-keys.
- Enable maintenance mode, dump database with mysqldump, copy data directory, then disable maintenance mode.
- Schedule regular backups of database, data directory, and config/config.php.
- Monitor performance and adjust disk size as needed.
Evidence
Nextcloud installs in ten minutes and then spends two years being mysteriously slow. Almost all of it comes down to four settings and one decision about where the files live.
The fourth service is not optional, and it is the one most guides leave out.
Set the method to Cron in Administration → Basic settings.
- Record date: 2026-09-17T15:00:29.865Z