Skip to main content

Self-Host Nextcloud: Cloud Storage & Collaboration 2026

·OSSAlt Team
nextcloudcloud-storagegoogle-driveself-hostingdocker2026

TL;DR

Nextcloud (AGPL 3.0, ~27K GitHub stars, PHP) is the most comprehensive self-hosted collaboration platform — Google Drive + Calendar + Contacts + Docs editing + Video calls, all in one. Google Workspace charges $6/user/month. Nextcloud replaces it entirely: file sync across all devices, real-time document editing (via Collabora or OnlyOffice), CalDAV/CardDAV sync to iOS/Android/macOS, and Nextcloud Talk for video calls. 300,000+ installs worldwide — used by the German government, universities, and enterprises.

Key Takeaways

  • Nextcloud: AGPL 3.0, ~27K stars, PHP — most feature-complete self-hosted Google alternative
  • Nextcloud Office: Real-time collaborative editing of DOCX/XLSX/PPTX via Collabora Online
  • CalDAV/CardDAV: Native calendar and contacts sync to iOS, Android, macOS, Thunderbird
  • Talk: Video calls, chat, screen sharing — Zoom/Teams alternative built-in
  • 250+ apps: Extend with Notes, Deck (kanban), Whiteboard, AI Assistant, etc.
  • External storage: Mount Google Drive, Dropbox, S3, SMB as external folders

Part 1: Docker Setup

# docker-compose.yml
services:
  nextcloud:
    image: nextcloud:latest
    container_name: nextcloud
    restart: unless-stopped
    ports:
      - "8080:80"
    volumes:
      - nextcloud_html:/var/www/html
      - nextcloud_data:/var/www/html/data
    environment:
      POSTGRES_HOST: db
      POSTGRES_DB: nextcloud
      POSTGRES_USER: nextcloud
      POSTGRES_PASSWORD: "${POSTGRES_PASSWORD}"
      NEXTCLOUD_ADMIN_USER: "${ADMIN_USER}"
      NEXTCLOUD_ADMIN_PASSWORD: "${ADMIN_PASSWORD}"
      NEXTCLOUD_TRUSTED_DOMAINS: "cloud.yourdomain.com"
      REDIS_HOST: redis
      SMTP_HOST: "smtp.yourdomain.com"
      SMTP_SECURE: "tls"
      SMTP_PORT: 587
      SMTP_NAME: "${SMTP_USER}"
      SMTP_PASSWORD: "${SMTP_PASS}"
      MAIL_FROM_ADDRESS: "cloud"
      MAIL_DOMAIN: "yourdomain.com"
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_started

  db:
    image: postgres:16-alpine
    restart: unless-stopped
    environment:
      POSTGRES_DB: nextcloud
      POSTGRES_USER: nextcloud
      POSTGRES_PASSWORD: "${POSTGRES_PASSWORD}"
    volumes:
      - db_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U nextcloud"]
      interval: 10s
      start_period: 20s

  redis:
    image: redis:7-alpine
    restart: unless-stopped

  # Cron job for background tasks:
  nextcloud-cron:
    image: nextcloud:latest
    container_name: nextcloud_cron
    restart: unless-stopped
    volumes:
      - nextcloud_html:/var/www/html
      - nextcloud_data:/var/www/html/data
    entrypoint: /cron.sh
    depends_on:
      - db
      - redis

volumes:
  nextcloud_html:
  nextcloud_data:
  db_data:
# .env
POSTGRES_PASSWORD=your-db-password
ADMIN_USER=admin
ADMIN_PASSWORD=your-admin-password

docker compose up -d

Part 2: HTTPS with Caddy

cloud.yourdomain.com {
    # CalDAV/CardDAV redirects (required for iOS/macOS auto-discovery):
    redir /.well-known/carddav /remote.php/dav 301
    redir /.well-known/caldav /remote.php/dav 301

    reverse_proxy localhost:8080
}

Part 3: Essential Configuration

After setup, run these optimizations:

# Add Nextcloud recommended settings:
docker exec -u www-data nextcloud php occ config:system:set default_phone_region --value="US"
docker exec -u www-data nextcloud php occ config:system:set maintenance_window_start --type=integer --value=1
docker exec -u www-data nextcloud php occ config:system:set log_type --value=file
docker exec -u www-data nextcloud php occ config:system:set loglevel --type=integer --value=2

# Enable Redis caching:
docker exec -u www-data nextcloud php occ config:system:set redis host --value=redis
docker exec -u www-data nextcloud php occ config:system:set redis port --type=integer --value=6379
docker exec -u www-data nextcloud php occ config:system:set memcache.local --value='\OC\Memcache\Redis'
docker exec -u www-data nextcloud php occ config:system:set memcache.locking --value='\OC\Memcache\Redis'

