Community Blog Install NextCloud on CentOS 7 using Alibaba Cloud ECS

Install NextCloud on CentOS 7 using Alibaba Cloud ECS

NextCloud is a free and open source self-hosted service that lets you host your files onto your own private server, providing you full control over your data.


By Liptan Biswas, Alibaba Cloud Tech Share Author

NextCloud is a free and open source self-hosted alternative to Dropbox or Google Drive. It lets you host your files onto your own private server, providing you full control over your data. Because of the open architecture of NextCloud, you can use apps to improve its functionality. NextCloud uses the best security practices to secure data and has built-in collaboration and sharing features. You can also turn on the encryption feature, which will encrypt all your data on disk. Apart from hosting files, NextCloud can also be used to store the contacts and make secure audio/video calls. It supports multiple authentication mechanisms and is available in multiple languages. Desktop and mobile applications are also available for multiple platforms to sync your files.


Create a new ECS instance choosing CentOS 7.4 as the operating system. Connect to your ECS instance and log in as the root user. To follow this guide, you will also need a domain name that needs to be pointed towards your ECS instance.

Once you are logged into your CentOS 7 instance, run the following command to update your base system with the latest available packages.

yum -y update

Create a new user.

adduser nextcloud
passwd nextcloud

Add the user to sudo group and switch to the newly created user.

usermod -aG wheel nextcloud
sudo su - nextcloud

Install Nginx with PHP 7

As of now, Nextcloud supports PHP version 7.0 and 7.1. In this tutorial, we will install PHP 7.1. Install EPEL and Remi repository so that we can install the pre-built PHP packages directly.

sudo yum -y install epel-release yum-utils nano unzip
sudo rpm -Uvh http://rpms.remirepo.net/enterprise/remi-release-7.rpm
sudo yum-config-manager --enable remi-php71

Install Nginx web server and PHP 7.1 along with the required PHP modules.

sudo yum -y install nginx php php-fpm php-mysqlnd php-ctype php-dom php-gd php-iconv php-json php-libxml php-mbstring php-posix php-xml php-zip php-openssl php-zlib php-curl php-fileinfo php-bz2 php-intl php-mcrypt php-ftp php-exif php-gmp php-memcached php-imagick

Edit the loaded PHP configuration file.

sudo nano /etc/php.ini

Set the appropriate time zone and memory limit. If you want, you can use -1 as the memory limit, which will remove the limits on the amount of memory a script may consume. Uncomment and set 0 to the value of cgi.fix_pathinfo and increase the file upload limits. Once you have updated the parameters, the updates should look like as shown below.

; Maximum amount of memory a script may consume (128MB)
; http://php.net/memory-limit
memory_limit = 512M

; Defines the default timezone used by the date functions
; http://php.net/date.timezone
date.timezone =Asia/Kolkata


post_max_size = 512M

upload_max_filesize = 512M

Once you have done configuring php.ini, open the php-fpm configuration file.

sudo nano /etc/php-fpm.d/www.conf

Look for the user and group parameters and change it from apache to nginx. Find listen = file to comment it out and append listen = /var/run/php-fpm/php-fpm.sock just below it. Finally, uncomment listen.owner and change its value from nobody to nginx. Once you have updated the parameters, the updates should look like as shown below.

user = nginx
group = nginx


;listen =
listen = /var/run/php-fpm/php-fpm.sock


listen.owner = nginx
listen.group = nginx

Also, search for the following line and uncomment them to enable php environment variables.

env[PATH] = /usr/local/bin:/usr/bin:/bin
env[TMP] = /tmp
env[TMPDIR] = /tmp
env[TEMP] = /tmp

Save the file and exit from the editor. Now create a new directory to store the PHP session data.

sudo mkdir -p /var/lib/php/session
sudo chown nginx:nginx -R /var/lib/php/session/

Set appropriate permission and ownership to php-fpm socket file.

sudo chown nginx:nginx /var/run/php-fpm/php-fpm.sock
sudo chmod 660 /var/run/php-fpm/php-fpm.sock

Now, start php-fpm and enable it to automatically start at boot time.

sudo systemctl restart php-fpm
sudo systemctl enable php-fpm

Also, start Nginx web server and enable it to automatically start at boot time.

sudo systemctl restart nginx
sudo systemctl enable nginx

Download NextCloud

Download NextCloud archive on your server.

wget https://download.nextcloud.com/server/releases/nextcloud-12.0.4.zip

You can always find the link to the latest version of the application on the NextCloud download page. Extract the downloaded archive into /usr/share/nginx/nextcloud.

sudo unzip nextcloud-*.zip -d /usr/share/nginx

Create a new directory to store the data.

sudo mkdir /usr/share/nginx/nextcloud/data

Provide appropriate ownership of the files.

sudo chown -R nginx:nginx /usr/share/nginx/nextcloud

All the files of NextCloud has been placed on the server successfully.

Setup SSL

