Cara install Nextcloud di Ubuntu 18.04 serta cara optimalisasi
Tags: nextcloud, ubuntu, linux, indonesia
Published: 2021-03-13 18:36:51

Nextcloud adalah sebuah software open-source yang mirip dengan Dropbox, dan banyak digunakan sebagai solusi alternatif dari Google Drive, Dropbox, dan sejenisnya.

File yang ada di PC atau laptop akan secara otomatis sinkron dengan yang ada di Nextcloud server, yang bisa diakses lewat perangkat yang lain termasuk smartphone. Pada artikel ini akan dijelaskan cara instalasi Nextcloud pada Ubuntu 18.04 dengan stack yang menggunakan Nginx, MariaDB, PHP7.4, dan Let's Encrypt SSL.

## Persiapan

Pastikan semua package yang dibutuhkan sudah terpasang dengan cara menjalankan perintah berikut. 
```
sudo apt install wget unzip zip libmagickcore-dev -y
```

## Instalasi Nginx

Jalankan perintah dibawah ini untuk mulai instalasi Nginx.
```
sudo apt install nginx -y
```

Sesudah instalasi, aktifkan Nginx dengan perintah dibawah ini, jalankan secara berurutan.
```
sudo systemctl start nginx
sudo systemctl enable nginx
```

Lalu cek apakah Nginx berjalan dengan normal.
```
sudo systemctl status nginx
```

Bisa juga dilihat pada artikel berikut.

