Nextcloud
Nextcloud 20 manual installation guide
By jplee ~ Published – 2020/12/22
By following this guide you will be able to install and setup the latest Nextcloud 20 version on to Ubuntu 20.04 LTS 64Bit (ARM64 and or AMD64), Nginx 1.19, TLSv1.3, PHP7.4, MariaDB 10.5, Redis. UFW, and Fail2ban. After the installment you will be able to receive an A+ from Nextcloud and Qualys SSL Labs. You will be able to request and implement your own SSL Certificates from Let’s Encrypt for your website name. You only have to make changes to all the Red marked values like your.website.com, 192.168.0.x based on your network environment.
Table of Content
1. Prepare and Configure Server for Nextcloud
Change to sudo privileged mode in localhost Terminal:
sudo -s
Setup your server for the installation:
apt install -y curl gnupg2 git lsb-release, ssl-cert, ca-certificates apt-transport-https tree locate software-properties-common dirmngr screen htop net-tools zip unzip bzip2, ffmpeg, ghostscript libfile-fcntllock-perl libfontconfig1 libfuse2
Add it to the System for more Software Repositories (software sources) to add to the current Releases of the individual packages to install can. Go to the following directory:
cd /etc/apt/sources.list.d
If it is necessary, first of all, the DNS resolution:
rm -f /etc/resolv.conf
ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf
systemctl restart systemd-resolved.service
Add new Software Reposities:
echo "deb [arch=amd64,arm64] http://nginx.org/packages/mainline/ubuntu $(lsb_release -cs) nginx" | tee nginx.list
echo "deb [arch=amd64,arm64] http://ppa.launchpad.net/ondrej/php/ubuntu $(lsb_release -cs) main" | tee php.list
echo "deb [arch=amd64,arm64] http://ftp.hosteurope.de/mirror/mariadb.org/repo/10.5/ubuntu $(lsb_release -cs) main" | tee mariadb.list
Download the required keys to trust all the new sources:
curl -fsSL https://nginx.org/keys/nginx_signing.key | sudo apt-key add -
apt-key adv --recv-keys --keyserver hkps://keyserver.ubuntu.com:443 4F4EA0AAE5267A6C
apt-key adv --recv-keys --keyserver hkps://keyserver.ubuntu.com:443 0xF1656F24C74CD1D8
Update your server and generate self signed certificates:
apt update && apt upgrade -y
make-ssl-cert generate-default-snakeoil -y
To ensure that there are no relics of previous installations will interfere with the operation of the web server, we will remove these:
apt remove nginx nginx-extras nginx-common nginx-full -y --allow-change-held-packages
2. Install and Configure NGINX 1.19
First make sure Apache(2) isn’t running, otherwise NGINX will not start because the required port 80 will be in use by Apache(2):
systemctl stop apache2.service && systemctl disable apache2.service
apt install nginx -y
systemctl enable nginx.service
Change the default nginx configuration:
mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak && touch /etc/nginx/nginx.conf
vim /etc/nginx/nginx.conf
Paste all the following rows into the new file. Substitute the red marked parameters for your network environment:
user www-data;
worker_processes auto;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
multi_accept on; use epoll;
}
http {
server_names_hash_bucket_size 64;
upstream php-handler {
server unix:/run/php/php7.4-fpm.sock;
}
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log warn;
set_real_ip_from 127.0.0.1;
set_real_ip_from 192.168.0.0/24;
# please customize the ip-range properly
real_ip_header X-Forwarded-For;
real_ip_recursive on;
include /etc/nginx/mime.types;
#include /etc/nginx/proxy.conf;
#include /etc/nginx/ssl.conf;
#include /etc/nginx/header.conf;
#include /etc/nginx/optimization.conf;
default_type application/octet-stream;
sendfile on;
send_timeout 3600;
tcp_nopush on;
tcp_nodelay on;
open_file_cache max=500 inactive=10m;
open_file_cache_errors on;
keepalive_timeout 65;
reset_timedout_connection on;
server_tokens off;
#resolver IP is your DNS e.g. your FritzBox/Router
#resolver 192.168.0.1 valid=30s;
#resolver 127.0.0.53 valid=30s; *is recommended but requires a valid DNS configuration*
resolver 127.0.0.53 valid=30s;
resolver_timeout 5s;
include /etc/nginx/conf.d/*.conf;
}
Test and restart the nginx webserver
nginx -t && service nginx restart
Create four folders and apply the appropriate permissions:
mkdir -p /var/nc_data /var/www/letsencrypt/.well-known/acme-challenge /etc/letsencrypt/rsa-certs /etc/letsencrypt/ecc certs
chown -R www-data:www-data /var/nc_data /var/www
The above setup and installation of nginx has been completed, and we will install PHP 7.4 in the next following steps.
About Us
Ahuitech is a website prepared especially for the latest version of Nextcloud updates. This is a step by step manual guide.
Nextcloud is a self-hosted productivity application software platform on Ubuntu or other Linux systems that keeps you in total control of all your Data! You can use this latest Nextcloud version for free. Create your awesome remarkable cloud system today!
Privacy Policy – You act on your own accord and risk – No Warranty.
Recent Posts
3. Install and Configure PHP 7.4 (fpm)
The PHP 7.4 repository was enabled in above section. Therefore, in the below steps we will install PHP as needed by and recommended for Nextcloud:
apt update && apt install-y php7.4-fpm php7.4-DG php7.4-mysql php7.4-curl php7.4-xml php7.4-zip php7.4-intl php7.4-mbstring php7.4-json php7.4-bz2 php7.4-ldap php7.4-apcu php7.4-bcmath php7.4-gmp php7.4-imagick php7.4-smbclient imagemagick ldap-utils
Fantastic, PHP 7.4 is already installed. Now, verify your timezone settings:
date
In order to properly customize the date follow as shown below for Taipei:
timedatectl set-timezone Asia/Taipei Backup and then tweak PHP for optimization and security reasons:
cp /etc/php/7.4/fpm/pool.d/www.conf /etc/php/7.4/fpm/pool.d/www.conf.bak
cp /etc/php/7.4/cli/php.ini /etc/php/7.4/cli/php.ini.bak
cp /etc/php/7.4/fpm/php.ini /etc/php/7.4/fpm/php.ini.bak
cp /etc/php/7.4/fpm/php-fpm.conf /etc/php/7.4/fpm/php-fpm.conf.bak
cp /etc/php/7.4/mods-available/apcu.ini /etc/php/7.4/mods-available/apcu.ini.bak
cp /etc/ImageMagick-6/policy.xml /etc/ImageMagick-6/policy.xml.bak
sed -i “s/;env\[HOSTNAME\] = /env[HOSTNAME] = /” /etc/php/7.4/fpm/pool.d/www.conf
sed -i “s/;env\[TMP\] = /env[TMP] = /” /etc/php/7.4/fpm/pool.d/www.conf
sed -i “s/;env\[TMPDIR\] = /env[TMPDIR] = /” /etc/php/7.4/fpm/pool.d/www.conf
sed -i “s/;env\[TEMP\] = /env[TEMP] = /” /etc/php/7.4/fpm/pool.d/www.conf
sed -i “s/;env\[PATH\] = /env[PATH] = /” /etc/php/7.4/fpm/pool.d/www.conf
sed -i “s/pm.max_children =.*/pm.max_children = 120/” /etc/php/7.4/fpm/pool.d/www.conf
sed -i “s/pm.start_servers =.*/pm.start_servers = 12/” /etc/php/7.4/fpm/pool.d/www.conf
sed -i “s/pm.min_spare_servers =.*/pm.min_spare_servers = 6/” /etc/php/7.4/fpm/pool.d/www.conf
sed -i “s/pm.max_spare_servers =.*/pm.max_spare_servers = 18/” /etc/php/7.4/fpm/pool.d/www.conf
sed -i “s/;pm.max_requests =.*/pm.max_requests = 1000/” /etc/php/7.4/fpm/pool.d/www.conf
sed -i “s/output_buffering =.*/output_buffering = ‘Off’/” /etc/php/7.4/cli/php.ini
sed -i “s/max_execution_time =.*/max_execution_time = 3600/” /etc/php/7.4/cli/php.ini
sed -i “s/max_input_time =.*/max_input_time = 3600/” /etc/php/7.4/cli/php.ini
sed -i “s/post_max_size =.*/post_max_size = 10240M/” /etc/php/7.4/cli/php.ini
sed -i “s/upload_max_filesize =.*/upload_max_filesize = 10240M/” /etc/php/7.4/cli/php.ini
sed -i “s/;date.timezone.*/date.timezone = Asia\/\Taipei/” /etc/php/7.4/cli/php.ini
sed -i “s/memory_limit = 128M/memory_limit = 512M/” /etc/php/7.4/fpm/php.ini
sed -i “s/output_buffering =.*/output_buffering = ‘Off’/” /etc/php/7.4/fpm/php.ini
sed -i “s/max_execution_time =.*/max_execution_time = 3600/” /etc/php/7.4/fpm/php.ini
sed -i “s/max_input_time =.*/max_input_time = 3600/” /etc/php/7.4/fpm/php.ini
sed -i “s/post_max_size =.*/post_max_size = 10240M/” /etc/php/7.4/fpm/php.ini
sed -i “s/upload_max_filesize =.*/upload_max_filesize = 10240M/” /etc/php/7.4/fpm/php.ini
sed -i “s/;date.timezone.*/date.timezone = Asia\/\Taipei/” /etc/php/7.4fpm/php.ini
sed -i “s/;session.cookie_secure.*/session.cookie_secure = True/” /etc/php/7.4/fpm/php.ini
sed -i “s/;opcache.enable=.*/opcache.enable=1/” /etc/php/7.4/fpm/php.ini
sed -i “s/;opcache.enable_cli=.*/opcache.enable_cli=1/” /etc/php/7.4/fpm/php.ini
sed -i “s/;opcache.memory_consumption=.*/opcache.memory_consumption=128/” /etc/php/7.4/fpm/php.ini
sed -i “s/;opcache.interned_strings_buffer=.*/opcache.interned_strings_buffer=8/” /etc/php/7.4/fpm/php.ini
sed -i “s/;opcache.max_accelerated_files=.*/opcache.max_accelerated_files=10000/” /etc/php/7.4/fpm/php.ini
sed -i “s/;opcache.revalidate_freq=.*/opcache.revalidate_freq=1/” /etc/php/7.4/fpm/php.ini
sed -i “s/;opcache.save_comments=.*/opcache.save_comments=1/” /etc/php/7.4/fpm/php.ini
sed -i ‘$aapc.enable_cli=1’ /etc/php/7.4/mods-available/apcu.ini
sed -i “s/rights=\”none\” pattern=\”HP\”/rights=\”read|write\” pattern=\”HP\”/” /etc/ImageMagick-6/policy.xml
sed -i “s/rights=\”none\” pattern=\”EPS\”/rights=\”read|write\” pattern=\”EPS\”/” /etc/ImageMagick-6/policy.xml
sed -i “s/rights=\”none\” pattern=\”PDF\”/rights=\”read|write\” pattern=\”PDF\”/” /etc/ImageMagick-6/policy.xml
sed -i “s/rights=\”none\” pattern=\”XPS\”/rights=\”read|write\” pattern=\”XPS\”/” /etc/ImageMagick-6/policy.xml
Restart php7.4-fpm And Nginx Services:
service php7.4-fpm restart
service nginx restart
PHP7.4-fpm has been successfully installed and configured. We will proceed ahead with the installation of MariaDB 10.5:
4. Install and Configure MariaDB 10.5
Install MariaDB by issuing the following command:
apt update && apt install mariadb-server -y
Verify your database server version:
mysql --version
A mysql version like the following below results
mysql Ver 15.1 Distrib 10.5.8-MariaDB, for debian-linux-gnu (x86_64) using readline 5.2
Setup and configure your MariaDB by following the below commands:
mysql_secure_installation
Enter current password for root (enter for none): or type the password for mysql database.
Switch to unix_socket authentication [Y/n] Y
Set root password? [Y/n] Y
During installation you may have entered a password for MariaDB. Therefore, you may be asked to change or keep the password again…
Remove anonymous users? [Y/n] Y
Disallow root login remotely? [Y/n] Y
Remove test database and access to it? [Y/n] Y
Reload privilege tables now? [Y/n] Y
The following will configure MariaDB for Nextcloud:
service mysql stop
mv /etc/mysql/my.cnf /etc/mysql/my.cnf.bak
vim /etc/mysql/my.cnf
Paste all of the following into my.cnf
[client]
default-character-set = utf8mb4
port = 3306
socket = /var/run/mysqld/mysqld.sock
[mysqld_safe]
log_error = /var/log/mysql/mysql_error.log
nice = 0
socket = /var/run/mysqld/mysqld.sock
[mysqld]
basedir = /usr
bind-address = 127.0.0.1
binlog_format = ROW
bulk_insert_buffer_size = 16M
character-set-server = utf8mb4
collation-server = utf8mb4_general_ci
concurrent_insert = 2
connect_timeout = 5
datadir = /var/lib/mysql
default_storage_engine = InnoDB
expire_logs_days = 7
general_log_file = /var/log/mysql/mysql.log
general_log = 0
innodb_buffer_pool_size = 1024M
innodb_buffer_pool_instances = 1
innodb_flush_log_at_trx_commit = 2
innodb_log_buffer_size = 32M
innodb_max_dirty_pages_pct = 90
innodb_file_per_table = 1
innodb_open_files = 400
innodb_io_capacity = 4000
innodb_flush_method = O_DIRECT
key_buffer_size = 128M
lc_messages_dir = /usr/share/mysql
lc_messages = en_US
log_bin = /var/log/mysql/mariadb-bin
log_bin_index = /var/log/mysql/mariadb-bin.index
log_error = /var/log/mysql/mysql_error.log
log_slow_verbosity = query_plan
log_warnings = 2
long_query_time = 1
max_allowed_packet = 16M
max_binlog_size = 100M
max_connections = 200
max_heap_table_size = 64M
myisam_recover_options = BACKUP
myisam_sort_buffer_size = 512M
port = 3306
pid-file = /var/run/mysqld/mysqld.pid
query_cache_limit = 2M
query_cache_size = 64M
query_cache_type = 1
query_cache_min_res_unit = 2k
read_buffer_size = 2M
read_rnd_buffer_size = 1M
skip-external-locking
skip-name-resolve
slow_query_log_file = /var/log/mysql/mariadb-slow.log
slow-query-log = 1
socket = /var/run/mysqld/mysqld.sock
sort_buffer_size = 4M
table_open_cache = 400
thread_cache_size = 128
tmp_table_size = 64M
tmpdir = /tmp
transaction_isolation = READ-COMMITTED
#unix_socket = OFF
user = mysql
wait_timeout = 600
[mysqldump]
max_allowed_packet = 16M
quick
quote-names
[isamchk]
key_buffer = 16M
Restart MariaDB and login to MariaDB:
service mysql restart
mysql -uroot -p
Create the following:
- The Database – nextcloud,
- The User – nextcloud,
- The Password – nextcloud,
CREATE DATABASE nextcloud CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
CREATE USER nextcloud@localhost identified by 'nextcloud';
GRANT ALL PRIVILEGES on nextcloud.* to nextcloud@localhost;
FLUSH privileges;
quit;
Verify the above transaction with the following command:
mysql -h localhost -uroot -p -e "SELECT @@TX_ISOLATION; SELECT SCHEMA_NAME 'database', default_character_set_name 'charset', DEFAULT_COLLATION_NAME 'collation' FROM information_schema.SCHEMATA WHERE SCHEMA_NAME='nextcloud'"
We have finished installing and configuring mysql and proceed with the installation of redis-server
5. Install and Configure Redis-server
By installing Redis-server you will optimize Nextcloud performance and reduce the load on the MariaDB database.
apt update
apt install redis-server php7.4-redis -y
Change the redis-server configuration and set the group membership properly:
cp /etc/redis/redis.conf /etc/redis/redis.conf.bak
sed -i "s/port 6379/port 0/" /etc/redis/redis.conf
sed -i s/\#\ unixsocket/\unixsocket/g /etc/redis/redis.conf
sed -i "s/unixsocketperm 700/unixsocketperm 770/" /etc/redis/redis.conf
sed -i "s/# maxclients 10000/maxclients 512/" /etc/redis/redis.conf
usermod -aG redis www-data
cp /etc/sysctl.conf /etc/sysctl.conf.bak
sed -i '$avm.overcommit_memory = 1' /etc/sysctl.conf
Now reboot your server:
reboot now
We are now ready to install and configure Nextcloud.
6. Install and Configure Nextcloud 20 (enabled SSL, A+)
First create all the configuration and webhost files. Change into sudo mode and create the /etc/nginx/conf.d/nextcloud.conf file:
sudo -s
[ -f /etc/nginx/conf.d/default.conf ] && mv /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf.bak
touch /etc/nginx/conf.d/default.conf
vim /etc/nginx/conf.d/nextcloud.conf
Paste all the following into nextcloud.conf and customize the red marked parameters based on your network environment:
server {
server_name your.website.com;
listen 80 default_server;
listen [::]:80 default_server;
location ^~ /.well-known/acme-challenge {
proxy_pass http://127.0.0.1:81;
proxy_set_header Host $host;
}
location / {
return 301 https://$host$request_uri;
}
}
server {
server_name your.website.com;
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
root /var/www/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;
}
#SOCIAL app enabled? Please uncomment the following row
#rewrite ^/.well-known/webfinger /public.php?service=webfinger last;
#WEBFINGER app enabled? Please uncomment the following two rows.
#rewrite ^/.well-known/host-meta /public.php?service=host-meta last;
#rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json last;
client_max_body_size 10240M;
location / {
rewrite ^ /index.php;
}
location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)/ {
deny all;
}
location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) {
deny all;
}
location ^~ /apps/rainloop/app/data {
deny all;
}
location ~ \.(?:flv|mp4|mov|m4a)$ {
mp4;
mp4_buffer_size 100M;
mp4_max_buffer_size 1024M;
fastcgi_split_path_info ^(.+?.php)(\/.*|)$;
set $path_info $fastcgi_path_info;
try_files $fastcgi_script_name =404;
include fastcgi_params;
include php_optimization.conf;
}
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;
include php_optimization.conf;
}
location ~ ^\/(?:updater|oc[ms]-provider)(?:$|\/) {
try_files $uri/ =404;
index index.php;
}
location ~ \.(?:css|js|woff2?|svg|gif|map|png|html|ttf|ico|jpg|jpeg)$ {
try_files $uri /index.php$request_uri;
access_log off;
expires 360d;
}
} Create the file letsencrypt.conf:
vim /etc/nginx/conf.d/letsencrypt.conf
Paste the following into file letsencrypt.conf:
server
{
server_name 127.0.0.1;
listen 127.0.0.1:81 default_server;
charset utf-8;
location ^~ /.well-known/acme-challenge
{
default_type text/plain;
root /var/www/letsencrypt;
}
}
Create the file ssl.conf:
vim /etc/nginx/ssl.conf
Paste the following into file ssl.conf
ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;
ssl_trusted_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
#ssl_certificate /etc/letsencrypt/rsa-certs/fullchain.pem;
#ssl_certificate_key /etc/letsencrypt/rsa-certs/privkey.pem;
#ssl_certificate /etc/letsencrypt/ecc-certs/fullchain.pem;
#ssl_certificate_key /etc/letsencrypt/ecc-certs/privkey.pem;
#ssl_trusted_certificate /etc/letsencrypt/ecc-certs/chain.pem;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
ssl_session_timeout 1d; ssl_session_cache shared:SSL:50m;
ssl_session_tickets off; ssl_protocols TLSv1.3 TLSv1.2;
ssl_ciphers 'TLS-CHACHA20-POLY1305-SHA256:TLS-AES-256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384';
ssl_ecdh_curve X448:secp521r1:secp384r1:prime256v1;
ssl_prefer_server_ciphers on;
ssl_stapling on;
ssl_stapling_verify on;
Create the file proxy.conf:
vim /etc/nginx/proxy.conf
Paste the following into file proxy.conf
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Protocol $scheme;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-Server $host;
proxy_connect_timeout 3600;
proxy_send_timeout 3600;
proxy_read_timeout 3600;
proxy_redirect off;
Create the file header.conf:
vim /etc/nginx/header.conf
Paste the following into file header.conf
add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;";
add_header X-Robots-Tag none always;
add_header X-Download-Options noopen always;
add_header X-Permitted-Cross-Domain-Policies none always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "no-referrer" always;
add_header X-Frame-Options "SAMEORIGIN" always;
Create the file optimization.conf:
vim /etc/nginx/optimization.conf
Paste the following into file optimization.conf
fastcgi_hide_header X-Powered-By;
fastcgi_read_timeout 3600;
fastcgi_send_timeout 3600;
fastcgi_connect_timeout 3600;
fastcgi_buffers 64 64K;
fastcgi_buffer_size 256k;
fastcgi_busy_buffers_size 3840K;
fastcgi_cache_key $http_cookie$request_method$host$request_uri;
fastcgi_cache_use_stale error timeout invalid_header http_500;
fastcgi_ignore_headers Cache-Control Expires Set-Cookie;
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;
gzip_disable "MSIE [1-6]\.";
Create the file php_optimization.conf:
vim /etc/nginx/php_optimization.conf
Paste the following into file php_optimization.conf
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $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;
fastcgi_cache_valid 404 1m;
fastcgi_cache_valid any 1h;
fastcgi_cache_methods GET HEAD;
To enhance the security just create your own dhparam.pem file:
openssl dhparam -out /etc/ssl/certs/dhparam.pem 4096
Please be patient, it will take awhile depending on your hardware. If your dhparam.pem exists please customize and restart your nginx webserver:
sed -i s/\#\include/\include/g /etc/nginx/nginx.conf
service nginx restart
Download and extract the Nextcloud software:
cd /usr/local/src
wget https://download.nextcloud.com/server/releases/latest.tar.bz2
tar -xjf latest.tar.bz2 -C /var/www && chown -R www-data:www-data /var/www/ && rm -f latest.tar.bz2
Create a technical user to install and renew your ssl certificates from Let’s Encrypt using acme:
Please make sure that your Server is both using Port 80/TCP as well as Port 443/TCP is reachable from the outside. The Create and Update of Let’s encrypt certificates is strictly about http and Port 80! For the certificate handling, we will now create a dedicated user and add it to the www-data group:
adduser --disable-login acmeuser
usermod -a -G www-data acmeuser
To request ssl certificates from letsencrypt just install acme and follow the below commands:
su -acmeuser
curl https://get.acme.sh | sh
exit
Create three folders to request and store your ssl certificates. Please remember to substitute your.website.com):
sudo -s
mkdir -p /var/www/letsencrypt/.well-known/acme-challenge /etc/letsencrypt/rsa-certs /etc/letsencrypt/ecc-certs
chmod -R 775 /var/www/letsencrypt /etc/letsencrypt && chown -R www-data:www-data /var/www/ /etc/letsencrypt
exit
Go back into acmeuser and request the SSL certificates. Remember to replace your.website.com with your Domain:
su -acmeuser
acme.sh --issue -d your.website.com --keylength 4096 -w /var/www/letsencrypt --key-file /etc/letsencrypt/rsa-certs/privkey.pem --ca-file /etc/letsencrypt/rsa-certs/chain.pem --cert-file /etc/letsencrypt/rsa-certs/cert.pem --fullchain-file /etc/letsencrypt/rsa-certs/fullchain.pem
acme.sh --issue -d your.website.com --keylength ec-384 -w /var/www/letsencrypt --key-file /etc/letsencrypt/ecc-certs/privkey.pem --ca-file /etc/letsencrypt/ecc-certs/chain.pem --cert-file /etc/letsencrypt/ecc-certs/cert.pem --fullchain-file /etc/letsencrypt/ecc-certs/fullchain.pem
exit
Apply the appropiate permissions using a permissions.sh script file:
sudo -s
vim /root/permissions.sh
Paste the following into file permissions.sh
#!/bin/bash
find /var/www/ -type f -print0 | xargs -0 chmod 0640
find /var/www/ -type d -print0 | xargs -0 chmod 0750
chmod -R 775 /var/www/letsencrypt
chmod -R 775 /etc/letsencrypt
chown -R www-data:www-data /var/www/
chown -R www-data:www-data /var/nc_data/
chmod 0644 /var/www/nextcloud/.htaccess
chmod 0644 /var/www/nextcloud/.user.ini
exit 0
Change permissions of the file as executable and execute the file.
chmod +x /root/permissions.sh
./root/permissions.sh
Remove the links to your self signed certificates and restart nginx:
sed -i '/ssl-cert-snakeoil/d' /etc/nginx/ssl.conf
sed -i s/\#\ssl/\ssl/g /etc/nginx/ssl.conf
service nginx restart
In order to apply to renew the SSL certificates automatically, as well as the necessary web-server restart to initiate the following ‘renewal’ script:
vim /root/renewal.sh
#!/bin/bash
sudo -u acmeuser "/home/acmeuser/.acme.sh"/acme.sh --cron --home "/home/acmeuser/.acme.sh"
/usr/sbin/service nginx stop
/usr/sbin/service mysql restart
/usr/sbin/service redis-server restart
/usr/sbin/service php7.4-fpm restart
/usr/sbin/service nginx restart
exit 0
Save this script and mark it as “executable”.
chmod +x /root/renewal.sh
Now we need to disable the default ‘acme’ – Cronjob
crontab -e -u acmeuser
# 44 0 * * * "/home/acmeuser/.acme.sh"/acme.sh --cron --home "/home/acmeuser/.acme.sh" > /dev/null Now create a new cron job
crontab -e
@weekly /root/renewal.sh 2>&1
From now on every week looking for renewable SSL certificates, renewal of the SSL certificates updated, and the web server restarted automatically!
Now, we can proceed with installing your Nextcloud software silently by issuing the following occ command statement:
sudo -u www-data php /var/www/nextcloud/occ maintenance:install --database "mysql" --database-name "nextcloud" --database-user "nextcloud" --database-pass "nextcloud" --admin-user "YourNextcloudAdmin" --admin-pass "YourNextcloudAdminPasssword" --data-dir "/var/nc_data"
For Your Information:
- –database-name “nextcloud” This should be the same as your created database in step 3 above.
- –database-user “nextcloud” This should be the same as your created database in step 3 above.
- –database-pass “nextcloud” This should be the same as your created database in step 3 above.
- –admin-user “YourNextcloudAdmin” This is your choice nameuser.
- –admin-pass “YourNextcloudAdminPassword” This is your choice password.
First, set your trusted domain:
sudo -u www-data php /var/www/nextcloud/occ config:system:set trusted_domains 0 --value=your.website.com
sudo -u www-data php /var/www/nextcloud/occ config:system:set trusted_domains 1 --value=localhost
sudo -u www-data php /var/www/nextcloud/occ config:system:set trusted_domains 2 --value=127.0.0.1
Second, set your domain as overwrite.cli.url:
sudo -u www-data php /var/www/nextcloud/occ config:system:set overwrite.cli.url --value=https://your.website.com Next, enhance your Nextcloud configuration – back up the current config.php and issue the statements below:
sudo -u www-data cp /var/www/nextcloud/config/config.php /var/www/nextcloud/config/config.php.bak
Add-on to your Nextcloud ‘config.php’:
sudo -u www-data sed -i 's/^[ ]*//' /var/www/nextcloud/config/config.php
sudo -u www-data sed -i '/);/d' /var/www/nextcloud/config/config.php
sudo -u www-data cat <>/var/www/nextcloud/config/config.php 'activity_expire_days' => 14, 'auth.bruteforce.protection.enabled' => true, 'blacklisted_files' => array ( 0 => '.htaccess', 1 => 'Thumbs.db', 2 => 'thumbs.db', ), 'cron_log' => true, 'enable_previews' => true, 'enabledPreviewProviders' => array ( 0 => 'OC\Preview\PNG', 1 => 'OC\Preview\JPEG', 2 => 'OC\Preview\GIF', 3 => 'OC\Preview\BMP', 4 => 'OC\Preview\XBitmap', 5 => 'OC\Preview\Movie', 6 => 'OC\Preview\PDF', 7 => 'OC\Preview\MP3', 8 => 'OC\Preview\TXT', 9 => 'OC\Preview\MarkDown', ), 'filesystem_check_changes' => 0, 'filelocking.enabled' => 'true', 'htaccess.RewriteBase' => '/', 'integrity.check.disabled' => false, 'knowledgebaseenabled' => false, 'logfile' => '/var/nc_data/nextcloud.log', 'loglevel' => 2, 'logtimezone' => 'Asia/Taipei', 'log_rotate_size' => 104857600, 'maintenance' => false, 'memcache.local' => '\OC\Memcache\APCu', 'memcache.locking' => '\OC\Memcache\Redis', 'overwriteprotocol' => 'https', 'preview_max_x' => 1024, 'preview_max_y' => 768, 'preview_max_scale_factor' => 1, 'redis' => array ( 'host' => '/var/run/redis/redis-server.sock', 'port' => 0, 'timeout' => 0.0, ), 'quota_include_external_storage' => false, 'share_folder' => '/Shares', 'skeletondirectory' => '', 'theme' => '', 'trashbin_retention_obligation' => 'auto, 7', 'updater.release.channel' => 'stable', ); EOF sudo -u www-data sed -i "s/.*dbhost.*/\'dbhost\' \=\>\ \'localhost\:\/var\/run\/mysqld\/mysqld\.sock\'\,/g" /var/www/nextcloud/config/config.php
Edit Nextclouds file ‘.user.ini’ and adjust some Nextcloud apps as user www-data:
sudo -u www-data sed -i "s/output_buffering=.*/output_buffering='Off'/" /var/www/nextcloud/.user.ini
sudo -u www-data php /var/www/nextcloud/occ app:disable survey_client
sudo -u www-data php /var/www/nextcloud/occ app:disable firstrunwizard
sudo -u www-data php /var/www/nextcloud/occ app:enable admin_audit
sudo -u www-data php /var/www/nextcloud/occ app:enable files_pdfviewer
Your Nextcloud is now installed, optimized and secured. Lets issue a command to finally restart all relevant services:
service nginx stop
service php7.4-fpm stop
service mysql restart
service php7.4-fpm restart
service redis-server restart
service nginx restart
Add a Nextcloud cronjob for www-data:
crontab -u www-data -e
Paste the following into the end of the file:
*/5 * * * * php -f /var/www/nextcloud/cron.php > /dev/null 2>&1
sudo -u www-data php /var/www/nextcloud/occ background:cron
7. Security (Fail2ban and UFW)
Install and configure fail2ban to secure your server:
apt update && apt install fail2ban -y
Paste all the following into /etc/fail2ban/filter.d/nextcloud.conf
vim /etc/fail2ban/filter.d/nextcloud.conf
[Definition]
failregex=^{"reqId":".*","remoteAddr":".*","app":"core","message":"Login failed: '.*' \(Remote IP: ''\)","level":2,"time":".*"}$
^{"reqId":".*","level":2,"time":".*","remoteAddr":".*","user,:".*","app":"no app in context".*","method":".*","message":"Login failed: '.*' \(Remote IP: ''\)".*}$
^{"reqId":".*","level":2,"time":".*","remoteAddr":".*","user":".*","app":".*","method":".*","url":".*","message":"Login failed: .* \(Remote IP: \).*}$
Create a new file /etc/fail2ban/jail.d/nextcloud.local
vim /etc/fail2ban/jail.d/nextcloud.local
Paste all the following into nextcloud.local
[nextcloud]
backend = auto
enabled = true
port = 80,443
protocol = tcp
filter = nextcloud
maxretry = 10
bantime = 3600
findtime = 3600
logpath = /var/nc_data/nextcloud.log
[nginx-http-auth]
enabled = true
Restart the fail2ban-service and verify the fail2ban-status:
service fail2ban restart
fail2ban-client status nextcloud
We will install and customize the ufw – (uncomplicated firewall):
apt install ufw -y
ufw allow 80/tcp
ufw allow 443/tcp
ufw allow 22/tcp
ufw allow proto tcp from 192.168.1.0/24 to any port 22
You set the Firewall Logging to “medium” and prevent not defined for incoming Connections.
ufw logging medium
ufw default deny incoming
ufw enable
service ufw restart
Congratulations, you now have your own personal data on your own secured Nextcloud system!
At Ahuitech, we create clouds systems that allow you to have complete control of your Data. You are always in Control!

