Deployment guide

Self-Host Nextcloud on VPS: Complete Guide, NC 34 and Security

Deploy on a VPS Cloud →

Self-hosting12 min read

Self-Host Nextcloud on VPS: Complete Guide, NC 34 and Security

Nextcloud is one of the most widely deployed self-hosted applications — and one of the most misconfigured. Between instances running without Redis, without forced TLS, the May 2026 update patching two critical 2FA bypass vulnerabilities, and now the NC 34.0.0-specific regressions — recommended apps missing at first launch, a duplicated PostgreSQL constraint that can spike CPU — every release brings its own pitfalls. This guide takes you from a complete installation to security verification, covering the NC 34.0.2 fixes and the 5 most common mistakes.

Security Alert — May 2026 2FA Bypass CVEs

In May 2026, two critical two-factor authentication bypass vulnerabilities were disclosed in Nextcloud:

CVE-2026-45690 (CVSS score 5.9, disclosed May 15, 2026): an attacker with a username and password can bypass 2FA verification using HTTP Basic Auth (basic authentication via the Authorization: Basic base64(user:pass) header). Nextcloud, in affected versions, accepted HTTP Basic Auth even when 2FA was enabled for the targeted account.

CVE-2026-45691 (CVSS score 5.9, disclosed May 13, 2026): same vulnerability class, exploitable via a DAV Bearer token — the WebDAV protocol used by desktop sync clients (Nextcloud Desktop, Nautilus, Finder).

Both CVEs are fixed in Nextcloud 32.0.9 (branch 32), 33.0.3 (branch 33), and 34.0.2 (branch 34). Check if your instance is vulnerable (see dedicated section below).

NC 34.0.0 — Recommended Apps Missing on First Launch

Nextcloud 34.0.0 introduces a regression in the installation wizard: recommended apps (Notes, Calendar, Contacts) are not offered during initial setup. The suggested apps list stays empty, regardless of the installation profile selected.

Practical impact: a fresh NC 34.0.0 instance lacks the basic productivity apps. Users expecting CalDAV calendar or CardDAV contact sync must install them manually from the admin interface.

Sources: GitHub issues #61313 and #61611 — fixed in 34.0.2.

Check if your apps are present:

docker compose exec -u www-data app php occ app:list | grep -E 'calendar|contacts|notes'

If the command returns nothing, the apps are not installed. To add them manually:

docker compose exec -u www-data app php occ app:install calendar
docker compose exec -u www-data app php occ app:install contacts
docker compose exec -u www-data app php occ app:install notes

Recommendation: start directly on 34.0.2 or higher rather than 34.0.0. If your instance is already on 34.0.0, updating to 34.0.2 restores the wizard — but missing apps on the existing instance still need to be installed manually.

NC 34.0.0 — Duplicated PostgreSQL Constraint and CPU Spike

On instances using PostgreSQL (instead of MariaDB/MySQL), an interrupted Nextcloud 34.0.0 migration can leave a duplicated constraint on the oc_filecache_extended table. This duplicate goes unnoticed at startup but triggers a CPU and RAM spike during the next file scan (files:scan) or automatic maintenance.

Symptoms: abnormally high CPU load on the Nextcloud container, a file scan that never completes, log errors like duplicate key value violates unique constraint.

Source: GitHub issue #61597.

Verification and fix:

# 1. Clean up orphaned file cache entries
docker compose exec -u www-data app php occ files:cleanup

# 2. Rebuild missing indices on the affected table
docker compose exec -u www-data app php occ db:add-missing-indices

# 3. Verify no missing columns
docker compose exec -u www-data app php occ db:add-missing-columns

If errors persist, upgrade directly to 34.0.2 which contains the migration fix.

Note: this issue does not affect MariaDB/MySQL instances. PostgreSQL production instances on NC 34.0.0 should apply these commands before the next automatic scan.

Prerequisites and Sizing

Recommended configuration: VPS with 2 GB RAM (4 GB for more than 5 active users), SSD required (many file and thumbnail operations), 20 GB minimum storage plus data space, Ubuntu 22.04 or Debian 12, Docker Engine ≥ 24, a domain name with TLS certificate, ports 80 and 443 open.

Installing Nextcloud with Docker Compose

01

Step 1 — Create the project structure

Create /opt/nextcloud/docker-compose.yml with MariaDB 10.11, Redis 7-alpine, and Nextcloud nextcloud:34.0.2-apache. Bind the app to 127.0.0.1:8080:80. Set depends_on: db and redis.

02

Step 2 — Create the environment file

cat > /opt/nextcloud/.env << 'EOF'
MYSQL_ROOT_PASSWORD=strong_root_password
MYSQL_PASSWORD=strong_nextcloud_password
REDIS_PASSWORD=strong_redis_password
NEXTCLOUD_ADMIN_USER=admin
NEXTCLOUD_ADMIN_PASSWORD=strong_admin_password
NEXTCLOUD_DOMAIN=cloud.yourdomain.com
EOF
03

Step 3 — Start the containers

docker compose up -d
docker compose logs -f app

First startup takes 2 to 4 minutes. Wait for Nextcloud was successfully installed.

