Basic Installation Step

Getting the machine up-to-date

sudo apt autoremove (removes unused apps)
sudo apt update
sudo apt upgrade

Installing Apache - the webserver

sudo apt install apache2
systemctl start apache2
systemctl enable apache2 (start apache2 on boot)



If you’ve configured the server right, you should be able to go to your machine’s IP (you can get this via hostname -I) in the browser of your choice and see the “Apache2 Ubuntu Default Page”

Installing MariaDB - the database

sudo apt install mariadb-server
mysql_secure_installation



This will prompt you to login to MariaDB. Since we don’t have a password, just hit enter to set one up. After that, just accept all of the prompts and you’re set.

Installing phpMyAdmin

sudo apt install php libapache2-mod-php php-mysql
sudo apt install phpmyadmin


You should follow all of the default steps, just make sure that you set the webserver as apache2 and you’ll be good



sudo ln -s /etc/phpmyadmin/apache.conf /etc/apache2/conf-available/phpmyadmin.conf
a2enconf phpmyadmin
service apache2 reload
systemctl reload apache2


Now, if you go to 192.168.something.whatever/phpmyadmin/ (your computer’s IP) you should see the phpMyAdmin login page; however, you should not login yet.

Configuring MariaDB

mariadb

CREATE DATABASE nextcloud;
CREATE USER nextcloud IDENTIFIED BY 'Password'; # but with your password
GRANT USAGE ON *.* TO [email protected] IDENTIFIED BY 'Password'; # again, your password
GRANT ALL privileges ON nextcloud.* TO [email protected];
FLUSH PRIVILEGES;
quit;

Now you should be able to login on the myphpadmin forum with the nextcloud as the username, and the password you just set up as the password.

Installing PHP & Libraries

sudo apt install php-gd php-json php-mysql php-curl php-mbstring php-intl php-imagick php-xml php-zip

Installing Nextcloud

