In this guide, we are going to set up NextCloud on an Ubuntu server hosted with Nginx, Mariadb and PHP (LEMP stack). Everything here uses the packages that ship in the default Ubuntu repositories — MariaDB 10.11 and PHP 8.3 on Ubuntu 24.04, MariaDB 11.8 and PHP 8.5 on Ubuntu 26.04.
Updated for 2026. This guide was originally written for Ubuntu 20.04 with PHP 7.4. Both are past their supported life — Ubuntu 20.04 left standard support in May 2025, and PHP 7.4 has been end-of-life since November 2022. Current Nextcloud (34) requires PHP 8.2 or newer and will refuse to install on PHP 7.4, so the steps below target Ubuntu 24.04 LTS and 26.04 LTS. See the note under Prerequisites if you are still on 22.04.
Nextcloud is an Open Source suite of client-server software for creating and using file hosting services. It is a free self-hosted cloud storage solution similar to Dropbox, Google Drive, etc. With Nextcloud, you don’t have to worry about the pricey alternatives and since you will host your own files, you don’t have to worry about privacy or someone collecting your data.
NextCloud can be installed on a private home server or a virtual private server in the cloud. Files can then be uploaded and then synced to a local desktop, laptop or even a smartphone. This way you have full control of your data.
Features of NextCloud
- NextCloud has sync clients for Linux, Mac OS, Windows, Android and IOS
- End to end encryption - files are encrypted while being uploaded to the server
- NextCloud is free and Open Source
- Can be integrated with an online office suite (Collobora, OnlyOffice) so you can create and edit your doc, ppt, xls files directly from NextCloud.
- The app store contains hundreds of apps to extend functionality (like calendar app, notes-taking app, video conferencing app, etc).
Related Content:
- How to install and configure NextCloud on Ubuntu 22.04 and LEMP
- How to Install and set up PHP and Nginx (LEMP) on Ubuntu 20.04
- How to install and configure NextCloud on Debian 11 and LEMP
- How to install and configure NextCloud on Centos 8 and LEMP
- How to install and Configure Mariadb 10 in Ubuntu 20.04
- How to Install and Set Up mysql 8 on Ubuntu 20.04
- How to Install and set up PHP and Nginx (LEMP) on Debian 11
Prerequisites
To follow along this guide, ensure that you have:
- An up to date Ubuntu Server — 24.04 LTS (Noble Numbat) or 26.04 LTS (Resolute Raccoon)
- Internet access from the server
- Root access from the server or user with sudo access
- A DNS record pointing at the server if you want to reach Nextcloud by hostname
On Ubuntu 22.04? Its default PHP is 8.1, which Nextcloud 33 and later no longer support (Nextcloud 32 was the last release to accept it). You can either add the Sury PHP repository to get PHP 8.3+, or upgrade the host to 24.04 LTS. Ubuntu 20.04 has no supported path at all here — upgrade it.
Ensure that the server packages are up to date
Let us make sure that our server packages are up to date with this command:
sudo apt update
sudo apt -y upgrade
While at it, let us also install some dependencies that we will require
sudo apt install -y unzip vim
Installing Mariadb in Ubuntu
Mariadb is a popular Opensource relational management system. It is available in the default repositories as mariadb-server.
Install it with this command:
sudo apt install -y mariadb-server
Mariadb will be installed and started by default in Ubuntu. Check the status with this
sudo systemctl status mariadb
Look for Active: active (running) near the top of the output, along with
Status: "Taking your SQL requests now..." — that confirms the server came up cleanly.
You can confirm the exact version with mariadb --version; expect 10.11.x on Ubuntu 24.04
and 11.8.x on Ubuntu 26.04. Both are supported by current Nextcloud.
To ensure that mariadb starts on boot, enable it with this systemd command:
sudo systemctl enable mariadb
Once the service is running, you need to secure it. MariaDB provides a commandline utility that will do that:
sudo mariadb-secure-installation
The above command will take you through prompts to secure the instance — removing anonymous users, disallowing remote root login and dropping the test database.
Older guides call this
mysql_secure_installation. On Ubuntu that name still works as a compatibility symlink, but MariaDB has renamed all of its client tools tomariadb-*, so prefer the new name.
Check more info on Installing and setting up mariadb in this guide.
Creating mysql user for NextCloud
It is always recommended to have a dedicated user for each app that connects to the DB. Check out this guide on managing mysql permissions. We will set up a database, user and password to be used by nextcloud:
Connect to the database server. On a modern Ubuntu install the root MariaDB account
authenticates over a unix socket, so sudo is enough and no password is needed:
sudo mariadb
At the prompt, create the database and a dedicated user:
CREATE DATABASE nextcloud CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
CREATE USER 'nextcloud_user'@'localhost' IDENTIFIED BY 'S0mStrongPa$$word';
GRANT ALL PRIVILEGES ON nextcloud.* TO 'nextcloud_user'@'localhost';
FLUSH PRIVILEGES;
EXIT;
Two things worth calling out:
utf8mb4is not optional. Nextcloud stores filenames and comments as 4-byte UTF-8 (emoji included). Creating the database with the older default charset leads to “MySQL 4-byte support” warnings and truncation errors later.- Scope the user to
localhost, not'%'. The database and Nextcloud are on the same host here, so there is no reason to accept connections from anywhere on the network. Only widen this if your database genuinely lives on another machine.
Now that we have configured our mysql connection, lets go to the next section where we install and configure PHP and Nginx.
Installing PHP in Ubuntu
Current Nextcloud supports PHP 8.2 through 8.5, with 8.5 recommended. The default Ubuntu repositories already give you a supported version — PHP 8.3 on Ubuntu 24.04, PHP 8.5 on Ubuntu 26.04 — so no third-party PPA is needed.
Install php and its dependencies:
sudo apt install -y \
php-fpm \
php-cli \
php-mysql \
php-gd \
php-curl \
php-zip \
php-xml \
php-mbstring \
php-intl \
php-bcmath \
php-gmp \
php-apcu
A few notes on that list:
php-mysqlis mandatory. It provides thepdo_mysqldriver. Without it the setup wizard cannot talk to MariaDB and fails at the database step.php-domandphp-simplexmlare both provided byphp-xml, so installing it covers them.php-jsonno longer exists as a separate package — JSON has been part of PHP core since 8.0.php-apcuis not strictly required but Nextcloud will nag you about missing memory caching without it.- For thumbnail generation you can optionally add
php-imagickandlibmagickcore-6.q16-6-extra.
Confirm the version you ended up with, since you need it for the socket path and service name further down:
php -v
Nextcloud also wants a memory_limit of at least 512M. Set it in the FPM pool config,
substituting your PHP version for 8.3:
sudo sed -i 's/^memory_limit = .*/memory_limit = 512M/' /etc/php/8.3/fpm/php.ini
For more info on setting up PHP and Nginx, check out this guide.
Installing Nginx in Ubuntu
Next, let us install Nginx in our system. Use this command to install nginx
sudo apt install -y nginx
Nginx will be started by default. Check the status using this command:
sudo systemctl status nginx
Active: active (running) indicate that the service is now up and running.
To enable the service on boot, use this command:
sudo systemctl enable nginx
Download and configure Nextcloud
Now that we have successfully configured the LEMP server in our system, let us download and set up NextCloud. You can get the latest version of NextCloud from the NextCloud installation page. Rather than pinning a version that will go stale, use the latest.zip alias, which always resolves to the current stable release (Nextcloud 34 at the time of writing):
cd /tmp
curl -LO https://download.nextcloud.com/server/releases/latest.zip
Now let us change into a directory path to serve NextCloud in /var/www then extract the downloaded file there:
cd /var/www
sudo unzip /tmp/latest.zip
sudo chown -R www-data:www-data /var/www/nextcloud
sudo chmod -R 750 /var/www/nextcloud
Nextcloud required a directory to keep its data. So create a data directory and set the proper permissions on nextcloud directory
sudo mkdir -p /var/nextcloud/data
sudo chown -R www-data:www-data /var/nextcloud
sudo chmod -R 750 /var/nextcloud
The original version of this guide used
chown -R $USER:$GROUP. That is wrong on two counts:$GROUPis not a variable bash sets (so it expanded to nothing), and the files need to be owned by the user PHP-FPM runs as —www-data— or Nextcloud cannot write to its own config and data directories. Keeping the data directory at/var/nextcloud, outside the web root, is deliberate: it means the files are never directly reachable over HTTP.
Configure Nginx to serve NextCloud from a virtual host
We managed to download the NextCloud content to /var/www/nextcloud. The next bit it to set up Nginx to serve it.
Let’s create virtual site in the directory that nginx serves content here /etc/nginx/conf.d:
sudo vim /etc/nginx/conf.d/nextcloud.conf
Add the following content, replacing php8.3-fpm.sock with the version you saw from php -v
(Ubuntu 26.04 users want php8.5-fpm.sock):
server {
listen 80;
server_name nextcloud.citizix.com;
root /var/www/nextcloud;
index index.php index.html;
# Nextcloud moves large files; the nginx default of 1m is far too small.
client_max_body_size 512M;
client_body_timeout 300s;
fastcgi_buffers 64 4K;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Referrer-Policy "no-referrer" always;
# Service discovery for the CalDAV/CardDAV clients.
location = /.well-known/carddav { return 301 /remote.php/dav/; }
location = /.well-known/caldav { return 301 /remote.php/dav/; }
# Never serve these over HTTP.
location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/) { return 404; }
location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) { return 404; }
location / {
try_files $uri $uri/ /index.php$request_uri;
}
location = /favicon.ico {
log_not_found off;
access_log off;
}
location ~* \.(js|css|png|jpg|jpeg|gif|ico|woff2)$ {
expires 6M;
access_log off;
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
location ~ \.php(?:$|/) {
# Split the script from the trailing path so remote.php/dav/... routes correctly.
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
try_files $fastcgi_script_name =404;
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param front_controller_active true;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
fastcgi_index index.php;
fastcgi_hide_header X-Powered-By;
}
}
This is a deliberately minimal config that is enough to get Nextcloud running and passing its
own setup checks. For a production deployment — HTTP/2, caching headers, .mjs handling and
the rest — start from the full example in the Nextcloud admin manual
instead.
Check the syntax before reloading:
sudo nginx -t
Once the above changes have been made, we need to restart the nginx server and the php-fpm server. Use these commands in the terminal to achieve that.
sudo systemctl restart php8.3-fpm nginx
Accessing Nextcloud from the web url
Then head to your set domain, http://nextcloud.citizix.com/ for me. Since the vhost root
already points at /var/www/nextcloud, the app is served from the domain root — there is no
/nextcloud path segment to append.
- You will be asked to create the admin account. Enter the username and password to be using for the new user
- Set the data folder to
/var/nextcloud/data - Then enter the Database Details — database
nextcloud, usernextcloud_user, the password you chose, andlocalhostas the host
After that Click Finish. The installer takes a minute or two to seed the database. You will then be redirected to the login page where you will use the details for the created user to login. On Successful login you will get the Dashboard.
Secure the site with HTTPS
Nextcloud handles your files and credentials, so do not leave it on plain HTTP. With the DNS record already pointing at the server, Certbot will issue a certificate and rewrite the vhost for you:
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d nextcloud.citizix.com
Renewal is handled automatically by the certbot.timer systemd unit that the package installs.
Finishing touches
Open Administration settings → Overview in the web UI. Nextcloud runs its own configuration checks there and will tell you about anything still missing — a missing PHP module, an absent memory cache, or a cron job that has not been set up.
Two items worth handling straight away. First, register a real background job runner instead of the default AJAX one:
sudo crontab -u www-data -e
Add this line:
*/5 * * * * php -f /var/www/nextcloud/cron.php
Then switch the mode to Cron under Administration settings → Basic settings.
Second, if you reach the server by any hostname other than the one you installed with, add it
to trusted_domains or Nextcloud will refuse the request:
sudo -u www-data php /var/www/nextcloud/occ config:system:set \
trusted_domains 1 --value=nextcloud.example.com
Conclusion
In this guide, we managed to set up LEMP on Ubuntu to serve Next cloud.