Nextcloud is a FOSS solution for cloud storage, among other capabilities such as email, notes, calender, tasks. Pretty much every thing that you can do with the Google suite, you can use Nextcloud for. For that reasoning,
Basic Installation Step
We'll start by getting the machine up-to-date and setting up our webserver, apache, with the following commands
$ sudo apt update && sudo apt upgrade
$ sudo apt install apache2
$ systemctl start apache2 # turns on apache now
$ systemctl enable apache2 # auto-start apache2 on boot
If you’ve configured the server right, you should be able to
go to the server’s IP (which you can find by running
hostname -I
) in the browser of your choice and
see the "Apache2 Ubuntu Default Page."
Next, we can install MariaDB — the database.
$ sudo apt install mariadb-server
$ mysql_secure_installation
During the installation you'll be prompted to login (but we
don't have an account setup yet!). Just hit enter and it'll
prompt you to create an account. After that, accept all of
the recommended prompt options and you’re set. After we've
installed the database, we'll then configure it for
NextCloud. (note that "Password
" will be your
own password created during the installation phase).
$ mariadb
CREATE DATABASE nextcloud;
CREATE USER nextcloud IDENTIFIED BY 'Password';
GRANT USAGE ON *.* TO nextcloud@localhost IDENTIFIED BY 'Password';
GRANT ALL privileges ON nextcloud.* TO nextcloud@localhost;
FLUSH PRIVILEGES;
quit;
While it's not necessary for NextCloud, we'll install phpMyAdmin so that we have a GUI interface to our database.
$ sudo apt install php libapache2-mod-php php-mysql
$ sudo apt install phpmyadmin
When running through the installation dialog, make sure to
set the webserver as apache2
and follow all of
the default options. After the install, we will symlink the
apache and phpMyAdmin configurations which, in tandem with
the following commands, will enable phpMyAdmin.
$ sudo ln -s /etc/phpmyadmin/apache.conf /etc/apache2/conf-available/phpmyadmin.conf
$ a2enconf phpmyadmin
$ service apache2 reload
$ systemctl reload apache2
Now, (fingers crossed) if you go to
[server ip]/phpmyadmin/
you'll see the phpMyAdmin login page;
however, do not login yet. We do not have
encryption enabled on the web page yet so your ISP or server
can theoretically see what you send. We'll setup encryption
down the road in a bit.
But first, we'll install the required PHP (libraries)
$ sudo apt install php-gd php-json php-mysql php-curl php-mbstring php-intl php-imagick php-xml php-zip
as well as NextCloud itself
$ wget https://download.nextcloud.com/server/releases/latest.tar.bz2
$ tar -xvf latest.tar.bz2 # unzip
$ cd nextcloud
$ mv ./* /var/www/html/ # move all files to webserver directory
$ mv ./.htaccess /var/www/html # move hidden dot files
$ mv ./.user.ini /var/www/html # ^
$ cd /var/www/html
$ chown -R www-data:www-data ./* # Recursively set www-data as owner of files
$ chown www-data:www-data .htaccess # ^ for hidden dot files
$ chown www-data:www-data .user.ini # ^
Now if you go to
[server ip]
you’ll get the Nextcloud page
BUT DO NOT LOGIN / CREATE ACCOUNT. Again,
we still need to set up encryption!
To set up encryption, we'll use certbot which we'll install and configure like this:
$ sudo apt install certbot
$ sudo apt install python-certbot-apache
$ vim /etc/apache2/sites-available/000-default.conf
then uncomment and change ServerName
to
whatever domain you’re using, such as
cloud.mehvix.com
.
Next, 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 that if you’re using Cloudflare,
you have to disable Universal SSL for Nextcloud to work.
After making your server open to the WWW, you can finish setting up certbot by restarting the webserver and activating certbot
$ systemctl restart apache2
$ certbot --apache
Following the set up dialog will prompt you to auto-redirect from http to https. Your choice, but I'd go ahead and choose redirect. Now you can login on the myPhpAdmin/Nextcloud securely!
We're not done yet though. 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, I did sudo blkid
to grab
the UUID of the partition which I then appended to
/etc/fstab
:
UUID=[YOUR UUID] /media/nextcloud-data ext4 defaults 0 0
From there, 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 username (nextcloud) and
password.
Now you’ve got yourself a working 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 most common:
The PHP memory limit is below the recommended value of 512MB.
vim /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.
vim /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
vim /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
vim /var/www/html/config/config.php
'memcache.local' => '\OC\Memcache\APCu'
sudo vim /etc/php/7./mods-available/apcu.ini
apc.enable_cli=1
systemctl restart apache2
The PHP OPcache is not properly configured
vim /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:
vim /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
Transferring [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]
Transferring [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]
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 vim /etc/php/7.4/apache2/php.ini
Addopen_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
vim /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
vim /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
vim /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/
vim /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
vim /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')& 1usRzYpaOVFwKn63xrCrtJTHuLpMXQz_j" -O rclick && rm -rf /tmp/cookies.txt $ rm -rf files_rightclick/ $ unzip rclick $ rm rclick $ systemctl restart apache2
systemctl restart apache2
Set timezone
vim /var/www/html/config/config.php
Find your timezone in the ones available here.'logtimezone' => 'America/Chicago',
vim /etc/php/7.4/apache2/php.ini
date.timezone = America/Chicago,
sudo -u www-data php occ config:system:set logtimezone --value "Los_Angeles"
Change default files for new users
All files that are created for a user can be found in
/var/www/html/core/skeleton/
Backing Up
$ cd /var/www/html/
$ sudo -u www-data php occ maintenance:mode --no-check-certificate
$ cd /var/www/
$ rsync -Aavx html/ backupdir/html_bkup_`date +"%Y%m%d"`/
$ mysqldump --single-transaction -u [nextcloud] -p[password] nextcloud > backupdir/sqlbkp_`date +"%Y%m%d"`.bak
$ cd /var/www/html/
$ sudo -u www-data php occ maintenance:mode --off