04

Step 4 — Configure Nginx with TLS

Install Nginx and Certbot, create the Nextcloud site with client_max_body_size 10G; and proxy headers, then run certbot --nginx -d cloud.yourdomain.com.

05

Step 5 — Configure SMTP for Email Notifications

Nextcloud sends email notifications for file sharing, password reset, and 2FA. Configure SMTP in Administration → Basic Settings:

- Send mode: SMTP
- Host: your SMTP server (e.g. smtp.eu.mailgun.org)
- Port: 587 (STARTTLS)
- Authentication: required
- Username/password: your SMTP credentials

Test with Send test email at the bottom of the page.

Check if Your Instance is Vulnerable to the 2FA CVEs

Check current version:

docker compose exec -u www-data app php occ status

Vulnerable versions: all Nextcloud 32.x < 32.0.9, 33.x < 33.0.3, and 34.x < 34.0.2.

Vulnerability test (on your own instance only):

curl -u user:password -X PROPFIND \
  https://cloud.yourdomain.com/remote.php/dav/files/user/ \
  -H "Depth: 0" -s -o /dev/null -w "%{http_code}"

If this returns 207 Multi-Status without 2FA challenge, your instance is vulnerable to CVE-2026-45690.

Update to 34.0.2:

sed -i 's|nextcloud:[0-9.]*-apache|nextcloud:34.0.2-apache|g' docker-compose.yml
docker compose pull app && docker compose up -d app
docker compose exec -u www-data app php occ upgrade

Optimize Performance with Redis and OPcache

Nextcloud without Redis is a slow Nextcloud. Redis plays two critical roles: session caching (avoids disk reads/writes on every authenticated request) and distributed locking (file locking) which prevents conflicts during simultaneous synchronizations.

Verify Redis is connected:

docker compose exec -u www-data app php occ config:system:get redis

If nothing appears, add the Redis config to config.php manually.

The 5 Most Common Mistakes

1. Redis not configured — slow interface, sync conflicts. Fix: configure Redis as shown above.
2. overwrite.cli.url pointing to http:// instead of https:// — share links and emails generate insecure URLs.
3. trusted_domains misconfigured — 'untrusted domain' access denied error.
4. Upload size limited to 2 MB — PHP default is too low. Add client_max_body_size 10G in Nginx and configure PHP upload_max_filesize=10G.
5. Missed security updates — instances stay vulnerable without regular patching.

Verify Redis Effectiveness with occ

# Check general instance status
docker compose exec -u www-data app php occ status

# List configuration warnings (memcache, Redis, HTTPS…)
docker compose exec -u www-data app php occ check

# Show current Redis configuration
docker compose exec -u www-data app php occ config:system:get redis

The occ check command lists all detected configuration issues. It is the first diagnostic to run on any existing Nextcloud instance.

Nextcloud Backups — Data, Database and Config

Nextcloud stores data in three places — all three must be backed up:

1. MariaDB database: file metadata, users, shares, installed apps.
2. nextcloud volume: PHP code, installed apps, and config/config.php.
3. User files: default in the Docker volume or in the path set by datadirectory in config.php.

# Enable maintenance mode for consistency
docker compose exec -u www-data app php occ maintenance:mode --on
# Backup the database
docker compose exec -T db mysqldump -u nextcloud -p${MYSQL_PASSWORD} nextcloud | gzip > /opt/nextcloud/backups/db-$(date +%Y%m%d).sql.gz
# Disable maintenance mode
docker compose exec -u www-data app php occ maintenance:mode --off

Update Nextcloud in Production

Always run updates with maintenance mode enabled to prevent data corruption during synchronization:

# Enable maintenance mode
docker compose exec -u www-data app php occ maintenance:mode --on
# Update image tag in docker-compose.yml
sed -i 's|nextcloud:[0-9.]*-apache|nextcloud:34.0.2-apache|g' docker-compose.yml
# Pull new image and restart
docker compose pull app && docker compose up -d app
# Run migrations
docker compose exec -u www-data app php occ upgrade
# Disable maintenance mode
docker compose exec -u www-data app php occ maintenance:mode --off

Next Steps — Go Further with Your Instance

Once Nextcloud is installed and secured:

Enable Talk (video conferencing): install the Nextcloud Talk app from the admin interface. For meetings with more than 4–5 participants, a TURN server is required (Coturn on a dedicated VPS).

Enable OnlyOffice or Collabora Online: these apps require their own Docker container and Nextcloud Office configuration. They allow creating and editing .docx, .xlsx, and .pptx files directly in the web interface.

Monitor your instance: configure alerts in Administration → Monitoring to receive email notifications if Nextcloud detects configuration errors, security updates, or quota issues.

A Reliable VPS for Your Nextcloud Instance

Nextcloud needs an SSD VPS with good bandwidth for smooth file synchronization. Our VPS Cloud plans start at 2 GB RAM with daily snapshots — exactly what a stress-free Nextcloud instance needs.

Need help?

Browse our help center and FAQ, or reach our team — callback, WhatsApp or email. Support in French, English and Arabic.