How to Install Nextcloud on Ubuntu 20.04

Updated on March 29, 2022
How to Install Nextcloud on Ubuntu 20.04 header image

Overview

NextCloud is an open-source self-hosted cloud storage server and workspace tool. Its extensive plug-in community offers solutions for most file-hosting and collaborative needs.

Prerequisites

Install Dependencies

  1. Install unzip.

     $ sudo apt-get install unzip
  2. Install the server dependencies.

     $ sudo apt-get install nginx mysql-server
  3. Install the PHP dependencies.

     $ sudo apt-get install php7.4 php7.4-cli php7.4-common php7.4-json php7.4-fpm php7.4-curl php7.4-mysql php7.4-gd php7.4-opcache php7.4-xml php7.4-zip php7.4-mbstring

PHP Setup

  1. Verify php7.4-fpm is installed.

     $ php-fpm7.4 --version
     PHP 7.4.3 (fpm-fcgi)
  2. Start and enable php7.4-fpm.

     $ sudo systemctl start php7.4-fpm
     $ sudo systemctl enable php7.4-fpm
  3. Verify php7.4-fpm is running.

     $ sudo systemctl status php7.4-fpm
     Active: active (running)

Database Setup

  1. Verify MySQL is installed.

     $ mysql --version
     mysql  Ver 8.0.xx-0ubuntu0.20.04.x
  2. Start and enable MySQL to run on boot.

     $ sudo systemctl start mysql
     $ sudo systemctl enable mysql
  3. Verify MySQL is running.

     $ sudo systemctl status mysql
     Active: active (running)
  4. Enter MySQL console as a root user.

     $ sudo mysql -u root
  5. Create a new database called nextcloud.

     mysql> CREATE DATABASE nextcloud;
  6. Create a new privileged user inside the nextcloud database. Replace username with a username and password with a strong password of your choice.

     mysql> CREATE USER 'username'@'localhost' IDENTIFIED BY 'password';
     mysql> GRANT ALL PRIVILEGES ON nextcloud.* TO 'username'@'localhost';
     mysql> FLUSH PRIVILEGES;

    > NextCloud uses this user to authenticate a connection with MySQL.

  7. Exit MySQL.

     mysql> exit;

Server Setup

  1. Verify Nginx is installed.

     $ nginx -v
     nginx version: nginx/1.18.x
  2. Start and enable Nginx to run on boot.

     $ sudo systemctl start nginx
     $ sudo systemctl enable nginx
  3. Verify Nginx is running.

     $ sudo systemctl status nginx
     Active: active (running)
  4. Download the latest release of NextCloud to /var/www/.

     $ sudo wget https://download.nextcloud.com/server/releases/latest.zip -P /var/www/
  5. Change directory to /var/www/ and extract latest.zip.

     $ cd /var/www/
     $ sudo unzip -q latest.zip
     $ sudo rm latest.zip

    > After extracting, latest.zip is no longer required. You may delete it.

  6. Change the ownership of the NextCloud folder.

     $ sudo chown -R www-data:www-data nextcloud
  7. Change directory to /etc/nginx/sites-available/ and delete the default Nginx server block.

     $ cd /etc/nginx/sites-available/
     $ sudo rm default
     $ sudo rm /etc/nginx/sites-enabled/default
  8. Create and edit a new Nginx server block.

     $ sudo nano nextcloud
  9. Add the following server configuration to the file.

     upstream php-handler {
             server unix:/var/run/php/php7.4-fpm.sock;
     }
    
     server {
             listen 80;
             listen [::]:80;
             server_name _;
    
             root /var/www/nextcloud;
             index index.php index.html /index.php$request_uri;
    
             # Limit Upload Size
             client_max_body_size 512M;
             fastcgi_buffers 64 4K;
    
             # Gzip Compression
             gzip on;
             gzip_vary on;
             gzip_comp_level 4;
             gzip_min_length 256;
             gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
             gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
    
             # Recommended Security Headers
             add_header Referrer-Policy                      "no-referrer"   always;
             add_header X-Content-Type-Options               "nosniff"       always;
             add_header X-Download-Options                   "noopen"        always;
             add_header X-Frame-Options                      "SAMEORIGIN"    always;
             add_header X-Permitted-Cross-Domain-Policies    "none"          always;
             add_header X-Robots-Tag                         "none"          always;
             add_header X-XSS-Protection                     "1; mode=block" always;
             fastcgi_hide_header X-Powered-By;
    
             # Recommended Hidden Paths
             location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/)  { return 404; }
             location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console)              { return 404; }
    
             location ~ \.php(?:$|/) {
                     fastcgi_split_path_info ^(.+?\.php)(\/.*|)$;
                     set $path_info $fastcgi_path_info;
                     try_files $fastcgi_script_name =404;
                     fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                     fastcgi_param PATH_INFO $path_info;
                     fastcgi_param modHeadersAvailable true;
                     fastcgi_param front_controller_active true;
                     fastcgi_pass php-handler;
                     fastcgi_intercept_errors on;
                     fastcgi_request_buffering off;
                     include fastcgi_params;
                     proxy_connect_timeout 600s;
                     proxy_send_timeout 600s;
                     proxy_read_timeout 600s;
                     fastcgi_send_timeout 600s;
                     fastcgi_read_timeout 600s;
             }
    
             # Cache-Control on Assets
             location ~ \.(?:css|js|woff2?|svg|gif|map)$ {
                     try_files $uri /index.php$request_uri;
                     add_header Cache-Control "public, max-age=15778463";
                     expires 6M;
             }
    
             location ~ \.(?:png|html|ttf|ico|jpg|jpeg|bcmap)$ {
                     try_files $uri /index.php$request_uri;
             }
    
             location / {
                     try_files $uri $uri/ /index.php$request_uri;
             }
     }
  10. Create server block link of nextcloud in sites-enabled.

    $ sudo ln -s /etc/nginx/sites-available/nextcloud -t /etc/nginx/sites-enabled/
  11. Restart Nginx for the changes to take effect.

    $ sudo systemctl restart nginx

