How to Self-Host Nextcloud: Your Private Google Drive Alternative

How to Self-Host Nextcloud: Your Private Google Drive Alternative

Complete guide to self-hosting Nextcloud with Docker. Build your own cloud storage, calendar, and file sync — no subscription required.

If you’re tired of paying $100/year for Google One or worried about Google reading your files (let’s be honest, they’re analyzing them), self-hosting Nextcloud is the move. Nextcloud is an open-source cloud storage platform that does everything Google Drive and Dropbox do — sync files, calendar, contacts, collaborative editing — but it runs on your server, under your control.

I switched from Google Drive three years ago and never looked back. Yes, the initial setup is more work than just using Google’s cloud, but the peace of mind is worth it. Plus, you get file versioning, advanced sharing controls, and encrypted end-to-end encryption — features Google charges extra for.

In this guide, I’ll walk you through deploying Nextcloud with Docker Compose, PostgreSQL for the database (MariaDB works too), and Redis for performance. This isn’t a minimal setup — this is production-ready with caching and proper resource tuning.

Why Self-Host Nextcloud Instead of Google Drive?

Let’s address the elephant in the room: yes, Google Drive is convenient and cheap. But there are real reasons to self-host:

Privacy & control: Your files never touch Google’s servers. Full stop. No AI training data, no privacy policy changes, no surprise access from government agencies. Your data is yours.

Unlimited storage (technically): Pay once for a server, store terabytes. Google charges $99/year for 2TB. With Nextcloud, you’re only paying for the hardware — usually $5-10/month.

Offline access: Files sync to your devices. Work offline, they sync when you’re back online. Google Drive used to have this; now it’s killed.

File versioning & encryption: Keep unlimited file versions. Restore anything to any point in time. Encrypt files end-to-end so even you can’t see them if you lose the key (optional, but awesome).

Collaborative tools built-in: Calendar, contacts, task lists, collaborative documents (with Collabora Office integration). No switching between apps.

It’s actually simple: Docker makes Nextcloud deployment dead-simple. If you can copy-paste, you can self-host it.

The downside? You’re responsible for backups, updates, and if something breaks at 3am, that’s on you.

What You’ll Need

Before we start, here’s what I use:

  • A server: Minimum 2GB RAM, 30GB storage. I recommend at least 4GB RAM if you’re syncing 100k+ files. Hetzner’s CX21 (€7/month) or DigitalOcean’s $12/month droplet works great.
  • A domain: You’ll need nextcloud.yourdomain.com (or just cloud.yourdomain.com). SSL is mandatory.
  • Docker & Docker Compose: We’ll install these.
  • Patience for the first setup: Initial sync of 50k+ files can take hours. Plan accordingly.

Performance note: Nextcloud eats RAM. Here’s what I’ve observed:

  • 10-100 files: 512MB RAM fine
  • 100-10,000 files: 2GB RAM minimum
  • 10k-100k files: 4GB+ RAM, Redis caching required
  • 100k+ files: 8GB+ RAM, dedicated PostgreSQL, Redis, and probably a reverse proxy (nginx/Caddy)

I’m running on 4GB and it’s snappy with ~50k files.

Step 1: Prepare Your Server

SSH into your server:

ssh root@your-server-ip

Install Docker

apt update
apt install -y apt-transport-https ca-certificates curl software-properties-common

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"

apt update
apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin

docker --version
docker compose version

Create Directory Structure

mkdir -p /opt/nextcloud/{data,postgres,redis}
cd /opt/nextcloud

The data folder will hold your files, postgres holds the database, and redis is for caching.

Step 2: Create the Docker Compose File

This is the heart of the setup. It spins up four containers: Nextcloud, PostgreSQL, Redis, and Caddy (for SSL).

nano docker-compose.yml

Paste this:

version: '3.8'

