Updated October 2026: this article originally existed as an unpublished draft based on Ubuntu 20.04 and accidentally contained several sections copied from a WordPress installation guide. Before publication it was rebuilt from scratch. This version uses Ubuntu Server 24.04 LTS, Apache, MariaDB, PHP 8.3, Redis/APCu, Let’s Encrypt HTTPS, and the stable Nextcloud 35 branch.
Nextcloud lets you run a private cloud for files, calendars, contacts, photos, collaboration, and many other functions through apps. Unlike hosted services such as Google Drive, OneDrive, or Dropbox, a self-hosted deployment gives you direct control over the infrastructure, backups, access policy, and data location.
cloud.example.com, with DNS A —and AAAA when using IPv6— records pointing to the server.Replace cloud.example.com, usernames, and passwords in every example with your own values.
sudo apt update
sudo apt full-upgrade
sudo reboot lsb_release -a If UFW is in use, make sure SSH remains allowed before enabling it:
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status Ubuntu 24.04 already includes PHP 8.3 in its official repositories, so no third-party PHP PPA is required.
sudo apt install apache2 mariadb-server libapache2-mod-php php php-gd php-mysql php-curl php-mbstring php-intl php-gmp php-xml php-imagick php-zip php-bcmath php-apcu php-redis redis-server curl wget bzip2 sudo systemctl enable --now apache2 mariadb redis-server
sudo systemctl status apache2 --no-pager
sudo systemctl status mariadb --no-pager
sudo systemctl status redis-server --no-pager
php -v For Nextcloud 35, do not follow older tutorials that force PHP 8.2 or MySQL 8.0. Nextcloud 35 dropped PHP 8.2 support and raised the minimum MySQL version to 8.4 and MariaDB to 10.11.
sudo mariadb CREATE DATABASE nextcloud CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
CREATE USER 'nextcloud'@'localhost' IDENTIFIED BY 'CHANGE-THIS-PASSWORD';
GRANT ALL PRIVILEGES ON nextcloud.* TO 'nextcloud'@'localhost';
FLUSH PRIVILEGES;
EXIT; Use a dedicated database account. The MariaDB root account should not be used by Nextcloud itself.
Using latest-35.tar.bz2 keeps the guide on the current maintenance release within the stable 35 branch instead of hard-coding a patch version.
cd /tmp
wget https://download.nextcloud.com/server/releases/latest-35.tar.bz2
wget https://download.nextcloud.com/server/releases/latest-35.tar.bz2.sha256
sha256sum -c latest-35.tar.bz2.sha256 tar -xjf latest-35.tar.bz2
sudo mv nextcloud /var/www/nextcloud
sudo chown -R www-data:www-data /var/www/nextcloud sudo mkdir -p /var/ncdata
sudo chown -R www-data:www-data /var/ncdata
sudo chmod 750 /var/ncdata Keeping the user-data directory outside Apache’s DocumentRoot reduces accidental exposure and makes the server layout easier to manage.
sudo nano /etc/apache2/sites-available/nextcloud.conf <VirtualHost *:80>
ServerName cloud.example.com
DocumentRoot /var/www/nextcloud
<Directory /var/www/nextcloud/>
Require all granted
AllowOverride All
Options FollowSymLinks MultiViews
</Directory>
ErrorLog ${APACHE_LOG_DIR}/nextcloud-error.log
CustomLog ${APACHE_LOG_DIR}/nextcloud-access.log combined
</VirtualHost> sudo a2enmod rewrite headers env dir mime setenvif
sudo a2ensite nextcloud.conf
sudo a2dissite 000-default.conf
sudo apache2ctl configtest
sudo systemctl reload apache2 On Ubuntu 24.04, Apache normally uses /etc/php/8.3/apache2/php.ini. A reasonable starting point for a small server is:
memory_limit = 512M
upload_max_filesize = 2G
post_max_size = 2G
max_execution_time = 3600
max_input_time = 3600
date.timezone = UTC sudo systemctl restart apache2 When APCu is also needed by command-line jobs, enable apc.enable_cli=1 in the appropriate CLI PHP configuration.
The web installer can also be used, but occ makes a server installation easier to reproduce and document.
sudo -u www-data php /var/www/nextcloud/occ maintenance:install --database "mysql" --database-name "nextcloud" --database-user "nextcloud" --database-pass "DATABASE-PASSWORD" --admin-user "admin" --admin-pass "VERY-STRONG-ADMIN-PASSWORD" --data-dir "/var/ncdata" sudo -u www-data php /var/www/nextcloud/occ config:system:set trusted_domains 0 --value=cloud.example.com
sudo -u www-data php /var/www/nextcloud/occ config:system:set overwrite.cli.url --value=https://cloud.example.com Before requesting the certificate, make sure the hostname resolves to the server and TCP port 80 is reachable.
sudo snap install --classic certbot
sudo ln -sf /snap/bin/certbot /usr/local/bin/certbot
sudo certbot --apache -d cloud.example.com sudo certbot renew --dry-run Modern Certbot installations manage certificate renewal automatically, so a custom daily renewal cron entry is not required.
For a single-server deployment, Nextcloud recommends APCu for local caching and Redis for distributed caching and transactional 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 --type=integer --value=6379 redis-cli ping Nextcloud supports AJAX, Webcron, and cron for background work. On a server you control, real cron is the preferred option.
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/nextcloud
sudo chmod 644 /etc/cron.d/nextcloud sudo -u www-data php /var/www/nextcloud/occ status
sudo -u www-data php /var/www/nextcloud/occ db:add-missing-indices
sudo -u www-data php /var/www/nextcloud/occ maintenance:repair
sudo apache2ctl configtest
sudo systemctl status apache2 --no-pager
sudo systemctl status mariadb --no-pager
sudo systemctl status redis-server --no-pager Then open Administration settings → Overview. Nextcloud reports configuration, database, security, and performance warnings there. Resolve meaningful warnings before treating the server as production-ready.
A usable Nextcloud backup needs at least three components:
/var/www/nextcloud/config/./var/ncdata.Backups should be tested by performing periodic restore exercises, not merely created and forgotten.
Nextcloud releases maintenance updates containing security and stability fixes. Before upgrading, review the release notes, check app compatibility, and make a recent backup.
Existing installations should follow the supported updater process rather than simply replacing files. The updater and occ upgrade handle the required migrations when applicable.
trusted_domains.php-redis extension./etc/cron.d/nextcloud and the configured background-job mode.www-data can write only where Nextcloud requires it; do not solve permission problems by making the whole tree world-writable.At this point the server is ready for additional work such as external storage, SMTP, LDAP/Active Directory, Collabora or Office integration, Talk, automated backups, and additional hardening.
A complete networking roadmap for future sysadmins: Ethernet, IPv4/IPv6, subnetting, VLANs, routing, DNS, DHCP, Linux,…
History and architecture of Evelyn Berezin’s United Airlines reservation system, distinguishing it from the earlier…
Biography of Evelyn Berezin: systems designer behind an early United Airlines reservation system and founder…
Step-by-step guide to installing WordPress on Ubuntu Server 24.04 LTS with Apache, MySQL 8.0, PHP…
What Delphi is in 2026: Object Pascal, VCL and FireMonkey, supported platforms, Community Edition, commercial…
What a web browser is, how it works, its history, Blink, Gecko and WebKit engines,…