How To Install Nextcloud On An Ubuntu Server

How To Install Nextcloud On An Ubuntu Server

Introduction, and Getting Started

Nextcloud is a powerful productivity platform that gives you access to some amazing features, such as collaborative editing, cloud file sync, private audio/video chat, email, calendar, and more! Best of all, Nextcloud is under your control and is completely customizable. In this article, we're going to be setting up our very own Nextcloud server on Linode. Alternatively, you can also spin up a Nextcloud server by utilizing the Linode marketplace, which you can use to set up Nextcloud in a single click. However, this article will walk you through the manual installation method. While this method has more steps, by the end you'd have built your very own Nextcloud server from scratch, which will be not only a valuable learning experience - you'll become intimately familiar with the process of setting up Nextcloud. Let's get started!

In order to install Nextcloud, we'll need a Linux instance to install it onto. That's the easy part - there's no shortage of Linux on Linode, so what we'll do in order to get started, is create a brand-new Ubuntu 20.04 Linode instance to serve as our base. Many of the commands we'll be using have changed since Ubuntu 20.04, so while you might be tempted to start with a newer instance, these commands were all tested on Ubuntu 20.04. And considering that Ubuntu 20.04 is supported until April of 2025, it's not a bad choice at all.

Creating your instance

During the process of creating your new Linode instance, choose a region that's closest to you geographically (or close to your target audience). For the instance type, be sure to choose a plan with 2GB of RAM (preferably 4GB). You can always increase the plan later, should you need to do so. You can save some additional money by choosing an instance from the Shared CPU section. For the label, give it a label that matches the designated purpose for the instance. A good name might be something like "nextcloud", but if you have a domain for you instance, you an use that as the name as well.

Continuing, you can consider using tags, which are basically basically a name value pair you can add to your instance. This is completely optional, but you could create whatever tags for your instance if you have a need to do so. For example, you could have a "production" tag, or maybe a "development" tag depending on whether or not you intend to use the instance for production. Again, this is optional, and there's no right or wrong way to tag an instance. If in doubt, you can just leave this blank.

Next, the root password should be unique, and preferably, randomly-generated. This password in particular is going to be the password we will use to log into our instance so make sure you remember it. SSH keys are preferred, and if you have one set up within your profile, you can check a box on this page to add it to your instance.

While building your instance, pay special attention to the backup option, which might be a very good idea if you intend on using your new Nextcloud server in production. I highly recommend that you set up backups for your Nextcloud instance so you'll get a backup every single day which can be very useful if something happens to instance - you could revert it back to the previous day which can help you out if you run into some sort of issue.

For the other options in this section, you can skip them or enable them, depending on your needs - but the goal for this section is to create a new instance that eventually become our new Nextcloud server. After verifying the monthly cost on the right-hand side, click Create Linode in order to finalize the process and begin the provisioning process for your server.

Setting up DNS (optional, but recommended)

Your Linode instance will automatically be assigned a public IP, and by "public", that's true in every sense of the word - your server is routable and reachable to and from the public internet. You can access your instance via its IP address, but if you own a domain - it's typically better to go with that. You can skip this entire section if you don't have a domain name to use, but it's highly recommended to use a domain if you can.

If you are planning on using a domain, you can associate the IP address of your Linode instance to a domain record anytime, but it's a good idea to associate the name and IP now, since it can take some time to propagate. Perhaps by the time you're finished following these steps, DNS propagation would have already finished. This can vary quite a bit, but in most cases it won't take too long. 

To add your domain, there's a Domains section within Linode you can use, right in the cloud dashboard. If you don't have one, you can get a domain from a service such as Hover. There are other domain registrars in existence, should you wish to explore alternatives. Once you register a domain, you can add it to Linode so that way you can integrate it easily with your instances. To do so, go into the "Domains" section, and create an Address Record for your new instance. Simply paste in the IP address into the appropriate field, and be sure to enter in the hostname in the designated field.

Connecting to your instance

After your instance finishes provisioning and booting, you can connect to it via SSH or the Lish console in order to configure it. SSH is the preferred method, but the Lish console can be useful if you don't already have an ssh client installed. The username, at least until we add a new user, is going to be root and the password will be whatever you assigned during the instance creation process. If you're using SSH, you can connect via an SSH key (if you have one) otherwise you can use standard authentication.

Creating a local user

Once you're logged in to your instance, and you have a command shell into which to enter commands, you can start actually building your server. However, running commands as root isn't generally considered a best practice, so it's recommended that you create a non-root account to use in place of that. We can create a user with the following command:

adduser jay

Fill out each of the fields as you see them, which includes setting a password, full name, and more. The password is required, but you can skip the other fields. Next, we'll need to give our new user access to sudo. We can add our user to the appropriate group that enables sudo access, by running the following command:

usermod -aG sudo jay

At this point, if you type groups and then the username,  you can see that the new user we've created is a member of the sudo group.

Now that we've created a non-root user, it's recommended that you log in with your new account and use that going forward. You can simply log out and log in again in order to start using the new account.