services:
  postgres:
    image: postgres:16-alpine
    container_name: nextcloud-db
    restart: unless-stopped
    environment:
      POSTGRES_DB: nextcloud
      POSTGRES_USER: nextcloud
      POSTGRES_PASSWORD: generate-a-strong-password-here  # Change this!
    volumes:
      - ./postgres:/var/lib/postgresql/data
    networks:
      - nextcloud-network
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U nextcloud"]
      interval: 10s
      timeout: 5s
      retries: 5

  redis:
    image: redis:7-alpine
    container_name: nextcloud-redis
    restart: unless-stopped
    command: redis-server --appendonly yes
    volumes:
      - ./redis:/data
    networks:
      - nextcloud-network
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5

  nextcloud:
    image: nextcloud:apache
    container_name: nextcloud-app
    restart: unless-stopped
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy
    environment:
      POSTGRES_HOST: postgres
      POSTGRES_DB: nextcloud
      POSTGRES_USER: nextcloud
      POSTGRES_PASSWORD: generate-a-strong-password-here  # Must match above!
      REDIS_HOST: redis
      NEXTCLOUD_ADMIN_USER: admin
      NEXTCLOUD_ADMIN_PASSWORD: change-this-too!  # Change this!
      NEXTCLOUD_TRUSTED_DOMAINS: "cloud.yourdomain.com localhost 192.168.1.0/24"
      OVERWRITEPROTOCOL: https
      OVERWRITEHOST: cloud.yourdomain.com  # Change this!
      OVERWRITEWEBROOT: /
    volumes:
      - ./data:/var/www/html/data
      - ./nextcloud:/var/www/html
    ports:
      - "8080:80"
    networks:
      - nextcloud-network

  caddy:
    image: caddy:latest
    container_name: nextcloud-proxy
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - ./caddy-data:/data
      - ./caddy-config:/config
    networks:
      - nextcloud-network

networks:
  nextcloud-network:
    driver: bridge

Critical configuration:

  • Replace generate-a-strong-password-here with an actual strong password (both places!)
  • Replace change-this-too! with your admin password
  • Replace cloud.yourdomain.com with your actual domain

Generate a strong password:

openssl rand -base64 32

Create the Caddyfile

nano Caddyfile

Paste this:

cloud.yourdomain.com {
    reverse_proxy nextcloud-app:80

    encode gzip

    header {
        Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
        X-Content-Type-Options "nosniff"
        X-Frame-Options "SAMEORIGIN"
        Referrer-Policy "no-referrer"
    }

    # Client timeout for large uploads
    request_header Connection "Upgrade"
    request_header Upgrade "websocket"
}

Change cloud.yourdomain.com to your domain.

Step 3: Configure DNS

  1. Point your domain’s A record to your server’s IP
  2. Wait 5-10 minutes for propagation

Test it:

dig cloud.yourdomain.com +short

Step 4: Start Nextcloud

cd /opt/nextcloud
docker compose up -d

Check status:

docker compose ps

All containers should show Up. If any are failing, check logs:

docker compose logs nextcloud
docker compose logs postgres
docker compose logs redis

Caddy will automatically get an SSL certificate from Let’s Encrypt. This takes 10-30 seconds.

Step 5: First Login & Initial Setup

Navigate to https://cloud.yourdomain.com in your browser. You’ll see the Nextcloud setup wizard.

The admin username and password are whatever you set in the Docker Compose environment variables.

First time setup tips:

  • It might take 2-3 minutes to fully load (especially if you’re syncing many files later)
  • The initial database setup happens automatically
  • You’ll see a warning about .well-known — ignore it for now (we’ll fix it if needed)

Step 6: Essential Apps to Install

Nextcloud’s power comes from apps. After logging in, go to Apps (top menu).

I recommend installing these:

Files & Sync:

  • Files (already installed) — core file management
  • Full Text Search — search through file contents (needs extra setup but worth it)

Productivity:

  • Calendar — sync with Outlook, Google Calendar, Apple Calendar
  • Contacts — your address book, syncs to phone
  • Tasks — todo lists, syncs across devices
  • Notes — lightweight markdown notes (I use this constantly)

Collaboration:

  • Collabora Office — Google Docs alternative (document editing directly in Nextcloud)
  • Comments — comment on files

Security:

  • Encryption — client-side file encryption (optional, but adds real privacy)
  • Two-Factor Authentication — enable this immediately for your admin account