NextCloud Setup

  1. Navigate to your server's IP address in a web browser.

     http://192.0.2.123/
  2. You should see a setup page asking to Create an admin account. Enter a username and a strong password of your choice for the main admin account.

  3. Inside the Storage & database section, the field for Data Folder is /var/www/nextcloud/data.

  4. Under the Configure the database section, enter the username and password created in Step 6 during the Database Setup.

  5. The Database name field is nextcloud, and Database host is localhost.

  6. Finally, click the Install button at the end of the form. NextCloud redirects to the dashboard when it finishes installing.

    Installing may take several minutes to complete depending on server specifications.

Additional Configuration

Redis Cache

A cache can improve NextCloud's performance by allowing faster access to assets.

  1. Install Redis and the php-redis module.

     $ sudo apt-get install redis-server php-redis
  2. Verify Redis installed.

     $ redis-server --version
     Redis server v=5.0.x
  3. Start and enable Redis to run on boot.

     $ sudo systemctl start redis-server
     $ sudo systemctl enable redis-server
  4. Verify Redis is running.

     $ sudo systemctl status redis-server
  5. Change directory to /etc/redis/ and edit redis.conf.

     $ cd /etc/redis/
     $ sudo nano redis.conf
  6. Uncomment unixsocket and unixsocketperm. Change unixsocketperm to 770.

     unixsocket /var/run/redis/redis-server.sock
     unixsocketperm 770
  7. Restart Redis.

     $ sudo systemctl restart redis-server
  8. Add www-data to the redis group.

     $ sudo usermod -a -G redis www-data
  9. Change directory to /var/www/nextcloud/config/ and edit config.php.

     $ cd /var/www/nextcloud/config/
     $ sudo nano config.php
  10. Append the following configuration parameters to the $CONFIG array.

    'memcache.distributed' => '\OC\Memcache\Redis',
    'memcache.locking' => '\OC\Memcache\Redis',
    'redis' => [
            'host'      => '/run/redis/redis-server.sock',
            'port'      => 0,
    ],
  11. Restart php7.4-fpm to apply changes.

    $ sudo systemctl restart php7.4-fpm 
  12. NextCloud should now be using Redis as a cache.

Configure SSL

A secure connection to NextCloud ensures encrypted communication. This is crucial for production servers exposed to the internet to maximize security.

  1. Change directory to /etc/nginx/sites-available/ and edit nextcloud.

     $ cd /etc/nginx/sites-available/
     $ sudo nano nextcloud
  2. At the bottom of the file, add the following server block code. Replace example.com with your domain.

     server {
             listen 80;
             listen [::]:80;
             server_name example.com;
             # Redirect non-HTTPS traffic to HTTPS
             return 301 https://$server_name:443$request_uri;
     }
  3. At the top of the file, add the following configuration in the original server block. Replace example.com with your domain.

     -- original --
     server {
             listen 80;
             listen [::]:80;
             server_name _;
    
             root /var/www/nextcloud;
             index index.php index.html /index.php$request_uri;
             ...
     }
     -- new --
     server {
             listen 443 ssl http2;
             listen [::]:443 ssl http2;
             server_name example.com; 
    
             ssl_certificate /path/to/ssl/certificate.pem;
             ssl_certificate_key /path/to/ssl/certificate.key;
    
             root /var/www/nextcloud;
             index index.php index.html /index.php$request_uri;
             ...
     }
  4. In the same server block, under the location ~ \.php(?:$|/) block, add the fastcgi_param HTTPS on; module. It should look like the following.

     -- original --
     location ~ \.php(?:$|/) {
             fastcgi_split_path_info ^(.+?\.php)(\/.*|)$;
             set $path_info $fastcgi_path_info;
             try_files $fastcgi_script_name =404;
             ...
     }
     -- new --
     location ~ \.php(?:$|/) {
             fastcgi_split_path_info ^(.+?\.php)(\/.*|)$;
             set $path_info $fastcgi_path_info;
             try_files $fastcgi_script_name =404;
             # Enable HTTPS
             fastcgi_param HTTPS on;
             ...
     }
  5. Restart Nginx to apply changes.

     $ sudo systemctl restart nginx 
  6. NextCloud should now be communicating through HTTPS.

Conclusion

You should have a working NextCloud server. For more information, refer to the official NextCloud documentation.