How to Self-Host Nextcloud with Docker Compose
What is Nextcloud?
Nextcloud is the Swiss Army knife of self-hosting. It replaces Google Drive, Google Calendar, Google Contacts, and dozens of other cloud services with a single platform you control. File sync, document editing, video calls, task management — it does it all. It’s the most popular self-hosted cloud platform, backed by a commercial company with an active open-source community.
Prerequisites
- Docker and Docker Compose installed (Docker Compose basics)
- A server with at least 2GB RAM (best mini PCs for self-hosting)
- A domain name pointing to your server (recommended for SSL)
- Sufficient storage for your files
Docker Compose Configuration
# docker-compose.yml for Nextcloud# Tested with Nextcloud 29+
services: nextcloud: container_name: nextcloud image: nextcloud:29-apache ports: - "8080:80" volumes: - nextcloud_data:/var/www/html - ./data:/var/www/html/data environment: - MYSQL_HOST=db - MYSQL_DATABASE=nextcloud - MYSQL_USER=nextcloud - MYSQL_PASSWORD=${DB_PASSWORD} - NEXTCLOUD_ADMIN_USER=${ADMIN_USER} - NEXTCLOUD_ADMIN_PASSWORD=${ADMIN_PASSWORD} - NEXTCLOUD_TRUSTED_DOMAINS=${TRUSTED_DOMAINS} # Performance tuning - PHP_MEMORY_LIMIT=1024M - PHP_UPLOAD_LIMIT=16G depends_on: db: condition: service_healthy redis: condition: service_healthy restart: unless-stopped
db: container_name: nextcloud_db image: mariadb:11 volumes: - db_data:/var/lib/mysql environment: - MYSQL_ROOT_PASSWORD=${DB_ROOT_PASSWORD} - MYSQL_DATABASE=nextcloud - MYSQL_USER=nextcloud - MYSQL_PASSWORD=${DB_PASSWORD} command: --transaction-isolation=READ-COMMITTED --log-bin=binlog --binlog-format=ROW healthcheck: test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"] interval: 10s timeout: 5s retries: 5 restart: unless-stopped
redis: container_name: nextcloud_redis image: redis:7-alpine volumes: - redis_data:/data healthcheck: test: redis-cli ping || exit 1 interval: 10s timeout: 5s retries: 5 restart: unless-stopped
cron: container_name: nextcloud_cron image: nextcloud:29-apache volumes: - nextcloud_data:/var/www/html - ./data:/var/www/html/data entrypoint: /cron.sh depends_on: - nextcloud restart: unless-stopped
volumes: nextcloud_data: db_data: redis_data:Create a .env file:
# .env file for NextcloudDB_PASSWORD=change-this-secure-passwordDB_ROOT_PASSWORD=change-this-root-passwordADMIN_USER=adminADMIN_PASSWORD=change-this-admin-passwordTRUSTED_DOMAINS=localhost your-domain.comStep-by-Step Setup
-
Create a directory for Nextcloud:
Terminal window mkdir ~/nextcloud && cd ~/nextcloud -
Create the
docker-compose.ymland.envfiles with the configs above. Change all passwords. -
Start the containers:
Terminal window docker compose up -d -
Wait for initialization — first startup takes 1-2 minutes while the database is configured.
-
Access the web UI at
http://your-server-ip:8080 -
Enable Redis caching — go to Settings → Administration → Basic settings and verify Redis is detected. If not, edit
config.php:'memcache.local' => '\\OC\\Memcache\\APCu','memcache.distributed' => '\\OC\\Memcache\\Redis','memcache.locking' => '\\OC\\Memcache\\Redis','redis' => ['host' => 'redis','port' => 6379,], -
Install the desktop and mobile sync clients from nextcloud.com/install.
Configuration Tips
- Increase upload limits: The config above already sets
PHP_UPLOAD_LIMIT=16G. Verify in Settings → Administration. - Background jobs: The
croncontainer handles background tasks automatically. Verify it’s set to “Cron” in Settings → Administration → Basic settings. - Reverse proxy: Put Nextcloud behind a reverse proxy for HTTPS. See our reverse proxy guide. You’ll need to set
overwriteprotocoltohttpsinconfig.php. - Collabora/OnlyOffice: Add document editing by installing the Collabora Online or OnlyOffice app from the Nextcloud app store.
Backup & Migration
- Backup: Back up the
datafolder (your files), the MariaDB database (docker exec nextcloud_db mysqldump --single-transaction -u root -p nextcloud > backup.sql), and theconfig.phpfile. - Migration from Google Drive: Use Google Takeout to export your files, then upload them through the Nextcloud web interface or sync client.
Troubleshooting
- Sync not working: Check that the trusted domains setting includes your actual domain/IP. See our Nextcloud sync troubleshooting guide.
- Slow performance: Enable Redis caching (see step 6), increase PHP memory limit, and consider Nextcloud performance optimization.
- 502 Bad Gateway behind reverse proxy: Check the
overwriteprotocol,overwritecliurl, andtrusted_proxiessettings inconfig.php.
Alternatives
If you only need file sync (without calendars, contacts, and apps), consider Syncthing (peer-to-peer, no server needed) or Seafile (faster sync for large libraries). See our Nextcloud vs Syncthing comparison or the full Best Self-Hosted File Sync roundup.
Verdict
Nextcloud is the default choice for self-hosted cloud storage. No other platform comes close to its breadth of features. The tradeoff is complexity — it’s heavier than single-purpose tools and needs tuning for good performance. But if you want one platform to replace Google Workspace, Nextcloud is it.