Nextcloud Installation on Ubuntu 21.04.4 LTS
Update to PHP 8.1
I needed to install the following packages manually after upgrading Ubuntu to Ubuntu 22.04.1 LTS (jammy).
sudo apt install php8.1-common php8.1-opcache php8.1-readline php8.1-cli php8.1-phpdbg php8.1-imagick php8.1-igbinary php8.1-redis php8.1-mysql php8.1-curl php8.1-xml php8.1-gd php8.1-mbstring php8.1-zip php8.1-bz2 php8.1-intl
The symlinks in /etc/apache2/mods-enabled
need to be adusted for PHP8.1.
cd /etc/apache2/mods-enabled
sudo rm php7.4.conf php7.4.load
sudo ln -s ../mods-available/php8.1.conf php8.1.conf
sudo ln -s ../mods-available/php8.1.load php8.1.load
Any settings which were changed in php ini files to be adjusted for the new PHP
version, e.g. the memory_limit
. See PHP Settings in the
installation section.
cd /etc/php/8.1/apache2
memory_limit = 512M
post_max_size = 10G
upload_max_filesize = 10G
max_input_time = 3600
max_execution_time = 3600
Install Packages
Docs: https://docs.nextcloud.com/server/stable/admin_manual/installation/example_ubuntu.html
sudo apt update
sudo apt install apache2 mariadb-server libapache2-mod-php7.4
sudo apt install php7.4-gd php7.4-mysql php7.4-curl php7.4-mbstring php7.4-intl
sudo apt install php7.4-gmp php7.4-bcmath php-imagick php7.4-xml php7.4-zip
Change MySQL root password.
Note: Instead of using the method below, just run
mysql_secure_installation
. This will prompt you to change the root
password
as well and you should/must(!) absolutely run this command anyway.
Connect to db with default root password root
.
sudo mysql -u root -p
Then change it:
ALTER USER 'root'@'localhost' IDENTIFIED BY 'NEW_SECURE_PASSWORD';
FLUSH PRIVILEGES;
MySQL socket: /run/mysqld/mysqld.sock
Useful commands after logging into DB
SELECT User,Host from mysql.user;
show databases;
use nextcloud; show tables;
For backups with mysqldump
the parameter --default-character-set=utf8mb4
must be used because the database uses utf8mb4
. Otherwise, the backup seems
broken when being restored.
NOT NEEDED. Nextcloud will create the user and database itself.
Create Nextcloud user (change nextcloud_dbuser
and password
):
CREATE USER 'nextcloud_dbuser'@'localhost' IDENTIFIED BY 'password';
CREATE DATABASE IF NOT EXISTS nextcloud CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
GRANT ALL PRIVILEGES ON nextcloud.* TO 'nextcloud_dbuser'@'localhost';
FLUSH PRIVILEGES;
quit;
END NOT NEEDED
Download current nextlcoud release from https://nextcloud.com/install
Check signature
wget https://download.nextcloud.com/server/releases/nextcloud-x.y.z.tar.bz2.asc
wget https://nextcloud.com/nextcloud.asc
gpg --import nextcloud.asc
gpg --verify nextcloud-x.y.z.tar.bz2.asc nextcloud-x.y.z.tar.bz2
Unzip/untar it and copy it to the document root if Apache2 is used.
unzip nextcloud-x.y.z.zip
sudo cp -r nextcloud /var/www/
Generate Apache2 config file: /etc/apache2/sites-available/nextcloud.conf
:
<VirtualHost *:80>
DocumentRoot /var/www/nextcloud/
ServerName server.name.de
<Directory /var/www/nextcloud/>
Require all granted
AllowOverride All
Options FollowSymLinks MultiViews
<IfModule mod_dav.c>
Dav off
</IfModule>
</Directory>
</VirtualHost>
Enable the configuration:
a2ensite nextcloud.conf
Additional Apache2 configurations:
# enable module mod_rewrite
a2enmod rewrite
# recommended:
a2enmod headers env dir mime
# restart apache2
systemctl restart apache2
Apache2 enable SSL
Enable ssl with apache2.
a2enmod ssl
systemctl restart apache2
Install certbot
:
sudo apt install certbot python3-certbot-apache
Get certificate and make sure that the domain is the same domain as specified
in the apache2 configuration as ServerName
.
certbot --apache -d server.name.de
This will also add a corresponding apache nextcloud-le-ssl.conf
file. Add the
HSTS header and a custom error and custom log file for nextcloud.
<IfModule mod_ssl.c>
<VirtualHost *:443>
DocumentRoot /var/www/nextcloud/
ServerName server.name.de
<IfModule mod_headers.c>
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
# optionally with ;preload
# Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
</IfModule>
ErrorLog ${APACHE_LOG_DIR}/nextcloud_error.log
# "combined" also logs the USER_AGENT and the REFERER
CustomLog ${APACHE_LOG_DIR}/nextcloud_access.log combined
...
TODO: Add logrotate config for this log file?
In /etc/apache2/conf-available/security.conf
switch off Apache version
disclosure (ServerTokens
) and do not include information in server-generated
pages (ServerSignature
).
ServerTokens Prod
ServerSignature Off
Nextclour setup
Change the owner and group to www-data
of the /var/www/nextcloud
directory.
sudo chown -R www-data:www-data /var/www/nextcloud/
Finish the Nextcloud setup.
The db user must be root
or some other user who is allowed to create users
and assign privileges. The --admin-user
and --admin-pass
are the
credentials for the new nextcloud admin user who is allowed to install apps and
so on.
cd /var/www/nextcloud/
sudo -u www-data php occ maintenance:install --database "mysql" --database-name "nextcloud" --database-user "root" --database-pass 'root-user-password' --admin-user "nextcloud_adminuser" --admin-pass "nextcloud_adminuser_pw"
Nextcloud Settings
Config.php
Misc settings
Set default phone region in /var/www/nextcloud/config/config.php
.
'default_phone_region' => 'DE',
Better user experience (only used if an invalid value is supplied by the user, otherwise, the user's value is used).
'default_language' => 'de',
'default_locale' => 'de_DE',
Disable the "Help" item in the user menu (top right corner)
'knowledgebaseenabled' => false,
Delete files in trash automatically after 30 days. If space is needed, delete files automatically, too.
'trashbin_retention_obligation' => 'auto, 30',
# check that apps only use public and no private APIs of Nextcloud.
'appcodechecker' => true,
'logtimezone' => 'Europe/Berlin',
# https://docs.nextcloud.com/server/stable/admin_manual/configuration_files/file_versioning.html
#'versions_retention_obligation' => 'auto',
This disables image previews in nextcloud directories. This feature seems to be problematic sometimes (check CVE-2022-24741 and CVE-2021-32802).
'enable_previews' => false,
MariaDB Unix Socket Connection
Use the Unix socket for the MySQL connection.
'dbhost' => 'localhost:/run/mysqld/mysqld.sock',
By default, MariaDB only listens on the Unix socket and localhost, which is
specified by the bind-address
. If this were commented, then MariaDB would
listen on all interfaces. In /etc/mysql/mariadb.conf.d/50-server.cnf
set the
skip-networking
option to prevent MariaDB from binding to a network
interface.
[mysqld]
...
bind-address = 127.0.0.1
skip-networking
Then restart with systemctl restart mariadb
.
Pretty URLs
Add the following for a virtualhost configuration to make URLs pretty (if installed in subdirectory, check here.
'overwrite.cli.url' => 'https://server.name.de',
'htaccess.RewriteBase' => '/',
Then regenerate the .htaccess
file.
sudo -u www-data php /var/www/nextcloud/occ maintenance:update:htaccess
Nextcloud Cronjob for Regular Tasks
Use the cron
feature of the OS.
# get the absolute path of `php`
which php
/usr/bin/php
# edit cron for www-data user
crontab -u www-data -e
Append the following job:
*/5 * * * * /usr/bin/php -f /var/www/nextcloud/cron.php
Nextcloud Apps
Disable apps
- Activity?
- Circles
- Dashboard
- usage survey
- weather status
- user status
Check if the following apps are installed and wanted.
- Calendar
- Contacts
- 2FA
- Brute force limit
PHP Settings
Increase the memory limit to the recommended size in /etc/php/7.4/apache2/php.ini
.
memory_limit = 512M
In the same file increase the maximum file size for uploads and the maximum size of POST data.
post_max_size = 10G
upload_max_filesize = 10G
The following values can be set as well to increase the timeout.
max_input_time = 3600
max_execution_time = 3600
To get SVG support for the PHP module imagick
, install
libmagickcore-6.q16-6-extra
:
sudo apt install libmagickcore-6.q16-6-extra
Memory Caching
Install the required packages for redis
sudo apt install redis-server php-redis
Configure redis in /etc/redis/redis.conf
# do not listen on a tcp socket (value 0)
port 0
# enable unix socket
unixsocket /run/redis/redis-server.sock
# enable password authentication
requirepass LONG_AND_SECURE_PASSWORD
Add the web user www-data
to the redis group that it can write to the unix
socket.
usermod -aG redis www-data
Then restart the redis server and the apache2 service.
sudo systemctl restart redis
sudo systemctl restart apache2
Edit the /var/www/nextcloud/config/config.php
'memcache.local' => '\\OC\\Memcache\\Redis',
// If `memcache.distributed` is not set, it defaults to `memcache.local`
'memcache.locking' => '\\OC\\Memcache\\Redis',
'redis' => [
'host' => '/run/redis/redis-server.sock',
'port' => 0,
//'dbindex' => 0,
'password' => 'LONG_AND_SECURE_PASSWORD',
//'timeout' => 1.5,
],
Go the <your_cloud>.de/settings/admin/overview
and check if everyting worked
and the warning about the memory cache is gone.
Security
See Hardening Guide
Setup Fail2ban for Nextcloud
sudo apt install fail2ban
Create a filter in /etc/fail2ban/filter.d/nextcloud.conf
.
[Definition]
_groupsre = (?:(?:,?\s*"\w+":(?:"[^"]+"|\w+))*)
failregex = ^\{%(_groupsre)s,?\s*"remoteAddr":"<HOST>"%(_groupsre)s,?\s*"message":"Login failed:
^\{%(_groupsre)s,?\s*"remoteAddr":"<HOST>"%(_groupsre)s,?\s*"message":"Trusted domain error.
datepattern = ,?\s*"time"\s*:\s*"%%Y-%%m-%%d[T ]%%H:%%M:%%S(%%z)?"
Create the corresponding jail in /etc/fail2ban/jail.d/nextcloud.local
.
[nextcloud]
backend = auto
enabled = true
port = 80,443
protocol = tcp
filter = nextcloud
maxretry = 10
bantime = 604800
findtime = 43200
logpath = /var/www/nextcloud/data/nextcloud.log
Findtime is 12h (43200) with 10 matches (tries) and bantime is 1 week (604800).
TODO: test the jail
Activate other jails such as botsearch, mail crawler, 404 scanner, ssh jail.
Email setup
sudo apt install sendmail
While this installs, you might see this:
Everything you need to support STARTTLS (encrypted mail transmission
and user authentication via certificates) is installed and configured
but is *NOT* being used.
To enable sendmail to use STARTTLS, you need to:
1) Add this line to /etc/mail/sendmail.mc and optionally
to /etc/mail/submit.mc:
include(`/etc/mail/tls/starttls.m4')dnl
2) Run sendmailconfig
3) Restart sendmail
Then add include(``/etc/mail/tls/starttls.m4')dnl
to both files,
/etc/mail/sendmail.mc
and /etc/mail/submit.mc
and run sendmailconfig
to
reconfigure the mail service.
Finally, configure sendmail
in the /var/www/nextcloud/config/config.php
:
'mail_smtpmode' => 'sendmail',
'mail_smtphost' => '127.0.0.1',
'mail_smtpport' => '25',
'mail_smtptimeout' => 10,
'mail_smtpauthtype' => 'LOGIN',
'mail_sendmailmode' => 'smtp',
'mail_from_address' => 'nextcloud',
'mail_domain' => 'yourdomain.de',
Updating Nextcloud
Web Updates
The web updater can be used. Just click update and wait until it's finished. Then continue to the provided link the to update to do the "upgrade". This step can also be done on the command line with the following command:
cd /var/www/nextcloud/
sudo -u www-data php occ upgrade
Command Line
To run in non-interactive mode:
sudo -u www-data php /var/www/nextcloud/updater/updater.phar --no-interaction
The whole update can be done via the command line, too, and it's a guided process, so answer the interactive questions and the update will do its thing. This executes the same steps as the web updater.
sudo -u www-data php /var/www/nextcloud/updater/updater.phar
After this step is finished, occ upgrade
must be run either manually or just
respond with y
to the final questions of the update process above as it will
ask you whether it should run occ upgrade
for you.
The maintenance mode is enabled automatically and will be disabled
automatically, too. Manually, you can run the following with --on
or --off
.
sudo -u www-data php occ maintenance:mode --on
Manual steps
Manual steps which the auto updater does not do because the may be time consuming. These can be run without moving the Nextcloud instance in maintenance mode.
sudo -u www-data php occ db:add-missing-columns
sudo -u www-data php occ db:add-missing-indices
Troubleshooting
If files do not show up, do a rescan.
cd /var/www/nextcloud/
sudo -u www-data php console.php files:scan --all
There is also a repair function, which ... repairs things.
cd /var/www/nextcloud/
sudo -u www-data php occ maintenance:repair
Backup
Enable maintenance
cd /var/www/nextcloud
sudo -u www-data php occ maintenance:mode --on
Create backup
Copy everything
cd /var/www/
rsync -Aavx nextcloud/ nextcloud-dirbkp_`date +"%Y%m%d"`/
Create backup of MariaDB:
The user can be root
or the created db user for nextcloud. The password will
be asked interactively. The value nextcloud
sets the database to be exported
(it's not the password).
mysqldump --single-transaction --default-character-set=utf8mb4 -u root -p nextcloud > nextcloud-sqlbkp_`date +"%Y%m%d"`.bak
Restore Backup
rsync -Aax nextcloud-dirbkp/ nextcloud/
After restoring a backup, run the occ maintenance:data-fingerprint
command.
This will change the ETag for all files allowing sync client to realize that
files were changed.
Before restoring an sqldump, drop and recreate the nextcloud table.
mysql -u root -p
Execute
DROP DATABASE nextcloud;
CREATE DATABASE nextcloud CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
Then restore from backup file.
mysql -h [server] -u [username] -p[password] [db_name] < nextcloud-sqlbkp.bak
# specific with interactive password prompt:
mysql -u root -p nextcloud < nextcloud_sqlbkp.bak
Misc
Some command for occ
Clean trashbin for all users.
sudo -u www-data php occ trashbin:cleanup --all-users
Rescan files for all users.
sudo -u www-data php occ files:scan --all
Delete file cache entries that have not matching entreis in the storage table.
sudo -u www-data php occ files:cleanup
Update all apps.
```sh
sudo -u www-data php occ app:update --all
Show status information about Nextlcoud installation.
sudo -u www-data php occ status
Calendar
I think this is not neccessary as the cron job is running every 5 min. Otherwise, do I want this anyway?
Sending notifications with occ
.
crontab -u www-data -e
Append
*/5 * * * * php -f /var/www/nextcloud/occ dav:send-event-reminders
Then change the sending mode from background-job
to occ
:
cd /var/www/nextcloud/
sudo -u www-data php occ config:app:set dav sendEventRemindersMode --value occ
Misc todo
- [ ] TODO: db: is READ_COMMITTED?
- [ ] TODO: They recomend to move the
data
directory somewhere else and do not leave it in the document root, e.g./var/www/nextcloud/data
. - [ ] TODO MAYBE: activate HTTP/2.0