How to: Install Nextcloud with an NFS data directory
This article describes how to install Nextcloud Server on Ubuntu 26.04 LTS. Apache with PHP-FPM is used as the web server, while MariaDB provides the required database.
The actual Nextcloud user data is stored on an NFS-mounted storage system. The NFS storage is used as the primary Nextcloud data directory and is not integrated through the Nextcloud “External Storage” app.
This guide uses the following example values:
- Nextcloud address:
cloud.example.com - NFS server:
nfs.example.com - NFS export:
/nextcloud - Local NFS mount point:
/srv/nextcloud-data - Nextcloud directory:
/var/www/nextcloud - Database name:
nextcloud - Database user:
nextcloud
Adjust these values to match your environment.
Note: In this setup, the NFS storage is part of the primary Nextcloud storage. If the NFS server is unavailable, the Nextcloud data directory will also be unavailable.
Requirements
The following components are required for this guide:
- Ubuntu Server 26.04 LTS, 64-bit
- Apache 2.4
- PHP 8.5 with PHP-FPM
- MariaDB 11.8
- Redis
- An accessible NFSv4 export
- A DNS record for the Nextcloud domain
- TCP ports 80 and 443 must be reachable
For a small installation, the following resources can be used as an example:
- 4 vCPUs
- 4 GiB RAM
- At least 20 GiB of local storage for the operating system, Nextcloud application, database and logs
- Separate storage for the Nextcloud data directory
The actual resource requirements depend on factors such as the number of users, installed apps, number of files and concurrent access.
Important: NFS storage does not replace a backup. A complete backup must include at least the Nextcloud data directory, the MariaDB database and the Nextcloud configuration.
Preparing the system
The following commands are executed as the root user.
First update the operating system:
apt update apt full-upgrade -y
If a new kernel was installed, restart the system:
reboot
Then verify the installed Ubuntu version:
cat /etc/os-release
The output should contain the following information, among other values:
VERSION_ID="26.04" VERSION_CODENAME=resolute
Installing the required packages
Install Apache, MariaDB, PHP 8.5, Redis and the required PHP extensions:
apt install -y \
apache2 \
mariadb-server \
php8.5-fpm \
php8.5-cli \
php8.5-common \
php8.5-curl \
php8.5-gd \
php8.5-gmp \
php8.5-imagick \
php8.5-intl \
php8.5-mbstring \
php8.5-mysql \
php8.5-xml \
php8.5-zip \
php8.5-bcmath \
php8.5-bz2 \
php8.5-apcu \
php8.5-redis \
redis-server \
nfs-common \
cron \
bzip2 \
wget
Enable and start the required services:
systemctl enable --now \
apache2 \
mariadb \
php8.5-fpm \
redis-server \
cron
Verify the installed PHP version:
php8.5 --version
The output should begin with PHP 8.5.
The loaded PHP modules can be checked with the following command:
php8.5 -m
The following modules should be present, among others:
apcu curl dom fileinfo gd gmp imagick intl mbstring mysqli openssl pdo_mysql redis SimpleXML xml xmlreader xmlwriter zip
Configuring PHP 8.5
Nextcloud requires suitable PHP settings for both PHP-FPM and command-line PHP calls.
Configuring PHP-FPM
Create a dedicated PHP configuration file for Nextcloud:
nano /etc/php/8.5/fpm/conf.d/99-nextcloud.ini
Add the following configuration:
memory_limit = 512M upload_max_filesize = 10G post_max_size = 10G max_execution_time = 3600 max_input_time = 3600 output_buffering = 0
The values for upload_max_filesize and post_max_size determine the maximum file size that can be uploaded through the web interface. Adjust these values to suit your environment if required.
Configuring PHP CLI
The PHP command-line interface is used for cron jobs, maintenance tasks and the Nextcloud updater.
Create the following configuration file:
nano /etc/php/8.5/cli/conf.d/99-nextcloud.ini
Add the following content:
memory_limit = 512M apc.enable_cli = 1
Verify the configuration:
php8.5 --ini php8.5 -i | grep -E 'memory_limit|apc.enable_cli'
Restart PHP-FPM:
systemctl restart php8.5-fpm
Check the service status:
systemctl status php8.5-fpm
Setting up the NFS data directory
Creating the mount point
Create the local mount point:
mkdir -p /srv/nextcloud-data
Configuring the NFS mount
Add the following line to /etc/fstab:
nfs.example.com:/nextcloud /srv/nextcloud-data nfs4 rw,hard,_netdev,x-systemd.automount 0 0
Adjust the NFS server and export path to match your environment.
Reload the systemd configuration:
systemctl daemon-reload
Access the mount point to trigger the automatic mount:
ls -la /srv/nextcloud-data
Alternatively, the mount can be triggered manually:
mount /srv/nextcloud-data
Verify that the NFS file system has been mounted:
findmnt /srv/nextcloud-data
Example:
TARGET SOURCE FSTYPE OPTIONS /srv/nextcloud-data nfs.example.com:/nextcloud nfs4 rw,relatime,...
Only continue with the installation if /srv/nextcloud-data is actually mounted as an NFS file system.
Setting permissions
Apache and PHP-FPM run as the www-data user by default on Ubuntu.
Check its UID and GID:
id www-data
By default, Ubuntu uses UID and GID 33 for www-data.
The NFS directory must allow the www-data user to write to it. If NFS root_squash is enabled, ownership usually cannot be changed from the Nextcloud server. In this case, set the permissions directly on the NFS server.
Example on the NFS server:
chown -R 33:33 /path/to/export/nextcloud chmod 0750 /path/to/export/nextcloud
Then perform a write test on the Nextcloud server as the www-data user:
sudo -u www-data touch /srv/nextcloud-data/.write-test sudo -u www-data rm /srv/nextcloud-data/.write-test
If this test fails, correct the NFS export settings, UID/GID mapping or file system permissions before continuing.
Note: The data directory should be used exclusively by Nextcloud. Files should not be modified directly on the NFS share in parallel.
Making Apache and PHP-FPM depend on the NFS mount
To prevent the relevant services from starting without the data directory being available, systemd dependencies can be configured.
First create a dependency for Apache:
systemctl edit apache2
Add the following configuration:
[Unit] RequiresMountsFor=/srv/nextcloud-data Wants=network-online.target After=network-online.target
Then create the corresponding dependency for PHP-FPM:
systemctl edit php8.5-fpm
Add the following configuration there as well:
[Unit] RequiresMountsFor=/srv/nextcloud-data Wants=network-online.target After=network-online.target
Reload the systemd configuration:
systemctl daemon-reload
Check the configured dependencies:
systemctl cat apache2 systemctl cat php8.5-fpm
Configuring MariaDB
Setting the transaction isolation level
Nextcloud requires the READ-COMMITTED transaction isolation level for MySQL or MariaDB.
Create the following configuration file:
nano /etc/mysql/mariadb.conf.d/99-nextcloud.cnf
Add the following content:
[mysqld] transaction-isolation = READ-COMMITTED
If MariaDB binary logging is enabled, the ROW format must also be used:
[mysqld] transaction-isolation = READ-COMMITTED binlog_format = ROW
Restart MariaDB:
systemctl restart mariadb
Verify the configured transaction isolation level:
mariadb -e "SHOW VARIABLES LIKE 'transaction_isolation';"
The output should contain the following value:
READ-COMMITTED
Creating the database and user
Open the MariaDB console:
mariadb
Create the database and a database user that can only connect locally:
CREATE DATABASE nextcloud
CHARACTER SET utf8mb4
COLLATE utf8mb4_general_ci;
CREATE USER 'nextcloud'@'localhost'
IDENTIFIED BY 'SECURE-DATABASE-PASSWORD';
GRANT ALL PRIVILEGES
ON nextcloud.*
TO 'nextcloud'@'localhost';
FLUSH PRIVILEGES;
EXIT;
Replace SECURE-DATABASE-PASSWORD with a long, random password used exclusively for this database.
Because MariaDB and Nextcloud are installed on the same server, the user is deliberately restricted to localhost.
Test the login:
mariadb -u nextcloud -p -h localhost nextcloud
Exit the MariaDB console afterwards:
EXIT;
Installing Nextcloud
At the time this article was created, Nextcloud 34.0.1 was the current stable version.
Before performing a later installation, check whether a newer version is available within the supported Nextcloud release branch.
Download the Nextcloud archive and the corresponding SHA-256 checksum:
cd /tmp
NEXTCLOUD_VERSION="34.0.1"
wget https://download.nextcloud.com/server/releases/nextcloud-${NEXTCLOUD_VERSION}.tar.bz2
wget https://download.nextcloud.com/server/releases/nextcloud-${NEXTCLOUD_VERSION}.tar.bz2.sha256
Verify the integrity of the archive:
sha256sum -c nextcloud-${NEXTCLOUD_VERSION}.tar.bz2.sha256
The output must contain OK:
nextcloud-34.0.1.tar.bz2: OK
Extract Nextcloud:
tar -xjf nextcloud-${NEXTCLOUD_VERSION}.tar.bz2
mv nextcloud /var/www/nextcloud
Set the owner:
chown -R www-data:www-data /var/www/nextcloud
Check the permissions:
ls -ld /var/www/nextcloud
After a successful installation, the downloaded archive files can optionally be removed:
rm -f /tmp/nextcloud-${NEXTCLOUD_VERSION}.tar.bz2
rm -f /tmp/nextcloud-${NEXTCLOUD_VERSION}.tar.bz2.sha256
Configuring Apache with PHP-FPM
This guide uses a dedicated subdomain for Nextcloud:
cloud.example.com
Enable the required Apache modules:
a2enmod \
proxy_fcgi \
setenvif \
rewrite \
headers \
env \
dir \
mime \
ssl \
http2
Enable the PHP 8.5 FPM configuration:
a2enconf php8.5-fpm
Create the Apache configuration:
nano /etc/apache2/sites-available/nextcloud.conf
Add the following configuration:
<VirtualHost *:80>
ServerName cloud.example.com
DocumentRoot /var/www/nextcloud
<Directory /var/www/nextcloud/>
Require all granted
AllowOverride All
Options FollowSymLinks
<IfModule mod_dav.c>
Dav off
</IfModule>
SetEnv HOME /var/www/nextcloud
SetEnv HTTP_HOME /var/www/nextcloud
</Directory>
ErrorLog ${APACHE_LOG_DIR}/nextcloud-error.log
CustomLog ${APACHE_LOG_DIR}/nextcloud-access.log combined
</VirtualHost>
Replace cloud.example.com with the actual DNS name of the Nextcloud installation.
Enable the Nextcloud site:
a2ensite nextcloud.conf
If the default Apache site is no longer required, it can be disabled:
a2dissite 000-default.conf
Check the Apache configuration:
apache2ctl configtest
If the configuration is valid, the following output is displayed:
Syntax OK
Restart Apache and PHP-FPM:
systemctl restart php8.5-fpm systemctl restart apache2
Check both services:
systemctl status php8.5-fpm systemctl status apache2
Configuring the firewall
This step is only required if UFW is used on the server.
Before making changes, ensure that SSH remains allowed:
ufw allow OpenSSH
Allow HTTP and HTTPS:
ufw allow 'Apache Full'
Check the rules:
ufw status
Example:
To Action From -- ------ ---- OpenSSH ALLOW Anywhere Apache Full ALLOW Anywhere OpenSSH (v6) ALLOW Anywhere (v6) Apache Full (v6) ALLOW Anywhere (v6)
Setting up HTTPS
Nextcloud should only be accessible over HTTPS on production systems.
The following requirements apply for a publicly trusted certificate:
- The domain points to the Nextcloud server.
- TCP port 80 is reachable for certificate validation.
- TCP port 443 is reachable for subsequent HTTPS access.
Install Certbot and the Apache plugin:
apt install -y certbot python3-certbot-apache
Request the certificate:
certbot --apache --redirect -d cloud.example.com
Certbot configures the certificate and redirects HTTP requests to HTTPS.
Test automatic certificate renewal:
certbot renew --dry-run
Check the Certbot timer:
systemctl status certbot.timer
If a reverse proxy or load balancer is already placed in front of Nextcloud, TLS termination can alternatively take place there. In that case, the Nextcloud settings for trusted proxies and forwarded headers must also be configured correctly.
Self-signed certificates should only be used in isolated internal environments where the certificate can be added as trusted on all clients.
Completing the installation in the browser
Open the Nextcloud domain in a browser:
https://cloud.example.com/
Enter the following information in the installation dialog.
Administrator account
Create an administrator account with a secure password used exclusively for Nextcloud.
Data directory
Use the following path as the data directory:
/srv/nextcloud-data
Database
Select MariaDB or MySQL and use the following values:
- Database user:
nextcloud - Database password: the password defined previously
- Database name:
nextcloud - Database host:
localhost
Then start the installation.
-
Create an administrator account with a secure password.
-
Use the previously mounted NFS share as the data directory.
-
Enter the credentials for the local MariaDB database.
-
After a successful installation, the Nextcloud dashboard is displayed.
Configuring background jobs
Nextcloud requires background jobs to be executed regularly. Cron should be used for server installations.
Create the following cron file:
nano /etc/cron.d/nextcloud
Add the following content:
*/5 * * * * www-data /usr/bin/php8.5 -f /var/www/nextcloud/cron.php
Set the correct file permissions:
chmod 0644 /etc/cron.d/nextcloud
Enable cron mode in Nextcloud:
sudo -u www-data php8.5 /var/www/nextcloud/occ background:cron
Restart the cron service:
systemctl restart cron
Check the entry:
cat /etc/cron.d/nextcloud
Test the cron job manually once:
sudo -u www-data php8.5 -f /var/www/nextcloud/cron.php
The status of the background jobs can later be checked in Nextcloud under “Administration settings” → “Basic settings”.
Configuring APCu and Redis
APCu is used for the local application cache. Redis handles transactional file locking and can also be used as a distributed cache.
Open the Nextcloud configuration:
nano /var/www/nextcloud/config/config.php
Add the following entries inside the $CONFIG array:
'memcache.local' => '\OC\Memcache\APCu',
'memcache.distributed' => '\OC\Memcache\Redis',
'memcache.locking' => '\OC\Memcache\Redis',
'redis' => [
'host' => '127.0.0.1',
'port' => 6379,
'timeout' => 0.0,
],
Ensure that all entries are placed inside the existing $CONFIG array and that preceding entries are separated correctly with commas.
Restart PHP-FPM and Apache:
systemctl restart php8.5-fpm systemctl restart apache2
Check the Redis service:
systemctl status redis-server
Test the connection:
redis-cli ping
The expected response is:
PONG
Enabling pretty URLs
Pretty URLs remove the index.php component from Nextcloud URLs.
First set the complete Nextcloud URL:
sudo -u www-data php8.5 /var/www/nextcloud/occ \
config:system:set overwrite.cli.url \
--value="https://cloud.example.com"
Then set the rewrite base:
sudo -u www-data php8.5 /var/www/nextcloud/occ \
config:system:set htaccess.RewriteBase \
--value="/"
Update the Nextcloud .htaccess file:
sudo -u www-data php8.5 \
/var/www/nextcloud/occ maintenance:update:htaccess
Reload Apache:
systemctl reload apache2
Nextcloud URLs should now be displayed without index.php.
Verifying the installation
First check the Nextcloud status:
sudo -u www-data php8.5 /var/www/nextcloud/occ status
A successful installation returns information similar to the following:
installed: true maintenance: false needsDbUpgrade: false version: 34.0.1.0 versionstring: 34.0.1
Also check the relevant services:
systemctl status apache2 systemctl status php8.5-fpm systemctl status mariadb systemctl status redis-server systemctl status cron
Check the NFS mount again:
findmnt /srv/nextcloud-data
Verify that Nextcloud can still write to the data directory:
sudo -u www-data touch /srv/nextcloud-data/.write-test sudo -u www-data rm /srv/nextcloud-data/.write-test
Check the Nextcloud configuration:
sudo -u www-data php8.5 \
/var/www/nextcloud/occ config:list system
Finally, open “Administration settings” → “Overview” in Nextcloud. Missing PHP modules, cache issues, failed background jobs and other configuration problems are displayed there.
Optional configurations
Setting the default phone region
If phone numbers without an international country code are used in Nextcloud, a default region can be configured.
For Germany, use:
sudo -u www-data php8.5 /var/www/nextcloud/occ \
config:system:set default_phone_region \
--value="DE"
Configuring the maintenance window
Nextcloud can run resource-intensive daily background jobs preferentially during a maintenance window.
The following example sets the start of the maintenance window to 01:00 UTC:
sudo -u www-data php8.5 /var/www/nextcloud/occ \
config:system:set maintenance_window_start \
--type=integer \
--value=1
Running available repairs
After updates or configuration changes, the Nextcloud repair routines can be executed:
sudo -u www-data php8.5 \
/var/www/nextcloud/occ maintenance:repair
Operational notes
At least the following points should be considered for ongoing operation:
- Install security updates regularly
- Update Nextcloud and installed apps regularly
- Back up the MariaDB database
- Back up the NFS data directory
- Back up
/var/www/nextcloud/config - Monitor NFS availability
- Monitor local disk space
- Monitor Apache, PHP-FPM, MariaDB and Redis
- Check the Nextcloud administration overview regularly
- Check background jobs regularly
- Test restoring from existing backups
Relevant log files include:
/var/log/apache2/nextcloud-error.log /var/log/apache2/nextcloud-access.log /var/log/php8.5-fpm.log /srv/nextcloud-data/nextcloud.log
The systemd logs can also be displayed with the following commands:
journalctl -u apache2 journalctl -u php8.5-fpm journalctl -u mariadb journalctl -u redis-server
Displaying the Nextcloud version
The currently installed Nextcloud version can be checked at any time:
sudo -u www-data php8.5 /var/www/nextcloud/occ status
Displaying the PHP version
The command-line PHP version can be checked as follows:
php8.5 --version
The PHP-FPM version used by Apache can be checked through the service:
systemctl status php8.5-fpm