Installing updates

Continuing with our initial setup, let's install all available updates. This should be done every time we're setting up a new Linux server - we always want to start with the latest and greatest packages since they include security updates that are definitely important to take advantage of. We should be logged in as the new user, so we'll prefix administrative commands with sudo going forward.

To update the repository index, we'll enter the following command:

sudo apt update

Now that we've updated the repository index, we'll run the following command to actually install the available updates:

sudo apt dist-upgrade

You can simply press enter to accept the default, since "Y" is capital - which means that it's the default choice. After you press enter, updates will begin installing - which might take a while depending on how many are queued for installation. Give it some time, and we can continue once it's finished.

Next, you might not need the following command, but it might be useful for potential cleanup after installing updates:

sudo apt autoremove

The autoremove option will remove any orphaned packages that may be present.

Setting the Hostname

Before rebooting our server, we should configure its hostname. It starts off as localhost, but that's not very descriptive. Edit the hostname file, and change the hostname:

sudo nano /etc/hostname

Here, you can change "localhost" to a simple hostname, or even a domain (if you have one).

Save the file with CTRL, O then Enter. Exit nano by pressing CTRL, O, then x.

Next, we'll edit the /etc/hosts file, which also contains the hostname of our server. We should change it within this file to match what we named it in the /etc/hostname file. However, you should leave "localhost" in this particular file, then add your server's actual hostname on the next line. For example: nextcloud

Save the file, and then we should reboot the server before continuing. You can do this by clicking the "Reboot" button within the Linode dashboard for this instance.

Disabling root login via SSH

There's many tweaks you can make to increase the security of your Linux server, but at the very least, we should disable access to SSH via root. We should definitely disable that. As long as you've already created a non-root user, you can safely disable root access via SSH. To do this, you should edit the sshd_config file with nano:

sudo nano /etc/ssh/sshd_config

Look for the option PermitRootLogin and set it to no. Save the file, and exit nano.

To finalize the change, restart the ssh service:

sudo systemctl restart ssh

Downloading Nextcloud

In order to continue, we'll need to find the URL that points to Nextcloud's download. You can find this by visiting Nextcloud's official site, and look for a download link. Currently, there's a "Get Nextcloud" button, which should take you to the correct page. Once you find the download button, don't click on it via your left mouse button as you'd normally do - right-click the download link itself, and copy the download link.

Back in your terminal, use the wget command to download Nextcloud, along with the URL for the download file. The command below shows an example of using wget to download Nextcloud, and the URL that shows within this command is correct as of the time-stamp of this article:


After you finish downloading Nextcloud, we'll leave the file alone for now, and we'll come back to it later. Let's take a detour and set up MariaDB.

Database Setup

Installing MariaDB

The next thing we're going to do is set up the database server for Nextcloud, we definitely want to make sure we have that ready to go when we need it so first we'll install a special package that'll give us access to a MySQL server (specifically MariaDB) so we'll begin the process by installing MariaDB via apt:

sudo apt install mariadb-server

Once the installation is complete, this will satisfy our requirement for a database server. We can run the following command to check the status of the MariaDB server:

systemctl status mariadb

Within the output, ensure that the mariadb service is enabled, and that its status shows as running. Before we create the database that we'll need for Nextcloud, we should ensure our database service at least some basic level of security, so we'll run the following command to take care of some of the basics:

sudo mysql_secure_installation

Even though the command includes mysql in its name, it's compatible with MariaDB and will still suit our purposes. What this command will do, is launch a script that will ask various questions, with each answer being a potential benefit to increase security. This script won't make the server completely secure, but it does represent a good starting point and will be enough for our purposes. First, the command will ask for the current root password (specifically the root password for MySQL, not the password of the root Linux user). We haven't set that yet, so we'll press enter to bypass this prompt. Next, the script will ask us if we would like to actually set the root password (which would be a great idea). If you press enter, the default is to agree to set the password - which you'll then be asked to set. What I recommend you do is create a randomly generated password, and save it in a very safe place. For the remainder of the prompts, you can safely accept the default for each, by again pressing Enter for each question.

Creating the Nextcloud database

The next component we'll set up is the actual database itself, which will store information for our Nextcloud instance. To do this, we'll first access the MariaDB console, which we can do by running the mariadb command as root or with sudo:

sudo mariadb

Once inside the shell, we'll run a few commands in the MySQL format, which are going to be shown here (and in the video) as uppercase. While not required, it's common practice to type MySQL commands in upper case, which also differentiates the command portion from metadata, such as the database name. That said, the following command will create an empty database named nextcloud:


Let's make sure the database is truly there:


Next, we'll create some permissions to allow the Nextcloud application to access the database server. We do that by creating a "grant" which allows the nextcloud user to access the entire database:

GRANT ALL PRIVILEGES ON nextcloud.* TO 'nextcloud'@'localhost' IDENTIFIED BY 'mypassword';

Finally, let's flush privileges to ensure our new settings takes effect:


Now that we have the database server set up, we can move on to the webserver portion.

Apache Webserver Setup