Optional but useful:

  • Deck — kanban board for project management
  • Mail (if you want email integration)

Go to SettingsApps → Search for each app, then click Download and Enable.

Step 7: Connect Your Devices

Desktop (Windows/Mac/Linux)

Download Nextcloud Desktop Client:

  1. Install it
  2. Launch and click Sign in
  3. Enter your server URL: https://cloud.yourdomain.com
  4. Log in with your username/password
  5. Select which folders to sync

I recommend syncing selectively, not your entire Nextcloud folder. Choose specific directories to avoid overwhelming your local drive.

Mobile (iOS/Android)

Install the official Nextcloud app:

Before logging in:

  1. Tap the + to add an account
  2. Enter your server URL: https://cloud.yourdomain.com
  3. Log in

The mobile app is surprisingly good — better than Google Drive’s app in my opinion.

Web Browser

Just visit https://cloud.yourdomain.com and log in. The web interface handles uploads, file preview, and most operations.

Step 8: Performance Tuning

By default, Nextcloud works fine. But if you have 10k+ files or heavy usage, tune these settings.

Enable Background Jobs

This prevents Nextcloud from running tasks during web requests (which is slow).

SSH into your server:

docker compose exec -u www-data nextcloud-app \
  php occ config:app:set core backgroundjobs_mode --value cron

Then add a cron job:

crontab -e

Add this line (runs every 5 minutes):

*/5 * * * * cd /opt/nextcloud && docker compose exec -u www-data nextcloud-app php occ maintenance:mode --off >/dev/null 2>&1 && cd /opt/nextcloud && docker compose exec -u www-data nextcloud-app php -f cron.php >/dev/null 2>&1

Actually, wait — that’s complex. Use this instead (simpler):

*/5 * * * * docker exec nextcloud-app php -f cron.php > /dev/null 2>&1

Enable Redis Caching

We already have Redis in the Docker Compose. Now tell Nextcloud to use it.

Go to SettingsAdministrationSystem. Look for “Caching”. Nextcloud should auto-detect Redis. If not, check that Redis is running:

docker compose logs redis

Increase Upload Limits

By default, Nextcloud limits uploads to ~512MB. To increase (edit the Docker Compose):

nextcloud:
  environment:
    PHP_UPLOAD_LIMIT: 10G
    PHP_MEMORY_LIMIT: 1G

Then restart:

docker compose down
docker compose up -d

(You can also change this in the web interface under SettingsAdministrationSystem, but environment variables are cleaner.)

Enable HTTP/2

Makes downloads/uploads faster. Already handled by Caddy, nothing to do here.

Step 9: Backups (Critical!)

Your Nextcloud data is precious. Back it up regularly.

nano /opt/nextcloud/backup.sh

Paste this:

#!/bin/bash
BACKUP_DIR="/opt/backups/nextcloud"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)

mkdir -p $BACKUP_DIR

cd /opt/nextcloud

# Put Nextcloud in maintenance mode
docker compose exec -u www-data nextcloud-app php occ maintenance:mode --on

# Backup database
docker compose exec postgres pg_dump -U nextcloud nextcloud | \
  gzip > "$BACKUP_DIR/nextcloud-db_$TIMESTAMP.sql.gz"

# Backup files
tar -czf "$BACKUP_DIR/nextcloud-files_$TIMESTAMP.tar.gz" data/ nextcloud/config/

# Exit maintenance mode
docker compose exec -u www-data nextcloud-app php occ maintenance:mode --off

# Cleanup old backups (keep 14 days)
find $BACKUP_DIR -name "nextcloud-*" -mtime +14 -delete

echo "Backup completed: $TIMESTAMP"

Make it executable:

chmod +x /opt/nextcloud/backup.sh

Run it manually first:

/opt/nextcloud/backup.sh

Schedule it daily:

crontab -e

Add:

0 2 * * * /opt/nextcloud/backup.sh >> /var/log/nextcloud-backup.log 2>&1

This runs every day at 2 AM.

Step 10: Advanced Tips

Federated Sharing