wget https://download.nextcloud.com/server/releases/latest.tar.bz2
tar -xvf latest.tar.bz2
cd nextcloud
mv ./* /var/www/html/
mv ./.htaccess /var/www/html
mv ./.user.ini /var/www/html
cd /var/www/html
chown -R www-data:www-data ./*
chown www-data:www-data .htaccess
chown www-data:www-data .user.ini

Now if you go to 192.168.something.whatever you’ll get the Nextcloud page BUT DO NOT LOGIN / CREATE ACCOUNT. You need to set up encryption.

Setting up Encryption

sudo apt install certbot
sudo apt install python-certbot-apache

nano /etc/apache2/sites-available/000-default.conf and uncomment and change ServerName to whatever domain you’re using, e.g. cloud.mehvix.com



Then you need to point your domain at your server and open your server to the external access. You’ll first need to port forward your server (you can find the ip via hostname -I) to port 443, and then create an A record under your domain’s DNS settings pointing at your external IP (found via dig +short myip.opendns.com @resolver1.opendns.com)



NOTE: If you’re using Cloudflare, you have to disable Universal SSL for Nextcloud to work



systemctl restart apache2
certbot --apache

This will prompt you to autoredirect from http to https. Your choice, but I'd go ahead and choose redirect.

Setting up Storage/Login

For security reasons, it’s a good idea to have the data folder outside of the web root (/var/www/) I already set up my drives/raid config, so all I had to do was create and mount a partition:
mkdir /media/nextcloud-data/
chown www-data:www-data /media/nextcloud-data/
mkfs.ext4 /dev/sda
mount /dev/sda /media/nextcloud-data/

Then to set up automount, sudo blkid and grab the UUID of the partition, sudo nano /etc/fstab and add

UUID=[YOUR UUID] /media/nextcloud-data ext4 defaults 0 0

After that, you can go ahead to the Nextcloud page, create an account (you will use this for all Nextcloud logins). Make sure to change the data folder to /media/nextcloud-data/ or whatever dir you are using, then enter the MariaDB user/password.

Now you’ve got yourself a Nextcloud Server! However, there are still a couple things that you still need to configure which I’ll cover in the following section.

Securing Nextcloud

If you head to https://yournextcloud.com/settings/admin/overview you’ll see all security and setup warnings. Here’s how you fix the ones that I encountered:

The PHP memory limit is below the recommended value of 512MB.

nano /etc/php/7.4/apache2/php.ini

upload_max_filesize = 512M
memory_limit = 512M
post_max_size = 512M

systemctl restart apache2

The “Strict-Transport-Security” HTTP header is not set to at least “15552000” seconds. For enhanced security, it is recommended to enable HSTS as described in the security tips.

nano /etc/apache2/sites-available/000-default-le-ssl.conf

Add the following under ServerName:

<IfModule mod_headers.c>
    Header always set Strict-Transport-Security "max-age=15552000; includeSubDomains; preload"
</IfModule>

a2enmod headers
systemctl restart apache2

Your web server is not properly set up to resolve “/.well-known/[caldav][carddav]“. Further information can be found in the documentation

nano /etc/apache2/sites-available/000-default-le-ssl.conf

Add the following under ServerName:

<Directory /var/www/html/>
	Options +FollowSymLinks
	AllowOverride All
</Directory>

systemctl restart apache2

No memory cache has been configured. To enhance performance, please configure a memcache, if available. Further information can be found in the documentation

sudo apt install php-apcu
nano /var/www/html/config/config.php
'memcache.local' => '\OC\Memcache\APCu'

sudo nano /etc/php/7./mods-available/apcu.ini
apc.enable_cli=1

systemctl restart apache2

The PHP OPcache is not properly configured

nano /etc/php/7.4/apache2/php.ini
The following are default settings, consider checking out this blog for information on what each parameter means

opcache.enable=1
opcache.enable_cli=1
opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=10000
opcache.revalidate_freq=1
opcache.save_comments=1

systemctl restart apache2

Some columns in the database are missing a conversion to big int

sudo -u www-data php /var/www/html/occ db:convert-filecache-bigint

The database is missing some indexes

sudo -u www-data php /var/www/html/occ db:add-missing-indices

MySQL is used as database but does not support 4-byte characters

First, update MariaDB:
nano /etc/mysql/my.cnf

[mysqld]
innodb_file_per_table=1

systemctl restart mariadb
mariadb

ALTER DATABASE nextcloud CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
use nextcloud;
set global innodb_large_prefix=on;
set global innodb_file_format=Barracuda;
quit;

Then, update Nextcloud:
sudo -u www-data php /var/www/html/occ config:system:set mysql.utf8mb4 --type boolean --value="true"
sudo -u www-data php /var/www/html/occ maintenance:repair

Further Securing & Optimization

There are various other actions you can take to ensure that both your os and nextcloud are secure. I’ll be covering the one’s found on this wiki page.

Give PHP read access to /dev/urandom

On my system this ended up breaking Nextcloud, but I’ll keep it in here because it’s in the Nextcloud docs. If you’re site breaks, you should try commenting out open_basedir
sudo nano /etc/php/7.4/apache2/php.ini
Add open_basedir = /dev/urandom
systemctl restart apache2

Install and Tune PHP-FPM

sudo apt-get install php-fpm
a2enmod proxy_fcgi setenvif
a2enconf php7.4-fpm
systemctl reload apache2
nano /etc/php/7.4/fpm/pool.d/www.conf and add the following:

pm = dynamic
pm.max_children = 120
pm.start_servers = 12
pm.min_spare_servers = 6
pm.max_spare_servers = 18
pm.max_requests = 1000


Note that these are the recommended settings for 4GB total/1GB database and should be modified for your system.

Quality of Life Changes + Apps

While theses tips aren’t needed for security, they’re nice to have.

Removing /index.php from every URL

nano /var/www/html/config/config.php

'htaccess.RewriteBase' => '/'

sudo -u www-data php /var/www/html/occ maintenance:update:htaccess
systemctl restart apache2

Increasing the max file size

nano /etc/php/7.4/apache2/php.ini

upload_max_filesize = 16G
post_max_size = 16G
max_input_time = 3600
max_execution_time = 3600
upload_tmp_dir = /var/big_temp_files/

nano /var/www/html/.user.ini

upload_max_filesize = 16G
post_max_size = 16G

chown www-data:www-data /media/big_temp_files/

Solving “Index column size too large. The maximum column size is 767 bytes.”

mariadb

set global innodb_file_format = BARRACUDA
set global innodb_large_prefix = ON
set global innodb_file_per_table = ON
set global innodb_default_row_format = 'DYNAMIC'
quit

nano /etc/mysql/my.cnf

innodb_file_per_table=1
innodb-file-format=barracuda
innodb-file-per-table=ON
innodb-large-prefix=ON
innodb_default_row_format = 'DYNAMIC'

systemctl restart mariadb

Fixing right click not working (How to manually install an addon)

This is fixed, but I figured I'd keep it in anyways

cd /var/www/html/apps/
wget --load-cookies /tmp/cookies.txt "https://docs.google.com/uc?export=download&confirm=$(wget --quiet --save-cookies /tmp/cookies.txt --keep-session-cookies --no-check-certificate 'https://docs.google.com/uc?export=download&id=1usRzYpaOVFwKn63xrCrtJTHuLpMXQz_j' -O- | sed -rn 's/.*confirm=([0-9A-Za-z_]+).*/\1\n/p')&id=1usRzYpaOVFwKn63xrCrtJTHuLpMXQz_j" -O rclick && rm -rf /tmp/cookies.txt
rm -rf files_rightclick/
unzip rclick
rm rclick
systemctl restart apache2

Then make sure that you re-enable the right click app too. If that doesn’t work, try sudo apt-get install php-ldap

systemctl restart apache2

Set timezone

nano /var/www/html/config/config.php
Find your timezone in the ones avaliabe here

'logtimezone' => 'America/Chicago',

nano /etc/php/7.4/apache2/php.ini

date.timezone = America/Chicago,

Change default files for new users

All files that are created for a user can be found in /var/www/html/core/skeleton/

Common Issues & Fixes

Transering [file] - server replied: [nothing]

sudo -u www-data php /var/www/html/occ files:scan --all

Files aren’t showing up for [user]

sudo chown -R www-data:www-data [data mount location]/[user]
sudo -u www-data php /var/www/html/occ files:scan --[user]

Transfeing [file] - server replied: Forbidden (Sabre\DAV\Exception\Forbidden)

sudo rm [username]/uploads

Home storage for user [user] not writable

sudo chown -R www-data:www-data [data mount location]/[user]

---

Backing Up

Turn on maintenance:
cd /var/www/html/
sudo -u www-data php occ maintenance:mode --on

Copy Files:
cd /var/www/
rsync -Aavx html/ backupdir/html_bkup_`date +"%Y%m%d"`/


Backup MariaDB:
mysqldump --single-transaction -u [nextcloud] -p[password] nextcloud > backupdir/sqlbkp_`date +"%Y%m%d"`.bak


Turn off maintenance:
cd /var/www/html/
sudo -u www-data php occ maintenance:mode --off

Updating

- Go to https://cloud.dns.com/settings/admin/overview and select the version you want
- Follow the steps, make sure not to touch anything while updating
- systemctl restart apache2
- Double check the ‘Security & setup warnings’ (also on .../admin/overview)
- Verify your server's security
- Congrads!