Nextcloud replaces proprietary sync-and-share platforms for families and small teams: files, calendars, contacts, and optional office collaboration under your control. Docker Compose is the standard way to run it at home because you can version the entire stack—application, database, cache, and cron—in one repository. This guide covers a maintainable Compose layout, trusted-domain configuration, reverse-proxy integration, security practices, and backups that protect both database and user data.

Prerequisites

You need a Linux host (or Docker-capable server) with enough RAM for Postgres and PHP—4 GB is a practical minimum for light household use; 8 GB is comfortable with office apps and preview generation. Reserve fast storage for data/ and the database volume; spinning disks work but SSD noticeably improves sync and thumbnail jobs. Obtain a domain name or internal DNS name and plan TLS before users connect mobile clients; the official apps reject invalid certificates. Install Docker Engine and Compose v2. If you will run behind a reverse proxy, create an external Docker network shared with your proxy container.

Stack components

A reliable homelab Nextcloud deployment separates concerns:

  • nextcloud — the application (Apache or FPM image variants exist; FPM behind a web server is common in larger stacks).
  • postgres — authoritative metadata: users, sharing rules, activity, app settings.
  • redis — file locking and transactional cache performance; strongly recommended.
  • cron — background jobs (preview generation, notifications, federation checks).

Using SQLite is tempting for experiments; for production homelab use, Postgres avoids painful migrations later.

Docker Compose example

services:
  db:
    image: postgres:16-alpine
    restart: unless-stopped
    environment:
      POSTGRES_DB: nextcloud
      POSTGRES_USER: nextcloud
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    volumes:
      - ./db:/var/lib/postgresql/data
    networks:
      - nextcloud

  redis:
    image: redis:7-alpine
    restart: unless-stopped
    command: redis-server --requirepass ${REDIS_PASSWORD}
    networks:
      - nextcloud

  app:
    image: nextcloud:29-apache
    restart: unless-stopped
    depends_on:
      - db
      - redis
    environment:
      POSTGRES_HOST: db
      POSTGRES_DB: nextcloud
      POSTGRES_USER: nextcloud
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      REDIS_HOST: redis
      REDIS_HOST_PASSWORD: ${REDIS_PASSWORD}
      NEXTCLOUD_TRUSTED_DOMAINS: cloud.example.com
      OVERWRITEPROTOCOL: https
      TRUSTED_PROXIES: 172.16.0.0/12
    volumes:
      - ./data:/var/www/html/data
      - ./config:/var/www/html/config
    networks:
      - nextcloud
      - proxy

  cron:
    image: nextcloud:29-apache
    restart: unless-stopped
    entrypoint: /cron.sh
    depends_on:
      - app
    volumes:
      - ./data:/var/www/html/data
      - ./config:/var/www/html/config
    networks:
      - nextcloud

networks:
  nextcloud:
  proxy:
    external: true

Store secrets in a .env file excluded from git. After docker compose up -d, complete the web installer only if auto-setup did not run; otherwise use occ for maintenance.

Trusted domains and reverse proxy

Mobile and desktop clients connect via your public URL. Set NEXTCLOUD_TRUSTED_DOMAINS (or edit config/config.php) to include every hostname users type—LAN IP, .local name, and public FQDN. Behind a proxy, set overwritehost, overwriteprotocol, and trusted_proxies so generated links use HTTPS and correct hosts.

Performance tuning for household sync

Redis is not optional at scale—without it, desktop clients exhibit locking errors during large syncs. Tune PHP memory limits for big folder listings. Store previews on SSD; HDD pools work but feel sluggish during initial phone backup of camera rolls. Consider previewgenerator app or workflow if thousands of photos upload from phones. For CalDAV/CardDAV, point clients at the same FQDN; mixed HTTP/HTTPS confuses iOS. Office documents via Collabora or OnlyOffice add another Compose stack—plan RAM accordingly (another 2–4 GB). External storage mounts (S3 primary storage) are advanced; most homelabs keep data/ local or on NAS with nightly snapshots.

occ maintenance commands