Installing the required packages to support Apache

We'll need to run the following command, in order to install all of the packages that are required to support Apache on our instance:

sudo apt install php php-apcu php-bcmath php-cli php-common php-curl php-gd php-gmp php-imagick php-intl php-mbstring php-mysql php-zip php-xml

Next, let's ensure Apache is running:

systemctl status apache2

In order to satisfy requirements for Nextcloud, we'll need to enable the recommended PHP extensions, which we can do by running the following command:

sudo phpenmod bcmath gmp imagick intl

In addition, we'll also need to install zip, to enable us to unzip the Nextcloud zip file that we downloaded earlier:

sudo apt install unzip

After that, you should then be able to extract the downloaded Nextcloud archive:

unzip nextcloud-<version>.zip

Installing Nextcloud's files and setting up their permissions

Now that we’ve unzipped the files, let’s move the files to where they’ll be served from and also set the permissions as well:

mv nextcloud

Another change we'll make, is to ensure the www-data user and group own the Nextcloud directory, as well as any comments:

sudo chown -R www-data:www-data

After that, we'll move the Nextcloud directory to its proper place:

sudo mv /var/www

Finally, we should disable the default site that comes with Apache, since we won't be using it:

sudo a2dissite 000-default.conf

Creating a host configuration file for Nextcloud

Next, we’ll set up a config file for Apache that tells it how to serve Nextcloud.

sudo nano /etc/apache2/sites-available/

Add the following contents to the file (be sure to adjust the file names to match yours):

<VirtualHost *:80>

    DocumentRoot "/var/www/"


<Directory "/var/www/">
    Options MultiViews FollowSymlinks
    AllowOverride All
    Order allow,deny
    Allow from all

   TransferLog /var/log/apache2/nextcloud.learnlinux.cloud_access.log
   ErrorLog /var/log/apache2/nextcloud.learnlinux.cloud_error.log


Enable the site

To activate our new site configuration within Apache, run the following command:

sudo a2ensite apache-config-file-name.conf

Configuring PHP

Almost there! The next step will have us change some PHP options. First, edit the following file:

sudo nano /etc/php/7.4/apache2/php.ini

Adjust the following parameters within that file:

memory_limit = 512M

upload_max_filesize = 200M

max_execution_time = 360

post_max_size = 200M

date.timezone = America/Detroit







Run the following command to ensure required PHP modules are enabled:

sudo a2enmod dir env headers mime rewrite ssl

Restart Apache to ensure the new PHP settings take effect:

sudo systemctl restart apache2

Acquiring a TLS certificate

Let’s set up Let’s Encrypt and obtain a certificate for our Nextcloud installation. The following steps will guide you through the process.

Note: Instructions are taken from this link, which you may want to visit in case the instructions change in the future.

Ensure snapd is installed

To utilize Let's Encrypt, we'll be using snapd, so first make sure that's installed:

sudo apt install snapd

You'll also need to install the core snap:

sudo snap install core; sudo snap refresh core

Install Certbot

The following commands will ensure certbot is installed, which is the tool we'll use to acquire a certificate:

sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot

Attempt to obtain a certificate (DNS must have already propagated):

sudo certbot --apache

Answer the prompts carefully, and as long as you didn’t overlook everything you should have your very own TLS certificate!

Misc. Tweaks and Adjustments

To wrap things up, we'll implement some additional tweaks that won't necessarily fit in an earlier section.

Correct the permissions of the config.php file

We definitely wouldn’t want the config.php file to fall into the wrong hands, as it contains valuable setup information regarding our Nextcloud setup. Let’s adjust the permissions to better protect it.

sudo chmod 660 /var/www/<nextcloud_directory>/config/config.php
sudo chown root:www-data /var/www/<nextcloud_directory/config/config.php

Enable memory caching

Edit the Nextcloud config file:

sudo vim /var/www/

Add the following line to the bottom:

'memcache.local' => '\\OC\\Memcache\\APCu',

Resolving warnings pertaining to the default phone region

Edit the Nextcloud config file:

sudo vim /var/www/

Add the following line to the bottom of the file:

'default_phone_region' => 'US',

Note: Be sure to change “US” in the above example to your two-character country code, if yours is not US.

Get rid of the Image Magick error

Install the libmagickcore-6.q16-6-extra package:

sudo apt install libmagickcore-6.q16-6-extra

Enabling Strict Transport Security

Edit the SSL config file for our Nextcloud installation:

sudo vim /etc/apache2/sites-available/

Add the following line after the ServerName line:

<IfModule mod_headers.c>

    Header always set Strict-Transport-Security "max-age=15552000; includeSubDomains"


Project complete!

The last task to complete is to access the instance, which you can do so by typing in the domain or IP address for your instance. You should see a configuration page, asking you to fill in some information, such as info pertaining to the database. Simply use the values that you used earlier in the process, and your new Nextcloud instance should be up and running!

You can watch the tutorial here:

Jeremy 'Jay' LaCroix is the owner of LearnLinuxTV

Load Disqus comments