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.
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:
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
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.
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
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:
127.0.1.1 nextcloud.mydomain.org 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
sudo nano /etc/ssh/sshd_config
Look for the option
PermitRootLogin and set it to
no. Save the file, and exit
To finalize the change, restart the ssh service:
sudo systemctl restart ssh
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.
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:
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
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
CREATE DATABASE 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:
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 nextcloud.learnlinux.cloud
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 nextcloud.learnlinux.cloud
After that, we'll move the Nextcloud directory to its proper place:
sudo mv nextcloud.learnlinux.cloud /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/nextcloud.learnlinux.cloud.conf
Add the following contents to the file (be sure to adjust the file names to match yours):
<VirtualHost *:80> DocumentRoot "/var/www/nextcloud.learnlinux.cloud" ServerName nextcloud.learnlinux.cloud <Directory "/var/www/nextcloud.learnlinux.cloud/"> Options MultiViews FollowSymlinks AllowOverride All Order allow,deny Allow from all </Directory> TransferLog /var/log/apache2/nextcloud.learnlinux.cloud_access.log ErrorLog /var/log/apache2/nextcloud.learnlinux.cloud_error.log </VirtualHost>
Enable the site
To activate our new site configuration within Apache, run the following command:
sudo a2ensite apache-config-file-name.conf
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 opcache.enable=1 opcache.interned_strings_buffer=8 opcache.max_accelerated_files=10000 opcache.memory_consumption=128 opcache.save_comments=1 opcache.revalidate_freq=1
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
sudo snap install core; sudo snap refresh core
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/nextcloud.learnlinux.cloud/config/config.php
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/nextcloud.learnlinux.cloud/config/config.php
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
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/nextcloud.learnlinux.cloud-le-ssl.conf
Add the following line after the ServerName line:
<IfModule mod_headers.c> Header always set Strict-Transport-Security "max-age=15552000; includeSubDomains" </IfModule>
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: