TL;DR — Quick Summary

Deploy Nextcloud with Docker for self-hosted storage, calendar, and contacts. Covers reverse proxy, Redis, OnlyOffice, Talk video calls, and storage tuning.

What Is Nextcloud?

Nextcloud is a self-hosted cloud platform that provides file sync and sharing, calendar, contacts, video calls, document editing, and dozens of other collaboration features — all running on your own server. It is the leading open-source alternative to Google Workspace, Microsoft 365, and Dropbox.

Key features:

  • File sync & share — desktop and mobile clients, selective sync, sharing links
  • Calendar & Contacts — CalDAV and CardDAV, syncs with any standard client
  • Talk — video calls, screen sharing, chat (replaces Zoom/Meet)
  • Office documents — OnlyOffice or Collabora for real-time collaborative editing
  • Notes & Tasks — Markdown notes, Kanban boards, task management
  • Mail — integrated email client
  • 500+ apps — from the Nextcloud App Store
  • End-to-end encryption — per-folder E2E encryption
  • Federation — share files across Nextcloud instances

Prerequisites

  • Docker + Docker Compose installed.
  • Domain name with DNS pointing to your server.
  • Reverse proxy (Traefik, Nginx, or Caddy) for HTTPS.
  • 4 GB RAM minimum (8 GB recommended for office editing).
  • SSD storage recommended for the database and OS.

Installation with Docker Compose

services:
  nextcloud:
    image: nextcloud:latest
    container_name: nextcloud
    restart: always
    ports:
      - "8080:80"
    volumes:
      - nextcloud-data:/var/www/html
      - /mnt/storage/nextcloud:/var/www/html/data
    environment:
      - POSTGRES_HOST=nextcloud-db
      - POSTGRES_DB=nextcloud
      - POSTGRES_USER=nextcloud
      - POSTGRES_PASSWORD=your-secure-password
      - REDIS_HOST=nextcloud-redis
      - NEXTCLOUD_TRUSTED_DOMAINS=cloud.yourdomain.com
      - OVERWRITEPROTOCOL=https
    depends_on:
      - nextcloud-db
      - nextcloud-redis

  nextcloud-db:
    image: postgres:16-alpine
    container_name: nextcloud-db
    restart: always
    volumes:
      - nextcloud-db:/var/lib/postgresql/data
    environment:
      - POSTGRES_DB=nextcloud
      - POSTGRES_USER=nextcloud
      - POSTGRES_PASSWORD=your-secure-password

  nextcloud-redis:
    image: redis:7-alpine
    container_name: nextcloud-redis
    restart: always
    command: redis-server --requirepass your-redis-password

volumes:
  nextcloud-data:
  nextcloud-db:
docker compose up -d

Essential Post-Install Configuration

After initial setup, add these settings to config/config.php (inside the Nextcloud container or data volume):

'memcache.local' => '\\OC\\Memcache\\APCu',
'memcache.distributed' => '\\OC\\Memcache\\Redis',
'memcache.locking' => '\\OC\\Memcache\\Redis',
'redis' => [
    'host' => 'nextcloud-redis',
    'port' => 6379,
    'password' => 'your-redis-password',
],
'default_phone_region' => 'MX',
'maintenance_window_start' => 1,

Background Jobs

Switch from AJAX to Cron for reliable background processing:

# Add to host crontab
*/5 * * * * docker exec -u www-data nextcloud php cron.php

Or use the nextcloud/cron image as a sidecar container.


Must-Install Apps

App Replaces Built-in
Calendar Google Calendar ✅ (CalDAV)
Contacts Google Contacts ✅ (CardDAV)
Talk Zoom / Google Meet
Notes Google Keep ✅ (Markdown)
OnlyOffice Google Docs Install from App Store
Deck Trello Install from App Store
Mail Gmail Install from App Store
Photos Google Photos (basic)
Maps Google Maps (basic) Install from App Store

Reverse Proxy Configuration

Nginx Example

server {
    listen 443 ssl http2;
    server_name cloud.yourdomain.com;

    ssl_certificate /etc/letsencrypt/live/cloud.yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/cloud.yourdomain.com/privkey.pem;

    client_max_body_size 10G;
    fastcgi_buffers 64 4K;

    location / {
        proxy_pass http://localhost:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto https;
    }

    location /.well-known/carddav {
        return 301 $scheme://$host/remote.php/dav;
    }

    location /.well-known/caldav {
        return 301 $scheme://$host/remote.php/dav;
    }
}

Important: Set client_max_body_size to match your maximum upload size. Also configure upload_max_filesize and post_max_size in the Nextcloud PHP settings.


Troubleshooting

“Access through untrusted domain”

Add your domain to config.php:

'trusted_domains' => ['cloud.yourdomain.com'],

Slow performance

  1. Enable Redis caching (see config above).
  2. Use PostgreSQL instead of SQLite.
  3. Enable APCu for local caching.
  4. Set PHP memory_limit to at least 512M.

CalDAV/CardDAV not syncing

Ensure the .well-known redirects are configured in your reverse proxy (see Nginx example above).


Nextcloud vs. Alternatives

Feature Nextcloud Google Workspace Syncthing Seafile
File Sync
Calendar/Contacts
Video Calls ✅ (Talk) ✅ (Meet)
Office Editing ✅ (OnlyOffice) ✅ (Docs)
Self-Hosted ✅ (P2P)
E2E Encryption
Cost Free $6+/user/mo Free Free / paid
App Ecosystem 500+ apps Extensive None Limited

Summary

Nextcloud gives you a complete, self-hosted Google Workspace replacement with file sync, calendar, contacts, video calls, and document editing — all under your control. Deploy it with Docker Compose, configure Redis caching and a reverse proxy, and you have a private cloud for your team or family.