
Nextcloud on Linux: Self-Hosted File Cloud with Collabora Office
- AuthorTimothy M.
- Date
- Time29 minutes
Nextcloud is the leading open-source alternative to Dropbox, Google Drive, and OneDrive. It provides file sync, sharing, calendar, contacts, and collaborative document editing — all on infrastructure you control. For teams that handle sensitive data or want to avoid cloud vendor lock-in, Nextcloud on a dedicated Linux server is a proven production solution.
This guide installs Nextcloud with the recommended stack: Nginx, PHP-FPM 8.3, MariaDB, and Valkey/Redis for transactional file locking and memory caching. We also integrate Collabora Online for browser-based document editing and cover backup, security, and performance tuning.
Hardware Recommendations
- Small team (1–10 users) — 4 CPU, 8 GB RAM, 100 GB SSD
- Medium team (10–50 users) — 8 CPU, 16 GB RAM, 500 GB+ SSD
- Storage — separate data volume mounted at /mnt/nc-data
Step 1: Install Dependencies
sudo apt update
sudo apt install -y nginx mariadb-server valkey \\
php8.3-fpm php8.3-gd php8.3-mysql php8.3-curl php8.3-mbstring \\
php8.3-xml php8.3-zip php8.3-intl php8.3-bcmath php8.3-gmp \\
php8.3-redis php8.3-imagick php8.3-apcu unzip
sudo systemctl enable nginx mariadb valkey php8.3-fpmStep 2: Create Database
sudo mysql <<'SQL'
CREATE DATABASE nextcloud CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
CREATE USER 'nc_user'@'localhost' IDENTIFIED BY 'REPLACE_STRONG_PASSWORD';
GRANT ALL PRIVILEGES ON nextcloud.* TO 'nc_user'@'localhost';
FLUSH PRIVILEGES;
SQLStep 3: Download and Install Nextcloud
cd /tmp
curl -LO https://download.nextcloud.com/server/releases/latest.zip
unzip latest.zip
sudo mv nextcloud /var/www/
sudo mkdir -p /mnt/nc-data
sudo chown -R www-data:www-data /var/www/nextcloud /mnt/nc-dataStep 4: Nginx Configuration
sudo tee /etc/nginx/sites-available/nextcloud.conf >/dev/null <<'EOF'
upstream php-handler {
server unix:/run/php/php8.3-fpm.sock;
}
server {
listen 443 ssl http2;
server_name cloud.example.com;
root /var/www/nextcloud;
ssl_certificate /etc/letsencrypt/live/cloud.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/cloud.example.com/privkey.pem;
client_max_body_size 10G;
fastcgi_buffers 64 4K;
add_header Strict-Transport-Security "max-age=15552000" always;
add_header Referrer-Policy "no-referrer" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
location ^~ /.well-known {
allow all;
try_files $uri $uri/ =404;
}
location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/) {
deny all;
}
location / {
rewrite ^ /index.php$request_uri;
}
location ~ ^\\/(?:index|remote|public|cron|core\\/ajax\\/update|status|ocs\\/v[12]|updater\\/.+|oc[ms]\\-.+\\.php)\\.php(?:$|\\/) {
fastcgi_split_path_info ^(.+?\\.php)(\\/.*|)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param modHeadersAvailable true;
fastcgi_param front_controller_active true;
fastcgi_pass php-handler;
fastcgi_intercept_errors on;
fastcgi_request_buffering off;
}
location ~ \\.(?:css|js|svg|gif|png|jpg|ico|wasm|tflite|map|ogg|flac)$ {
try_files $uri /index.php$request_uri;
expires 6M;
access_log off;
}
}
EOF
sudo ln -s /etc/nginx/sites-available/nextcloud.conf /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginxStep 5: Run Web Installer or occ CLI
sudo -u www-data php /var/www/nextcloud/occ maintenance:install \\
--database mysql \\
--database-name nextcloud \\
--database-user nc_user \\
--database-pass 'REPLACE_STRONG_PASSWORD' \\
--admin-user admin \\
--admin-pass 'REPLACE_ADMIN_PASSWORD' \\
--data-dir /mnt/nc-dataStep 6: Configure Redis Caching and File Locking
sudo -u www-data php /var/www/nextcloud/occ config:system:set memcache.local --value '\\OC\\Memcache\\APCu'
sudo -u www-data php /var/www/nextcloud/occ config:system:set memcache.distributed --value '\\OC\\Memcache\\Redis'
sudo -u www-data php /var/www/nextcloud/occ config:system:set memcache.locking --value '\\OC\\Memcache\\Redis'
sudo -u www-data php /var/www/nextcloud/occ config:system:set redis host --value '127.0.0.1'
sudo -u www-data php /var/www/nextcloud/occ config:system:set redis port --value 6379Step 7: Enable Background Jobs via Cron
sudo -u www-data php /var/www/nextcloud/occ background:cron
echo "*/5 * * * * www-data php -f /var/www/nextcloud/cron.php" | sudo tee /etc/cron.d/nextcloudStep 8: Add Collabora Online (Document Editing)
# Deploy Collabora CODE via Docker:
sudo docker run -d --name collabora \\
-p 127.0.0.1:9980:9980 \\
-e "domain=cloud\\.example\\.com" \\
--restart unless-stopped \\
collabora/code
# Install Nextcloud Office app:
sudo -u www-data php /var/www/nextcloud/occ app:install richdocuments
sudo -u www-data php /var/www/nextcloud/occ config:app:set richdocuments wopi_url --value="https://office.example.com"Step 9: Security and Performance Tuning
# Enable HSTS and security headers (done in Nginx config above)
sudo -u www-data php /var/www/nextcloud/occ config:system:set overwrite.cli.url --value='https://cloud.example.com'
sudo -u www-data php /var/www/nextcloud/occ config:system:set default_phone_region --value='DE'
sudo -u www-data php /var/www/nextcloud/occ config:system:set maintenance_window_start --value=3
# Run security scan:
sudo -u www-data php /var/www/nextcloud/occ security:bruteforce:resetStep 10: Backup Strategy
#!/usr/bin/env bash
# /usr/local/bin/nextcloud-backup.sh
set -euo pipefail
mysqldump --single-transaction nextcloud | gzip > /backup/nc-db-$(date +%F).sql.gz
rsync -a /mnt/nc-data/ /backup/nc-data/
rsync -a /var/www/nextcloud/config/ /backup/nc-config/Production Checklist
- Run occ status after setup — all checks should be green.
- Enable server-side encryption for sensitive deployments.
- Configure brute-force protection and fail2ban/CrowdSec.
- Set up automated backups for database and data directory.
- Keep Nextcloud updated via occ upgrade on a maintenance schedule.
"Self-hosted file sync only wins when backups, Redis locking, and cron jobs are production-grade — otherwise you traded one cloud risk for a different one."



