← Back to Blog

How to Self-Host Nextcloud on a VPS (Ubuntu 24.04)

Published May 2, 2026  ·  12 min read  ·  Dakota Hopson, Galaxy Cloud Solutions

I've had a lot of customers ask about running Nextcloud on a VPS. It's one of those things where self-hosting makes a lot of sense — you get full control over your files, no monthly subscription to a cloud storage provider, and you know exactly where your data is. For a small team or personal use, a $10/mo VPS running Nextcloud beats a $10/mo Dropbox subscription in almost every way.

This guide sets up Nextcloud on Ubuntu 24.04 with Nginx, PHP 8.3, MySQL, and Let's Encrypt SSL. It's a bit longer than the other guides but the end result is worth it.

⚡ Need a VPS? The Nebula 2 plan (2GB RAM) is perfect for Nextcloud — Use code LAUNCH2026 for 50% off

What Plan Do You Need?

Storage is the other consideration. Our plans include 20-320GB SSD. If you need more, you can always add block storage later.

Step 1 — Update and Install Dependencies

apt update && apt upgrade -y
apt install nginx mysql-server php8.3-fpm php8.3-mysql php8.3-xml php8.3-curl php8.3-gd php8.3-mbstring php8.3-zip php8.3-intl php8.3-bcmath php8.3-imagick php8.3-redis unzip wget -y

Step 2 — Configure MySQL

mysql_secure_installation
mysql -u root -p
CREATE DATABASE nextcloud CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
CREATE USER 'nextclouduser'@'localhost' IDENTIFIED BY 'your_strong_password';
GRANT ALL PRIVILEGES ON nextcloud.* TO 'nextclouduser'@'localhost';
FLUSH PRIVILEGES;
EXIT;

Step 3 — Download Nextcloud

cd /var/www
wget https://download.nextcloud.com/server/releases/latest.tar.bz2
tar -xjf latest.tar.bz2
chown -R www-data:www-data nextcloud
rm latest.tar.bz2

Step 4 — Configure PHP

Nextcloud needs a few PHP settings adjusted:

nano /etc/php/8.3/fpm/php.ini

Find and update these values:

memory_limit = 512M
upload_max_filesize = 16G
post_max_size = 16G
max_execution_time = 360
output_buffering = Off

Restart PHP-FPM:

systemctl restart php8.3-fpm

Step 5 — Configure Nginx

cat > /etc/nginx/sites-available/nextcloud << 'NGINXEOF'
server {
    listen 80;
    server_name yourdomain.com;
    root /var/www/nextcloud;
    index index.php index.html;

    client_max_body_size 16G;
    fastcgi_buffers 64 4K;

    add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload" always;
    add_header Referrer-Policy "no-referrer" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-Download-Options "noopen" always;
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Permitted-Cross-Domain-Policies "none" always;
    add_header X-Robots-Tag "none" always;
    add_header X-XSS-Protection "1; mode=block" always;

    location = /robots.txt { allow all; log_not_found off; access_log off; }
    location = /.well-known/carddav { return 301 $scheme://$host:$server_port/remote.php/dav; }
    location = /.well-known/caldav { return 301 $scheme://$host:$server_port/remote.php/dav; }

    location / {
        rewrite ^ /index.php;
    }

    location ~ ^\/(?:build|tests|config|lib|3rdparty|templates|data)\/ { deny all; }
    location ~ ^\/(?:\.|autotest|occ|issue|indie|db_|console) { deny all; }

    location ~ ^\/(?:index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-provider\/.+)\.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 unix:/var/run/php/php8.3-fpm.sock;
        fastcgi_intercept_errors on;
        fastcgi_request_buffering off;
    }

    location ~ ^\/(?:updater|oc[ms]-provider)(?:$|\/) { try_files $uri/ =404; index index.php; }
    location ~ \.(?:css|js|woff2?|svg|gif|map)$ { try_files $uri /index.php$request_uri; add_header Cache-Control "public, max-age=15778463"; }
    location ~ \.(?:png|html|ttf|ico|jpg|jpeg|bcmap)$ { try_files $uri /index.php$request_uri; }
}
NGINXEOF

ln -s /etc/nginx/sites-available/nextcloud /etc/nginx/sites-enabled/
nginx -t && systemctl reload nginx

Step 6 — Add SSL

apt install certbot python3-certbot-nginx -y
certbot --nginx -d yourdomain.com

Step 7 — Complete the Installation

Visit https://yourdomain.com in your browser. You'll see the Nextcloud setup wizard. Enter:

Click Install. It takes a minute or two. When it's done, Nextcloud is live.

Step 8 — Set Up the Cron Job

Nextcloud needs a cron job to handle background tasks:

crontab -u www-data -e

Add this line:

*/5  *  *  *  * php -f /var/www/nextcloud/cron.php
Mobile apps: Download the Nextcloud app on iOS or Android, enter your server URL, and log in. File sync works exactly like Dropbox or Google Drive — just on your own server.

Run Nextcloud on your own server from $10/mo

The Nebula 2 plan (2GB RAM, 40GB SSD) is a solid starting point for personal Nextcloud use. Full root access, Ubuntu 24.04, instant deployment. Use code LAUNCH2026 for 50% off your first month.

Get Started