Operators live in docker compose exec -u www-data app php occ:

  • occ status — version and maintenance mode
  • occ files:scan --all — after bulk copy into data/
  • occ db:add-missing-indices — after upgrades
  • occ security:bruteforce:reset <ip> — when you lock yourself out

Script these in a monthly cron email to yourself. Before major upgrades, snapshot DB and run occ upgrade explicitly if the container entrypoint does not.

Example Nginx snippet:

location / {
  proxy_pass http://nextcloud-app:80;
  proxy_set_header Host $host;
  proxy_set_header X-Forwarded-Proto $scheme;
  proxy_set_header X-Real-IP $remote_addr;
  client_max_body_size 10G;
}

Large uploads require matching upload_max_filesize in PHP settings via a custom config drop-in or the image’s documented environment variables. Test WebDAV and desktop sync after proxy changes.

Collabora and OnlyOffice (optional)

Document editing adds a second stack. OnlyOffice Document Server in Docker pairs via Nextcloud app settings—allocate 2 GB RAM minimum. Set overwrite.cli.url and internal URLs so Nextcloud talks to OnlyOffice on the Docker network while browsers hit the public HTTPS URL. Misconfigured URLs cause “document could not be loaded” errors that look like corruption but are routing bugs.

High availability expectations

True HA (dual nodes, floating IP) exceeds most homelab needs. Single-node Compose is fine if backups exist. Maintenance windows: enable maintenance:mode, announce to family iMessage, upgrade, smoke-test WebDAV upload/download, disable maintenance. Keep a printed “if NAS is down” note for non-technical household members—humor helps.

Security notes

Nextcloud holds sensitive documents. Enforce HTTPS, disable unused apps, and enable brute-force protection (built-in). Use strong admin and database passwords; rotate app passwords for clients instead of sharing the main password. Keep the image updated—security advisories are frequent. Restrict admin UI exposure if possible (VPN-only management, public read-only shares disabled by policy). Enable server-side encryption only if you understand key recovery implications; it complicates backups and is not a substitute for transport security. Scan with the security and setup warnings in Settings → Administration → Overview after every upgrade.

Backup strategy

You must backup both the database and data/. Application files in the image are disposable; user files and config/ are not.

  1. Put Nextcloud in maintenance mode: docker compose exec -u www-data app php occ maintenance:mode --on
  2. Dump Postgres: docker compose exec db pg_dump -U nextcloud nextcloud > backup.sql
  3. Snapshot ./data and ./config with Restic, Borg, or ZFS snapshots.
  4. Turn maintenance mode off.

Run backups nightly; test restore to a staging Compose project quarterly. Document occ commands you use. For Borg/Restic, exclude caches if documented, but never skip data or the database dump.

Troubleshooting

“Access through untrusted domain”: add the hostname to trusted domains and clear opcode caches. Slow sync or locking errors: verify Redis credentials and connectivity. 413 errors on upload: increase proxy client_max_body_size and PHP limits. Cron jobs not running: ensure the cron container is healthy or configure system cron calling occ every five minutes. Upgrade loops: read release notes; run occ upgrade after image bumps. Preview generation load: move preview settings to off-peak hours or a dedicated preview generator service for large libraries. SMB external storage: latency kills WebDAV—prefer local volume for active sync folders.

Federation and apps

Federation between homelab instances is niche; disable if unused. Audit App Store installs—each app is PHP code with database access. Two-factor authentication via TOTP app should be mandatory for admin. Bruteforce protection whitelist your own VPN egress IP if you lock yourself out repeatedly.

Scaling beyond one household

Ten users on one VM is realistic with SSD and 16 GB RAM; beyond that, consider dedicated database host or external Postgres service. Object storage primary backends (S3) help when local disk is finite—complexity rises. Read-only replicas are enterprise territory; homelabs restart containers instead.

Key takeaways

Nextcloud on Docker Compose is maintainable when Postgres and Redis are first-class citizens from day one, not afterthoughts. Trusted domains and proxy headers are not optional for HTTPS clients. Treat backups as database plus data plus config, with tested restores. Pin versions, automate occ maintenance, and keep the Overview page clean—your household’s files depend on it.