Self-hosting Nextcloud on a VPS
Self-hosting Nextcloud on a VPS gives you private file storage and sync under your control. This guide covers installing the web stack, database and Nextcloud code, adding HTTPS, and the backups and maintenance you are responsible for compared with a managed service.
Self-hosting Nextcloud on a VPS
You can run your own Nextcloud on a VPS and get private file storage and sync under your control. You install the web stack, database and Nextcloud code, then add HTTPS and schedule background tasks. You also take on backups, upgrades and watching disk usage.
This picks up from a server you can already reach over SSH. If you are using our VPS, you can power cycle or open a VNC console in Virtualizor from the Hostworld client area if you need to recover access.
Before you start
- A Hostworld VPS or another Linux VPS you control. Our UK range is at Linux VPS. This guide covers AlmaLinux 9 and Ubuntu 24.04 LTS.
- A domain name pointed at the VPS. Certbot needs a resolvable domain and a working HTTP site for the certificate challenge.
- The database choice you will make. Nextcloud lists PostgreSQL or MariaDB as recommended. SQLite is only for testing and minimal instances.
- A storage plan. Nextcloud writes uploads to temporary
.partfiles before finalising them, keeps deleted files in Trash for a time, stores versions of files and generates previews indata/appdata_<instanceid>/preview. All of that uses disk. Set quotas and retention so you do not run out of space without warning. - A security plan. The Admin Manual recommends placing the data directory outside the web root. You can also put the config directory outside the web root by setting
NEXTCLOUD_CONFIG_DIRfor both web and CLI. - A backup plan you have tested. You need code, config, data and database in your backups.
If anything here is unclear, open a support ticket and we will help you get started.
Step 1: Decide your stack and where files will live
Decide which OS you will use, which database engine you will install, and where the Nextcloud code and data directories will live. The official example for Ubuntu 24.04 uses Apache and MariaDB. The Nextcloud docs provide a full, supported NGINX + PHP‑FPM configuration as well. This guide will use Apache on Ubuntu and NGINX + PHP‑FPM on AlmaLinux. In both cases place your data directory outside the document root, for example under /var/nextcloud-data.
Step 2: Install a web server and PHP
Ubuntu 24.04 LTS
This updates package indexes, then installs Apache, PHP 8.3 and PHP modules used by Nextcloud. php-bcmath and php-gmp are on Nextcloud's recommended list rather than the required one, and they are cheap to install now.
sudo apt update
sudo apt install apache2 libapache2-mod-php php php-xml php-mbstring php-zip php-intl php-gd php-curl php-bcmath php-gmp php-mysql php-pgsql
This enables and starts Apache so your site can serve HTTP.
sudo systemctl enable --now apache2
AlmaLinux 9
This shows available PHP module streams, enables the PHP 8.2 stream, then installs NGINX, PHP‑FPM and PHP modules used by Nextcloud. Note php-curl: that is the PHP extension Nextcloud's requirements check looks for. The curl package on its own is the command line tool and will not satisfy it.
sudo dnf module list php
sudo dnf module enable php:8.2
sudo dnf install nginx php php-fpm php-cli php-xml php-mbstring php-zip php-intl php-gd php-mysqlnd php-curl php-bcmath php-gmp
Now deal with a mismatch that catches people out. The default PHP‑FPM pool on AlmaLinux and other RHEL rebuilds runs as the user apache, not nginx. If you hand the files to nginx later and leave the pool alone, PHP cannot write to the data directory and the installer fails with permission errors that look like a file ownership problem. Pick one user and use it consistently. This guide uses nginx.
Open the pool configuration at /etc/php-fpm.d/www.conf in an editor and change the two lines that set the pool user and group so they read:
user = nginx
group = nginx
This enables and starts NGINX and PHP‑FPM so your site can serve HTTP and execute PHP.
sudo systemctl enable --now nginx php-fpm
Step 3: Install MariaDB
Nextcloud recommends PostgreSQL or MariaDB. This step installs MariaDB, which is used in the Ubuntu example. If you prefer PostgreSQL, follow the Nextcloud database notes for that engine and ensure it is available to PHP.
Ubuntu 24.04 LTS
This installs the MariaDB server, then enables and starts it.
sudo apt install mariadb-server
sudo systemctl enable --now mariadb
AlmaLinux 9
This installs the MariaDB server, then enables and starts it.
sudo dnf install mariadb-server
sudo systemctl enable --now mariadb
Nextcloud requires InnoDB and transaction isolation level READ‑COMMITTED on MySQL or MariaDB, and a utf8mb4 character set. It also expects the server collation to be a utf8mb4 variant. The database configuration page states that utf8mb4 and collation_server=utf8mb4_bin with READ‑COMMITTED are required. Set these at server level in your MariaDB configuration before going into production.
Be careful if you follow any “4‑byte support” conversion steps on an existing database. Back up first and confirm the target charset and collation match your goal before running ALTERs.
Step 4: Create a Nextcloud database and user
This connects to MariaDB, then creates a database with utf8mb4 using a binary collation, a user and the privileges that user needs.
Before you run any of it, replace strong_password_here with a long random password that you have generated yourself. Do not paste the block as written. A production database whose user password is a literal placeholder from a guide is an open door, and it is the kind of thing nobody goes back and fixes.
sudo mysql -u root
CREATE DATABASE nextcloud CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
CREATE USER 'ncuser'@'localhost' IDENTIFIED BY 'strong_password_here';
GRANT ALL PRIVILEGES ON nextcloud.* TO 'ncuser'@'localhost';
FLUSH PRIVILEGES;
EXIT;
Keep the database name, username and password. You will enter them in the Nextcloud installer.
Step 5: Download Nextcloud and prepare directories
This creates a code directory under /var/www and a data directory outside the web root, then downloads the current Nextcloud release and verifies it before extracting. The Admin Manual’s Ubuntu 24.04 example shows these steps and the exact filenames, and is the source of truth if anything below changes.
Ubuntu 24.04 LTS and AlmaLinux 9
This creates folders for the code and data.
sudo mkdir -p /var/www/nextcloud
sudo mkdir -p /var/nextcloud-data
This installs the tools needed to download and unpack the release. Run the line for your OS, not both.
On Ubuntu:
sudo apt install -y wget tar bzip2
On AlmaLinux:
sudo dnf install -y wget tar bzip2
This downloads the latest release and its checksum file, verifies the checksum, then extracts the archive to /var/www. If the checksum does not verify, stop and download again rather than extracting.
cd /var/www
sudo wget https://download.nextcloud.com/server/releases/latest.tar.bz2
sudo wget https://download.nextcloud.com/server/releases/latest.tar.bz2.sha256
sha256sum -c latest.tar.bz2.sha256
sudo tar -xjf latest.tar.bz2
sudo rm latest.tar.bz2 latest.tar.bz2.sha256
This sets ownership so your web server can read the code and write to the data directory.
Ubuntu 24.04 LTS
sudo chown -R www-data:www-data /var/www/nextcloud /var/nextcloud-data
AlmaLinux 9
This gives the files to nginx, which matches the PHP‑FPM pool user you set in step 2. If you chose to leave the pool running as apache instead, use apache:apache here. What matters is that the two agree.
sudo chown -R nginx:nginx /var/www/nextcloud /var/nextcloud-data
Ownership is not the whole story on AlmaLinux. SELinux runs in enforcing mode by default, and your data directory sits outside /var/www with no web server label on it, so NGINX and PHP‑FPM will be refused access no matter who owns the files. This installs the SELinux management tools, labels the directories the web server has to write to, then applies the labels.
sudo dnf install -y policycoreutils-python-utils
sudo semanage fcontext -a -t httpd_sys_rw_content_t '/var/nextcloud-data(/.*)?'
sudo semanage fcontext -a -t httpd_sys_rw_content_t '/var/www/nextcloud/config(/.*)?'
sudo semanage fcontext -a -t httpd_sys_rw_content_t '/var/www/nextcloud/apps(/.*)?'
sudo restorecon -R /var/nextcloud-data /var/www/nextcloud
Do not turn SELinux off to get past a permission error. It is the quickest way to make the symptom disappear and the worst thing to leave behind on a server holding your files. If access is still denied after labelling, read the denial in the audit log and fix the label it names. Nextcloud's hardening documentation covers SELinux settings in more depth, including the ones you may need for external storage or sending mail.
For non‑Apache servers, the Admin Manual advises installing outside the document root. If you use NGINX, follow the official NGINX reference configuration so NGINX serves Nextcloud correctly without relying on .htaccess.
You can optionally move your Nextcloud config directory outside the web root by setting NEXTCLOUD_CONFIG_DIR. If you do that, set it for both your web server process and for CLI, so occ commands see the same config.
Step 6: Configure the web server
Ubuntu 24.04 LTS (Apache)
Follow Nextcloud’s Apache guidance. It documents the required directives, Pretty URLs, and other hardening. Point your virtual host at /var/www/nextcloud as the document root, apply the settings in the Admin Manual, then reload Apache.
sudo systemctl reload apache2
AlmaLinux 9 (NGINX + PHP‑FPM)
Use the authoritative NGINX + PHP‑FPM configuration from the Admin Manual. It defines an upstream php‑handler, the correct rewrites and the security headers Nextcloud expects. Do not copy Apache or .htaccess rules into NGINX. Place the provided server block in your NGINX configuration, adjust the root to /var/www/nextcloud and the fastcgi_pass to match your PHP‑FPM socket, then test and reload NGINX.
sudo nginx -t
sudo systemctl reload nginx
If you changed the PHP‑FPM pool user in step 2, restart PHP‑FPM as well so the change takes effect.
sudo systemctl restart php-fpm
Step 7: Run the Nextcloud installer
Browse to your domain over HTTP. The installation wizard will ask for an admin username and password, then for your database connection. Use the database, user and password you created. The Admin Manual’s installation wizard page shows each prompt if you want to preview it.
After installation, set the canonical host name for CLI and cron jobs. Add your domain to trusted_domains and set overwrite.cli.url in config.php so links generated by occ and background jobs point at the right base URL.
Step 8: Enable HTTPS
Only do this after your domain resolves to the VPS and the site works over HTTP. Certbot needs to reach the HTTP virtual host to complete the challenge.
Ubuntu 24.04 LTS
This installs Certbot with the Apache plugin, then obtains and installs a certificate for your domain and reloads Apache. Replace the example domain with your real domain.
sudo apt install certbot python3-certbot-apache
sudo certbot --apache -d cloud.example.com
With the Apache plugin, renewals trigger an automatic reload after a successful renewal.
AlmaLinux 9
This installs Certbot from EPEL with the NGINX plugin, then obtains and installs a certificate for your domain and reloads NGINX. Replace the example domain with your real domain.
sudo dnf install epel-release
sudo dnf install certbot python3-certbot-nginx
sudo certbot --nginx -d cloud.example.com
Step 9: Set background jobs to Cron
Nextcloud recommends Cron. You can set this in the admin UI, or with occ, then schedule the job to run every five minutes under the same user PHP runs as.
Ubuntu 24.04 LTS
This tells Nextcloud to use Cron for background jobs.
sudo -u www-data php /var/www/nextcloud/occ background:cron
This opens the crontab editor for the web server user so you can add the job.
sudo crontab -u www-data -e
Add this line to run the Nextcloud cron every five minutes.
*/5 * * * * php -f /var/www/nextcloud/cron.php
AlmaLinux 9
Use the same user as your PHP‑FPM pool and your file ownership, which in this guide is nginx. This tells Nextcloud to use Cron for background jobs.
sudo -u nginx php /var/www/nextcloud/occ background:cron
This opens the crontab editor for that user so you can add the job.
sudo crontab -u nginx -e
Add this line to run the Nextcloud cron every five minutes.
*/5 * * * * php -f /var/www/nextcloud/cron.php
Not enabling Cron leaves background tasks unprocessed. That causes stale file locks, preview backlogs and unpredictable spikes later. Do this before putting users on the system.
Step 10: Configure caching
Nextcloud recommends APCu as the local memory cache and Redis for transactional file locking. Do not use Memcached for locking. When Redis runs locally, using a UNIX socket is recommended. The Admin Manual shows the config.php entries for APCu and Redis. Follow those and restart your web server. If you cannot install the PHP Redis module, the docs point to KeyValueCache as an alternative for some cache uses, but Redis is still required for file locking.
Step 11: Size storage, quotas and large uploads
- Quotas. Set user quotas so usage stays within limits you expect. When a user’s quota is exceeded, uploads can fail with “Insufficient space”.
- Trash and Versions. The Trash bin app has minimum and maximum retention controls. The default is auto. Versions are pruned automatically so users do not exceed their quotas. Tune retention so space is not tied up for too long.
- Previews. Thumbnails go under
data/appdata_<instanceid>/previewand can grow large. The Admin Manual provides preview configuration and server‑tuning guidance, including using the Imaginary microservice if suitable. Note that Imaginary is not compatible with server‑side encryption. - Uploads. Nextcloud writes incoming data to temporary
.partfiles before renaming. Leave headroom for files in flight. Large uploads may also need PHP limits raised. The big file upload guide lists the PHP settings to increase, and shows how to tune the chunk size viaocc.
Step 12: Keep it maintained
- Updates. Use the built‑in updater to replace the code, then run
occ upgrade. The updater can run in batch mode withupdater.phar --no‑interaction. Ifocc upgradereports “up to date” but you still see an upgrade prompt, it means code replacement has not run yet. The updater will ask whether to keep maintenance mode active. Only turn it off after a successful upgrade. - Backups. Back up code, config, data and the database. The Admin Manual documents restores and the official material stresses having a tested backup and restore routine in place before upgrades.
- Requirements. New releases can drop old PHP or database versions. For example, Nextcloud 30 drops PHP 8.0, deprecates 8.1, and drops some older database releases. Check the release notes before upgrading.
- Web server config. If you run NGINX, use the reference configuration. Do not rely on
.htaccess. For Apache, follow the documented directives and Pretty URLs guidance.
What next
If you want a clean slate to deploy this on, our UK range is here: Linux VPS. For broader context on running services on a VPS, browse our VPS guides.
If you get stuck at any point, the fastest way to reach us with full account context is to open a support ticket.
Common questions
Should I use PostgreSQL or MariaDB?
Both are recommended in the Admin Manual. PostgreSQL is listed as recommended on the system requirements page. If your team is already comfortable with MariaDB, that is also fine. If you choose MySQL or MariaDB, set transaction isolation to READ‑COMMITTED and use utf8mb4 with a utf8mb4 collation on the server, with InnoDB as the storage engine. Avoid SQLite for anything beyond testing.
How big should the disk be, and what happens when it fills?
Plan for user files plus overhead. Trash and Versions keep copies for a period, previews can grow under appdata.../preview, and uploads use temporary .part files. When quotas are exceeded, uploads can fail with “Insufficient space”. When the partition itself is tight, even temporary files can fail. Set user quotas, tune Trash and Versions retention, and monitor free space. The Admin Manual shows the controls for Trash and Previews.
Do I need Redis?
Yes for file locking. Nextcloud’s guidance is clear that Memcached must not be used for transactional locking. Use APCu for the local memory cache and Redis for locks. If Redis is local, use a UNIX socket.
Can I move the data directory later?
Be careful. Changing datadirectory in config.php or moving files by hand can make Nextcloud treat the storage as new, which breaks the file cache, shares, tags and activity history. Use the documented migration procedure if you must move it, and back up first.
How do I keep HTTPS working?
On Ubuntu, install Certbot with the Apache plugin and run it against your domain. On AlmaLinux, install the EPEL Certbot packages and use the NGINX plugin. Certbot renews certificates automatically and reloads the service when you use those plugins. Do not run Certbot until the domain resolves to your VPS and plain HTTP works, or issuance will fail.