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 justcloud.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-herewith an actual strong password (both places!) - Replace
change-this-too!with your admin password - Replace
cloud.yourdomain.comwith 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
- Point your domain’s A record to your server’s IP
- 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 Settings → Apps → Search for each app, then click Download and Enable.
Step 7: Connect Your Devices
Desktop (Windows/Mac/Linux)
Download Nextcloud Desktop Client:
- Install it
- Launch and click Sign in
- Enter your server URL:
https://cloud.yourdomain.com - Log in with your username/password
- 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:
- iOS: App Store
- Android: Google Play
Before logging in:
- Tap the + to add an account
- Enter your server URL:
https://cloud.yourdomain.com - 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 Settings → Administration → System. 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 Settings → Administration → System, 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 Settings → Sharing and enable “Allow users to share with users on other servers”.
Full-Text Search
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 Settings → Notifications.
External Storage
Connect Nextcloud to AWS S3, Google Drive, or other cloud storage as a “folder” inside Nextcloud. Go to Settings → Administration → External 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:
- You can run 5+ services on the same VPS (Nextcloud, Vaultwarden, Immich, etc.)
- No subscription increases
- 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 Settings → Sharing 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
- Migrate your files from Google Drive (export and upload)
- Install the desktop client and set up sync on your main machine
- Enable Two-Factor Authentication for your admin account
- Set up automatic backups (don’t skip this!)
- Install Collabora Office if you want document editing
- 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.