# Run initial maintenance:
docker exec -u www-data nextcloud php occ maintenance:repair
docker exec -u www-data nextcloud php occ db:add-missing-indices

Part 4: Nextcloud Office (Collabora)

Real-time collaborative document editing — edit DOCX, XLSX, PPTX in browser:

# Add to docker-compose.yml:
services:
  collabora:
    image: collabora/code:latest
    container_name: collabora
    restart: unless-stopped
    ports:
      - "9980:9980"
    environment:
      aliasgroup1: "https://cloud.yourdomain.com:443"
      username: admin
      password: "${COLLABORA_PASSWORD}"
      extra_params: "--o:ssl.enable=false --o:ssl.termination=true"
    cap_add:
      - MKNOD
# Add to Caddy:
office.yourdomain.com {
    reverse_proxy collabora:9980
}

In Nextcloud:

  1. Apps → Nextcloud Office → Install
  2. Settings → Administration → Nextcloud Office
  3. Use your own serverhttps://office.yourdomain.com

Now clicking any DOCX/XLSX opens the Collabora editor in your browser.


Part 5: Desktop Sync Clients

Desktop client setup

  1. Download Nextcloud Desktop (Windows/Mac/Linux)
  2. Log in → Server: https://cloud.yourdomain.com
  3. Choose sync folders

Mobile apps

iOS: Install Nextcloud from App Store → add server URL → auto-upload photos
Android: Install from Google Play or F-Droid → same setup → enable automatic photo upload


Part 6: Calendar (CalDAV)

iOS / macOS Calendar

  1. Settings → Calendar → Accounts → Add Account → Other → CalDAV
  2. Server: https://cloud.yourdomain.com
  3. Username: your Nextcloud username
  4. Password: your password (or create an App Password)

Android

Use DAVx⁵ (free on F-Droid):

  1. Install DAVx⁵
  2. + → Login with URL: https://cloud.yourdomain.com/remote.php/dav
  3. Username + password → sync calendars and contacts

Thunderbird

  1. Calendar → New Calendar → On the Network → CalDAV
  2. URL: https://cloud.yourdomain.com/remote.php/dav/calendars/username/personal/

Part 7: Nextcloud Talk (Video Calls)

Built-in video conferencing — Zoom alternative:

  1. Apps → Talk → Install
  2. Create a conversation → Video call icon

High-performance backend (for large calls, 5+ participants):

# Add Coturn TURN server for calls through NAT:
services:
  coturn:
    image: coturn/coturn:alpine
    network_mode: host
    volumes:
      - ./coturn.conf:/etc/coturn/turnserver.conf:ro
# In Talk admin settings:
# STUN server: stun.yourdomain.com:3478
# TURN server: turns:turn.yourdomain.com:3478 [shared secret]

Part 8: Notable Apps

Install from Apps in Nextcloud admin:

AppFunction
Nextcloud NotesMarkdown notes, iOS/Android sync
DeckKanban project boards
WhiteboardCollaborative infinite canvas
MailWeb email client (IMAP)
ContactsFull CardDAV address book UI
MusicSubsonic-compatible music player
PhotosAI photo management (basic)
External storageMount S3, Google Drive, Dropbox, SMB
SocialActivityPub-federated social network
CirclesTeam groups and sharing
Two-Factor TOTP2FA for accounts
Nextcloud AILLM assistant (configurable backends)

Part 9: User Management

# Create a user:
docker exec -u www-data nextcloud php occ user:add alice \
  --display-name "Alice Smith" \
  --group "users"

# List users:
docker exec -u www-data nextcloud php occ user:list

# Set storage quota:
docker exec -u www-data nextcloud php occ user:setting alice files quota 50GB

# Disable a user:
docker exec -u www-data nextcloud php occ user:disable alice

# Reset password:
docker exec -u www-data nextcloud php occ user:resetpassword alice

Maintenance

# Update Nextcloud:
docker compose pull
docker compose up -d
# Then run upgrade:
docker exec -u www-data nextcloud php occ upgrade
docker exec -u www-data nextcloud php occ db:add-missing-indices
docker exec -u www-data nextcloud php occ maintenance:mimetype:update-db

# Backup:
docker exec nextcloud-db-1 pg_dump -U nextcloud nextcloud \
  | gzip > nextcloud-db-$(date +%Y%m%d).sql.gz
tar -czf nextcloud-data-$(date +%Y%m%d).tar.gz \
  $(docker volume inspect nextcloud_nextcloud_data --format '{{.Mountpoint}}')

# Fix file permissions:
docker exec nextcloud chown -R www-data:www-data /var/www/html

# Logs:
docker compose logs -f nextcloud
docker exec -u www-data nextcloud php occ log:tail

See all open source cloud storage tools at OSSAlt.com/categories/storage.

Comments