{% post https://dev.to/erolj/cara-install-nginx-di-ubuntu-18-04-43k2 %}


## Instalasi dan Konfigurasi PHP 7.4

### Instalasi PHP 7.4

Versi terbaru PHP adalah `7.4`, sedangkan bawaan untuk Ubuntu 18.04 adalah `7.2`. Supaya bisa dipasang versi terakhir, maka diperlukan konfigurasi awal sebagai berikut.

Jalankan perintah berikut.
```
sudo add-apt-repository ppa:ondrej/php
sudo add-apt-repository ppa:ondrej/nginx
```

Tekan tombol <kbd>Enter</kbd> jika pada layar muncul pertanyaan yang harus dikonfirmasi.

Kemudian jalankan perintah berikut, untuk melakukan update/upgrade pada Ubuntu.
```
sudo apt update -y && sudo apt upgrade -y
```

Untuk mulai instalasi PHP 7.4 beserta komponen yang dibutuhkan oleh Nextcloud, jalankan perintah ini.
```
sudo apt install php7.4 php7.4-fpm php7.4-bcmath php7.4-gmp php7.4-curl php7.4-cli php7.4-mysql php7.4-gd php7.4-common php7.4-xml php7.4-json php7.4-intl php7.4-imagick php7.4-dev php7.4-common php7.4-mbstring php7.4-zip php7.4-soap php7.4-bz2 -y
```

Lalu cek versi PHP yang sedang aktif dengan cara berikut.
```
php -version
```

Output yang diharapkan terlihat seperti ini.
```
PHP 7.4.16 (cli) (built: Mar  5 2021 07:54:20) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
    with Zend OPcache v7.4.16, Copyright (c), by Zend Technologies
```

### Konfigurasi PHP 7.4

Lakukan konfigurasi yang pertama terhadap file `php.ini` yang berlokasi di `/etc/php/7.4/fpm/` dengan perintah berikut.
```
sudo nano /etc/php/7.4/fpm/php.ini
```

Dalam editor tekan <kbd>Ctrl+W</kbd> lalu ketik `date.timezone` akhiri dengan tekan <kbd>Enter</kbd>. Lakukan cara ini untuk memudahkan pencarian sebuah teks tertentu dalam sebuah dokumen yang panjang, jika menggunakan editor `nano`.

Cari dan ubah baris berikut.
```
;date.timezone =
;cgi.fix_pathinfo=1
memory_limit = 128M
;opcache.enable=1
;opcache.memory_consumption=128
;opcache.interned_strings_buffer=8
;opcache.max_accelerated_files=10000
;opcache.revalidate_freq=2
;opcache.save_comments=1
```

Sehingga menjadi seperti ini.
```
date.timezone = Asia/Makassar
cgi.fix_pathinfo=0
memory_limit = 512M
opcache.enable=1
opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=10000
opcache.revalidate_freq=1
opcache.save_comments=1
```

Simpan perubahan pada file tersebut. Lanjutkan untuk mengubah konfigurasi pada file `php.ini` yang berlokasi di `/etc/php/7.4/cli/` dengan perintah berikut.
```
sudo nano /etc/php/7.4/cli/php.ini
```

Cari dan ubah baris berikut.
```
;date.timezone =
;cgi.fix_pathinfo=1
;opcache.enable=1
;opcache.memory_consumption=128
;opcache.interned_strings_buffer=8
;opcache.max_accelerated_files=10000
;opcache.revalidate_freq=2
;opcache.save_comments=1
```

Sehingga menjadi seperti ini.
```
date.timezone = Asia/Makassar
cgi.fix_pathinfo=0
opcache.enable=1
opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=10000
opcache.revalidate_freq=1
opcache.save_comments=1
```

Jangan lupa untuk menyimpan perubahannya.

Perubahan konfigurasi file berikutnya adalah terhadap file `www.conf`, jalankan perintah berikut.
```
sudo nano /etc/php/7.4/fpm/pool.d/www.conf
```

Kemudian cari dan edit baris berikut ini.
```
;env[HOSTNAME] = $HOSTNAME
;env[PATH] = /usr/local/bin:/usr/bin:/bin
;env[TMP] = /tmp
;env[TMPDIR] = /tmp
;env[TEMP] = /tmp
pm.max_children = 1
pm.start_servers = 2
pm.min_spare_servers = 2
pm.max_spare_servers = 4
```
Menjadi seperti dibawah ini.
```
env[HOSTNAME] = $HOSTNAME
env[PATH] = /usr/local/bin:/usr/bin:/bin
env[TMP] = /tmp
env[TMPDIR] = /tmp
env[TEMP] = /tmp
pm.max_children = 120
pm.start_servers = 12
pm.min_spare_servers = 6
pm.max_spare_servers = 18
```

Simpan perubahannya dan keluar dari editor. Selanjutnya restart `php7.4-fpm` dengan cara berikut. Jalankan secara berurutan.
```
sudo systemctl restart php7.4-fpm
sudo systemctl enable php7.4-fpm
```

Verifikasi apakah php7.4-fpm berjalan dengan seharusnya, jalankan perintah berikut.
```
ss -xa | grep php && sudo systemctl status php7.4-fpm
```

Output yg diharapkan akan terlihat mirip seperti dibawah ini.
```
u_strLISTEN 0       128                        /run/php/php7.4-fpm.sock 1845793                                          * 0
● php7.4-fpm.service - The PHP 7.4 FastCGI Process Manager
   Loaded: loaded (/lib/systemd/system/php7.4-fpm.service; enabled; vendor preset: enabled)
   Active: active (running) since 1min 49s ago
     Docs: man:php-fpm7.4(8)
 Main PID: 3549 (php-fpm7.4)
   Status: "Processes active: 0, idle: 2, Requests: 0, slow: 0, Traffic: 0req/sec"
    Tasks: 3 (limit: 4663)
   CGroup: /system.slice/php7.4-fpm.service
           ├─3549 php-fpm: master process (/etc/php/7.4/fpm/php-fpm.conf)
           ├─3576 php-fpm: pool www
           └─3577 php-fpm: pool www
```

## Instalasi dan konfigurasi MariaDB

### Instalasi MariaDB

Jalankan perintah berikut untuk mulai instalasi MariaDB.
```
sudo apt install mariadb-server -y
```

Lanjutkan dengan mengaktifkan MariaDB, dengan cara jalankan perintah berikut secara berurutan.
```
sudo systemctl start mariadb
sudo systemctl enable mariadb
```

Cek apakah MariaDB berjalan dengan normal.
```
sudo systemctl status mariadb
```

Output yang diharapkan adalah seperti dibawah ini.
```
● mariadb.service - MariaDB 10.1.47 database server
   Loaded: loaded (/lib/systemd/system/mariadb.service; enabled; vendor preset: enabled)
   Active: active (running) since 1min 33s ago
     Docs: man:mysqld(8)
           https://mariadb.com/kb/en/library/systemd/
 Main PID: 20554 (mysqld)
   Status: "Taking your SQL requests now..."
    Tasks: 27 (limit: 4663)
   CGroup: /system.slice/mariadb.service
           └─20554 /usr/sbin/mysqld
```

### Konfigurasi MariaDB

Selanjutnya konfigurasi MariaDB dilakukan dengan perintah berikut ini.
```
sudo mysql_secure_installation
```

Akan terlihat output seperti berikut ini.
```
NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB
      SERVERS IN PRODUCTION USE!  PLEASE READ EACH STEP CAREFULLY!

In order to log into MariaDB to secure it, we'll need the current
password for the root user.  If you've just installed MariaDB, and
you haven't set the root password yet, the password will be blank,
so you should just press enter here.

Enter current password for root (enter for none):
```

Tekan tombol <kbd>Enter</kbd>, sebab ini adalah pertama kalinya MariaDB diinstall, jadi root password masih kosong. Pada langkah berikutnya akan di set.

Pertanyaan selanjutnya akan membantu untuk mengamankan instalasi MariaDB, jawablah dengan menuliskan `Y` dan konfirmasikan dengan tombol <kbd>Enter</kbd>. Daftarkan root password baru, jika ditanyakan pada langkah berikut ini.
```
Set root password? [Y/n] Y
New password:
Re-enter new password:
```

Seluruh proses konfigurasi MariaDB diatas, akan memiliki output akhir kurang lebih seperti ini.
```
NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB
      SERVERS IN PRODUCTION USE!  PLEASE READ EACH STEP CAREFULLY!

In order to log into MariaDB to secure it, we'll need the current
password for the root user.  If you've just installed MariaDB, and
you haven't set the root password yet, the password will be blank,
so you should just press enter here.

Enter current password for root (enter for none):
OK, successfully used password, moving on...

Setting the root password ensures that nobody can log into the MariaDB
root user without the proper authorisation.

Set root password? [Y/n] Y
New password:
Re-enter new password:
Password updated successfully!
Reloading privilege tables..
 ... Success!


By default, a MariaDB installation has an anonymous user, allowing anyone
to log into MariaDB without having to have a user account created for
them.  This is intended only for testing, and to make the installation
go a bit smoother.  You should remove them before moving into a
production environment.

Remove anonymous users? [Y/n] Y
 ... Success!

Normally, root should only be allowed to connect from 'localhost'.  This
ensures that someone cannot guess at the root password from the network.

Disallow root login remotely? [Y/n] Y
 ... Success!

By default, MariaDB comes with a database named 'test' that anyone can
access.  This is also intended only for testing, and should be removed
before moving into a production environment.

Remove test database and access to it? [Y/n] Y
 - Dropping test database...
 ... Success!
 - Removing privileges on test database...
 ... Success!

Reloading the privilege tables will ensure that all changes made so far
will take effect immediately.

Reload privilege tables now? [Y/n] Y
 ... Success!

Cleaning up...

All done!  If you've completed all of the above steps, your MariaDB
installation should now be secure.

Thanks for using MariaDB!
```

### Membuat database data Nextcloud

Login ke MariaDB dengan perintah berikut. Isilah root password ketika diminta, akhiri dengan menekan tombol <kbd>Enter</kbd>.
```
sudo mysql -u root -p
```

Pada terminal akan muncul prompt berikut, jika berhasil masuk.
```
MariaDB [(none)]>
```

Kemudian jalankan perintah dibawah ini secara berurutan. **INGAT**, jangan lupa mengganti `NAMA_DB` dengan nama database yg diinginkan, `DB_USER` dengan username untuk database tersebut, dan `DB_PASS` dengan password untuk database tersebut.
```
create database NAMA_DB;
create user DB_USER@localhost identified by 'DB_PASS';
grant all privileges on NAMA_DB.* to DB_USER@localhost identified by 'DB_PASS';
flush privileges;
```

Output akhirnya akan terlihat kurang lebih seperti berikut ini.
```
MariaDB [(none)]> create database NAMA_DB;
Query OK, 1 row affected (0.00 sec)

MariaDB [(none)]> create user DB_USER@localhost identified by 'DB_PASS';
Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> grant all privileges on NAMA_DB.* to DB_USER@localhost identified by 'DB_PASS';
Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> flush privileges;
Query OK, 0 rows affected (0.00 sec)
```

## Instalasi Let's Encrypt

Jalan perintah berikut untuk mulai instalasi certbot.
```
sudo apt install certbot -y
```

Hentikan Nginx, untuk mencegah kegagalan pendaftaran sertifikat SSL karena belum ada server block rujukan.
```
sudo systemctl stop nginx
```

Untuk memulai proses pendaftaran sertifikat SSL, jalankan perintah dibawah ini. **INGAT**, jangan lupa mengganti `EMAIL_ANDA` dengan alamat email, dan `DOMAIN_ANDA` dengan nama domain yg akan digunakan untuk Nextcloud. Pada artikel ini akan menggunakan domain `nextcloud.contoh.com`.
```
sudo certbot certonly --agree-tos --email EMAIL_ANDA --standalone -d nextcloud.contoh.com
```

Apabila saat eksekusi perintah diatas, kemudian muncul pesan error soal firewall, jangan sungkan untuk menghentikan firewall untuk sementara, jika menggunakan `ufw` jalankan perintah ini.
```
sudo ufw disable
```

Jangan lupa untuk mengaktifkan firewall kembali, apabila pesan error soal firewall sudah tidak ada, dan eksekusi perintah `certbot` diatas berjalan dengan mulus. Aktifkan firewall dengan perintah berikut.
```
sudo ufw enable
```

Proses pendaftaran sertifikat SSL dikatakan berhasil, apabila outputnya terlihat mirip seperti dibawah ini.
```
IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/nextcloud.contoh.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/nextcloud.contoh.com/privkey.pem
   Your cert will expire on 2021-07-28. 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"
 - Your account credentials have been saved in your Certbot
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Certbot so
   making regular backups of this folder is ideal.
 - 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
```

## Instalasi Nextcloud

Buka folder `/var/www` dengan perintah ini.
```
cd /var/www
```

Unduh Nextcloud.
```
sudo wget -q https://download.nextcloud.com/server/releases/latest.zip
```

Jalankan perintah dibawah ini secara berurutan untuk meng-ekstrak file `latest.zip`, sekaligus menyiapkan folder untuk instalasi Nextcloud.
```
sudo unzip -qq latest.zip
sudo chown -R www-data:www-data /var/www/nextcloud
sudo rm -fR latest.zip
```

## Konfigurasi setelah instalasi

### Konfigurasi server block nginx untuk Nextcloud

Jalankan perintah berikut ini.
```
sudo nano /etc/nginx/sites-available/nextcloud
```

Salin dan isi kode dibawah ini, lalu simpan filenya. **INGAT**, jangan lupa mengganti domain `nextcloud.contoh.com` dengan domain Anda.
```
upstream php-handler {
    #server 127.0.0.1:9000;
    server unix:/var/run/php/php7.4-fpm.sock;
}

server {
    listen 80;
    listen [::]:80;
    server_name nextcloud.contoh.com;
    # enforce https
    return 301 https://$server_name:443$request_uri;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name nextcloud.contoh.com;

    # Use Mozilla's guidelines for SSL/TLS settings
    # https://mozilla.github.io/server-side-tls/ssl-config-generator/
    # NOTE: some settings below might be redundant
    ssl_certificate /etc/letsencrypt/live/nextcloud.contoh.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/nextcloud.contoh.com/privkey.pem;

    # Add headers to serve security related headers
    # Before enabling Strict-Transport-Security headers please read into this
    # topic first.
    add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;" always;
    #
    # WARNING: Only add the preload option once you read about
    # the consequences in https://hstspreload.org/. This option
    # will add the domain to a hardcoded list that is shipped
    # in all major browsers and getting removed from this list
    # could take several months.
    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;

    # Remove X-Powered-By, which is an information leak
    fastcgi_hide_header X-Powered-By;

    # Path to the root of your installation
    root /var/www/nextcloud;

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

    # The following 2 rules are only needed for the user_webfinger app.
    # Uncomment it if you're planning to use this app.
    #rewrite ^/.well-known/host-meta /public.php?service=host-meta last;
    #rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json last;

    # The following rule is only needed for the Social app.
    # Uncomment it if you're planning to use this app.
    #rewrite ^/.well-known/webfinger /public.php?service=webfinger last;

    location = /.well-known/carddav {
      return 301 $scheme://$host:$server_port/remote.php/dav;
    }
    location = /.well-known/caldav {
      return 301 $scheme://$host:$server_port/remote.php/dav;
    }
    location ^~ /.well-known            { return 301 /index.php$uri; }

    # set max upload size
    client_max_body_size 512M;
    fastcgi_buffers 64 4K;

    # Enable gzip but do not remove ETag headers
    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;

    # Uncomment if your server is build with the ngx_pagespeed module
    # This module is currently not supported.
    #pagespeed off;

    location / {
        rewrite ^ /index.php;
    }

    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\/.+|oc[ms]-provider\/.+)\.php(?:$|\/) {
        fastcgi_split_path_info ^(.+?\.php)(\/.*|)$;
        set $path_info $fastcgi_path_info;
        try_files $fastcgi_script_name =404;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $path_info;
        fastcgi_param HTTPS on;
        # Avoid sending the security headers twice
        fastcgi_param modHeadersAvailable true;
        # Enable pretty urls
        fastcgi_param front_controller_active true;
        fastcgi_pass php-handler;
        fastcgi_intercept_errors on;
        fastcgi_request_buffering off;
    }

    location ~ ^\/(?:updater|oc[ms]-provider)(?:$|\/) {
        try_files $uri/ =404;
        index index.php;
    }

    # Adding the cache control header for js, css and map files
    # Make sure it is BELOW the PHP block
    location ~ \.(?:css|js|woff2?|svg|gif|map)$ {
        try_files $uri /index.php$request_uri;
        add_header Cache-Control "public, max-age=15778463";
        # Add headers to serve security related headers (It is intended to
        # have those duplicated to the ones above)
        # Before enabling Strict-Transport-Security headers please read into
        # this topic first.
        add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;" always;
        #
        # WARNING: Only add the preload option once you read about
        # the consequences in https://hstspreload.org/. This option
        # will add the domain to a hardcoded list that is shipped
        # in all major browsers and getting removed from this list
        # could take several months.
        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;

        # Optional: Don't log access to assets
        access_log off;
    }

    location ~ \.(?:png|html|ttf|ico|jpg|jpeg|bcmap)$ {
        try_files $uri /index.php$request_uri;
        # Optional: Don't log access to other assets
        access_log off;
    }
}
```

Aktifkan server block ini dengan perintah berikut.
```
sudo ln -s /etc/nginx/sites-available/nextcloud /etc/nginx/sites-enabled/
```

Periksa konfigurasi server block sebelum dijalankan.
```
sudo nginx -t
```

Output yang diharapkan akan terlihat seperti dibawah ini.
```
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
```

Jalankan `nginx` dan `php7.4-fpm` dengan perintah dibawah ini secara berurutan.
```
sudo systemctl restart nginx
sudo systemctl restart php7.4-fpm
```

### Konfigurasi `ufw` firewall

Tambahkan layanan yang terkait dengan Nextcloud pada 'ufw' dengan cara berikut ini.
```
sudo ufw allow ssh
sudo ufw allow http
sudo ufw allow https
sudo ufw reload
```

### Setup Nextcloud via browser

Buka dan akses Nextcloud lewat browser `https://nextcloud.contoh.com`.

![setup-nextcloud-browser](https://cdn.hashnode.com/res/hashnode/image/upload/v1615651042601/P2wxcN1Z3.png)

Isilah semua data yang diminta, dan klik tombol <kbd>Finish Setup</kbd> untuk memulai proses setup. Setelah selesai, berikut adalah tampilan dashboard dari Nextcloud.

![dashboard-nextcloud.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1615651221950/Ybm9BjVnf.png)

Selesai. Selamat mencoba.