In this tutorial, we will use the free SSL certificate generated by Let's Encrypt CA. However, business users should consider using Alibaba Cloud SSL Certificates Service to achieve a high level of security and reliability.

Certbot is the client application for generating Let's Encrypt free SSL certificates. Install Certbot.

sudo wget https://dl.eff.org/certbot-auto -O /usr/bin/certbot
sudo chmod a+x /usr/bin/certbot

For generating Let's Encrypt certificate, the domain must be pointed towards the ECS instance. If the certbot client could not resolve the domain name to your ECS instance, certificate won't be issued. In that case, make sure that the domain is pointed towards the ECS instance and wait for the DNS to propagate before making the certificate request again.

Generate the SSL certificate for your domain.

sudo certbot certonly --webroot -w /usr/share/nginx/html -d files.example.com

Replace files.example.com with your actual domain name. Provide your email address and accept the license to proceed further. If the certificates are successfully generated, you should see the following output.

 - Congratulations! Your certificate and chain have been saved at:
   Your key file has been saved at:
   Your cert will expire on 2018-03-26. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot
   again. To non-interactively renew *all* of your certificates, run
   "certbot renew"
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

Create a new Nginx server block for virtual hosting of the NextCloud application.

sudo nano /etc/nginx/conf.d/files.example.com.conf

Populate the file with the following configuration.