You can share files with users on other Nextcloud servers. Go to SettingsSharing and enable “Allow users to share with users on other servers”.

If you installed Full Text Search, set it up:

docker compose exec -u www-data nextcloud-app php occ search:index

This indexes all files. First run takes a while (depends on file count), but afterward search is instant.

Notification Push

Enable desktop notifications in the mobile app. Go to SettingsNotifications.

External Storage

Connect Nextcloud to AWS S3, Google Drive, or other cloud storage as a “folder” inside Nextcloud. Go to SettingsAdministrationExternal storages. (Requires additional apps.)

Gotchas I’ve Hit (So You Don’t Have To)

Forgotten admin password: Use this command:

docker compose exec -u www-data nextcloud-app php occ user:resetpassword admin

“Trusted domain” errors: If you access Nextcloud from multiple domains/IPs, add them to NEXTCLOUD_TRUSTED_DOMAINS in docker-compose.yml. Separate by space.

Mobile sync is slow: This is normal on first sync of many files. Subsequent syncs are fast. Be patient.

Nextcloud is using too much RAM: Make sure Redis is working. Check:

docker compose logs redis

And that your PHP memory limit isn’t too low (should be 1G minimum).

Large file uploads fail: Check your PHP max upload size. Should be set via environment variable in docker-compose.yml.

Troubleshooting

“Unable to login”:

  • Check the admin username/password in docker-compose.yml
  • Restart Nextcloud: docker compose restart nextcloud

“504 Bad Gateway”:

  • Caddy couldn’t reach Nextcloud. Check Nextcloud logs: docker compose logs nextcloud
  • Restart everything: docker compose down && docker compose up -d

“Pending Cron Jobs”:

  • Set up background cron (see Performance Tuning section)

“Maintenance Mode”:

  • If Nextcloud won’t load, it’s probably in maintenance mode:
docker compose exec -u www-data nextcloud-app php occ maintenance:mode --off

Cost Analysis

Google One (1TB): $100/year Nextcloud self-hosted (unlimited):

  • Hetzner CX21: €7/month = €84/year (~$90)
  • Domain: ~$12/year
  • Total: ~$102/year

For smaller storage it’s similar, but:

  1. You can run 5+ services on the same VPS (Nextcloud, Vaultwarden, Immich, etc.)
  2. No subscription increases
  3. Complete privacy

If you’re already self-hosting, the marginal cost is basically zero.

FAQ

Q: Can multiple users share files? A: Yes. Go to SettingsSharing and create additional users. Set share permissions per-folder.

Q: Is Nextcloud as good as Google Drive? A: For file sync and versioning, it’s better. For collaborative editing, Collabora Office is pretty close (but not quite as polished as Google Docs). For everything else (storage, sharing, mobile sync), it’s essentially equivalent.

Q: Do I need backups if I have RAID? A: Yes. RAID protects against drive failure, not against ransomware, accidental deletion, or buggy updates that corrupt your data. Backups to external storage are critical.

Q: Can I access files offline? A: Yes, via the desktop client. Files you’ve synced locally are available offline. Once you’re back online, changes sync automatically.

Q: What if my server dies? A: That’s why you back up. Restore from backup to a new server (same docker-compose.yml setup). Should take 30 minutes.

Q: Can I run Nextcloud on my home network? A: Yes, but you’ll need a dynamic DNS service to point your domain to your home IP (which changes). And your ISP probably limits upload bandwidth. A cheap VPS is better.


Next Steps

  1. Migrate your files from Google Drive (export and upload)
  2. Install the desktop client and set up sync on your main machine
  3. Enable Two-Factor Authentication for your admin account
  4. Set up automatic backups (don’t skip this!)
  5. Install Collabora Office if you want document editing
  6. Explore other self-hosted apps to run alongside Nextcloud

Interested in self-hosting more? Check out our guide on self-hosting Vaultwarden for password management or self-hosting Immich for photo backup (coming soon).


Resources:

Stay in the loop 📬

Get self-hosting tutorials, tool reviews, and infrastructure tips delivered to your inbox. No spam, unsubscribe anytime.

Join 0 self-hosters. Free forever.