upstream php-handler {
    server unix:/var/run/php-fpm/php-fpm.sock;

server {
    listen 80;
    server_name files.example.com;
    return 301 https://$server_name$request_uri;

server {
    listen 443 ssl;
    server_name files.example.com;

    ssl_certificate  /etc/letsencrypt/live/files.example.com/fullchain.pem;
    ssl_certificate_key  /etc/letsencrypt/live/files.example.com/privkey.pem;

    add_header Strict-Transport-Security "max-age=15768000;
    includeSubDomains; preload;";
    add_header X-Content-Type-Options nosniff;
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Robots-Tag none;
    add_header X-Download-Options noopen;
    add_header X-Permitted-Cross-Domain-Policies none;

    root /usr/share/nginx/nextcloud/;

    location = /robots.txt {
        allow all;
        log_not_found off;
        access_log off;

    location = /.well-known/carddav {
      return 301 $scheme://$host/remote.php/dav;
    location = /.well-known/caldav {
      return 301 $scheme://$host/remote.php/dav;

    client_max_body_size 512M;
    fastcgi_buffers 64 4K;

    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;    

    error_page 403 /core/templates/403.php;
    error_page 404 /core/templates/404.php;

    location / {
        rewrite ^ /index.php$uri;

    location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)/ {
        deny all;
    location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) {
        deny all;

    location ~ ^/(?:index|remote|public|cron|core/ajax/update|status|ocs/v[12]|updater/.+|ocs-provider/.+|core/templates/40[34])\.php(?:$|/) {
        include fastcgi_params;
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
        fastcgi_param HTTPS on;
        fastcgi_param modHeadersAvailable true;
        fastcgi_param front_controller_active true;
        fastcgi_pass php-handler;
        fastcgi_intercept_errors on;
        fastcgi_request_buffering off;

    location ~ ^/(?:updater|ocs-provider)(?:$|/) {
        try_files $uri/ =404;
        index index.php;

    location ~* \.(?:css|js)$ {
        try_files $uri /index.php$uri$is_args$args;
        add_header Cache-Control "public, max-age=7200";
        add_header Strict-Transport-Security "max-age=15768000;
        includeSubDomains; preload;";
        add_header X-Content-Type-Options nosniff;
        add_header X-XSS-Protection "1; mode=block";
        add_header X-Robots-Tag none;
        add_header X-Download-Options noopen;
        add_header X-Permitted-Cross-Domain-Policies none;
        access_log off;

    location ~* \.(?:svg|gif|png|html|ttf|woff|ico|jpg|jpeg)$ {
        try_files $uri /index.php$uri$is_args$args;
        access_log off;

Make sure to replace all occurrences of files.example.com with your actual domain name. The above configuration includes Gzip compression config, which dynamically compresses the data before sending to the browser. It also includes security and browser caching configurations. Restart the Nginx web server to so that the changes can take effect.

sudo systemctl restart nginx

Setting Up MySQL Database

For hosting the MySQL database, you have two options here. If you want to use a high-performance database server to host the database, you can choose ApsaraDB database instance. If you are a small team and not looking for a pre-optimized database server, you can host the MySQL on the same ECS instance on which NextCloud is installed. This tutorial covers both the installation methods. Based on your choice of the database server, choose any of the database methods described in the tutorial.

Setting up MySQL database on ApsaraDB RDS instance

Using an ApsaraDB RDS instance of MySQL has many benefits over the self-hosted version of MySQL. It is very easy to deploy and provides ease of management with high-performance features such as SQL and parameter optimization.

To create a new ApsaraDB MySQL instance, go to your RDS console and click on Create Instance button. Choose your payment method, region, and zone. Create the RDS instance in the same region and zone where the ECS instance of NextCloud is created. Choose MySQL 5.6 as the database engine. Choose the instance type, for a small team 1GB instance should be enough. Choose the required storage space and network. It is important that you choose the same VPC network and VSwitch in which the ECS instance is running otherwise you will get errors while connecting to the database instance.

Once, you have created the RDS instance wait for few minutes to let it start. Once the instance has successfully started, click on the Manage link to go to the instance's management panel.


On basic information interface, click on the Set whitelist link.


You will be taken to Security tab. Click on Add a Whitelist Group. Provide a group name and enter the private IP address or Intranet address of the ECS instance on which you are running the NextCloud. You can find the private IP address of the ECS instance on your ECS dashboard.


Now, create a new database user for NextCloud database. Navigate to Accounts tab from the sidebar and click on Create Account button. Provide and database username and a password. Make a note of the username and password as we will require that later in the tutorial.


Once an account is created, navigate to Databases tab and click on Create Database button. Provide the name of the database and select the username from the list of accounts. Select Read/Write access checkbox. Make sure to choose "utf8mb4" as the character set. This will enable emoji support in NextCloud.


Now head back to the Basic Information tab from the sidebar and you will see the Intranet address of your RDS instance.


Make a note of the Intranet address which is pointing towards your RDS instance. Now skip the next section of setting up MySQL database server on the ECS instance and proceed to the web-based installation.

Setting up Database server on ECS instance

If you do not want to use ApsaraDB for MySQL database server, you can also install MariaDB into your system. MariaDB is an open source fork of MySQL. Add the repository for the latest version of MariaDB.

echo "[mariadb]
name = MariaDB
baseurl = http://yum.mariadb.org/10.2/centos7-amd64
gpgcheck=1" | sudo tee /etc/yum.repos.d/mariadb.repo

Install the MariaDB server and Client.

sudo yum -y install MariaDB-server MariaDB-client

Start MariaDB database server and enable it to automatically start at boot time by running.

sudo systemctl start mariadb
sudo systemctl enable mariadb

Set your root password and secure your MariaDB instance by running.

sudo mysql_secure_installation

Login to your MySQL database server as root user.

mysql -u root -p

Run the following queries to create a new database and a database user for the Nextcloud application.

CREATE DATABASE nextcloud CHARACTER SET utf8 COLLATE utf8_general_ci;
CREATE USER 'nextcloud'@'localhost' IDENTIFIED BY 'Password123';
GRANT ALL PRIVILEGES ON nextcloud.* TO 'nextcloud'@'localhost';

Replace Password123 with some strong password in above query. Database for Nextcloud is created. Proceed to install the application using the web-based installer.

Web-based Installation

Open your favorite browser and go to https://files.example.com and you should see the following web page.


Specify the administrator account details and expand the Storage & database options. Select the MySQL/MariaDB database type and provide the database username, password and the name of the database. If you are using ApsaraDB than provide the intranet address along with the port number "3306" as the hostname. For example, my hostname is "rm-gs50djs5qdna771jd.mysql.singapore.rds.aliyuncs.com:3306". If you have chosen to install the MariaDB server on your ECS instance, use "localhost:3306" as the hostname. Click on Finish setup button once done.

The installer will now write the database. Once NextCloud is successfully installed, you will be taken to its default dashboard.


Head out to the administrative panel and tweak the setting according to your requirements.

Configure Cron Job

By default, NextCloud is configured to use web-based Cron method in which Cron is automatically executed when you open the Nextloud web interface. If the web interface is not accessed for long periods, scheduled tasks are not executed. To make sure that scheduled tasks are regularly executing, you can make a Cron job entry. Open the crontab file for user nginx.

sudo crontab -u nginx -e

Populate the file with.

*/15 * * * * php -f /usr/share/nginx/nextcloud/cron.php

This will automatically execute the scheduled tasks of Nextcloud every fifteen minutes.

Since we have used Let's Encrypt SSL certificates to secure the site. Let's Encrypt provides the certificates for 3 months only. It is recommended to set up a Cron job for automatically renewing the certificates.

Open the crontab file for the root user.

sudo crontab -e

Now add the following line to the file.

0 12 * * 1 /usr/bin/certbot renew --quiet

The above Cron job will run the Certbot client every Monday on 12:00. If the certificates are due for expiry, it will automatically renew them.


And that's it! You should now have a fully functional cloud storage on Alibaba Cloud ECS with NextCloud. In my tutorial, I described in detail the necessary steps to set up NextCloud on CentOS 7.4. I have also provided several configuration options for you, so that you can optimize the installation for your applications. If you're looking to build a robust and enterprise-grade solution, I recommend you to perform the previous installations with Alibaba Cloud products, such as the Alibaba Cloud SSL Certificates Service and ApsaraDB for RDS.

0 1 1
Share on

Alibaba Clouder

2,600 posts | 750 followers

You may also like