Nextcloud
Installation
While Owncloud does provide packages for various distributions[1], Nextcloud only links to 3rd party providers, offering builds of their latest releases.[2]
When installing from the official release:
wget https://download.nextcloud.com/server/releases/nextcloud-20.0.4.tar.bz2{,.sha256,.asc} gpg --recv-keys 28806A878AE423A28372792ED75899B9A724937A gpg --verify nextcloud*.bz2.asc sha256sum -c nextcloud*.tar.bz2.sha256 cd $DOCROOT tar -xjf nextcloud*.tar.bz2
The webserver needs to be able to write to certain parts of the installation, but not all:
sudo chown -cR root:root nextcloud/ sudo chown -cR www-data:www-data nextcloud/{.htaccess,.user.ini,3rdparty,apps,config,data}
Install some dependencies:[3]
apt install php-fpm php-apcu php-bcmath php-bz2 php-curl php-gd php-gmp php-imagick php-intl php-json php-mbstring php-xml php-zip php-sqlite3 php-mysql php-pgsql php-redis
Enable PHP Opcache:[4]
$ cat /etc/php/7.0/mods-available/opcache.ini zend_extension=opcache.so opcache.enable=1 opcache.enable_cli=1 opcache.interned_strings_buffer=8 opcache.max_accelerated_files=10000 opcache.memory_consumption=128 opcache.save_comments=1 opcache.revalidate_freq=1
Prepare the database:
> CREATE USER nextcloud@localhost IDENTIFIED BY 's3cr3t'; > CREATE DATABASE IF NOT EXISTS nextcloud; > GRANT ALL PRIVILEGES ON nextcloud.* TO nextcloud@localhost;
With all that in place, the installer should start once a web browser is pointed to the document root.
The (newly generated) config/config.php
can be adjusted to switch to pretty URLs[5]
[...] 'datadirectory' => '/var/www/nextcloud/data', 'overwrite.cli.url' => 'https://www.example.net/nextcloud', 'htaccess.RewriteBase' => '/nextcloud',
Re-generate $DOCROOT/.htaccess
:
sudo -u www-data php /var/www/nextcloud/occ maintenance:update:htaccess
When serving Nextcloud in a subdirectory, we may also need the following settings on the web server to allow proper service discovery[6]
Redirect 301 /.well-known/carddav /nextcloud/remote.php/dav Redirect 301 /.well-known/caldav /nextcloud/remote.php/dav
sys_get_temp_dir
It may be necessary to adjust the handling of temporary files. This may even warrant a whole new topic, but let's add this here: the occ
command will need to use a temp
directory and usually gets the same from PHP:
$ sudo --preserve-env=NEXTCLOUD_CONFIG_DIR -u nextcloud /usr/bin/php -c /etc/php/php.ini -r 'print(sys_get_temp_dir()."\n");' /var/run/php_tmp
However, since we are running php-fpm
, the nextcloud
pool does not have write access to that directory:
$ ps -ef | grep pool\ nex[t] nextclo+ 7791 7788 0 22:39 ? 00:00:02 php-fpm: pool nextcloud nextclo+ 7792 7788 0 22:39 ? 00:00:01 php-fpm: pool nextcloud nextclo+ 7820 7788 0 22:39 ? 00:00:01 php-fpm: pool nextcloud $ ls -ld /var/run/php_tmp drwxrwx---+ 2 http http 80 Apr 2 22:44 /var/run/php_tmp
We have several options here:
- Add
nextcloud
to thehttp
group, but we may not want to do that, as we will lose some privilege separation. - Add an
ExecStartPost
rule[7] tophp-fpm.service
. However, this isn't working out of the box, as current unit files will setReadWritePaths
only to some distinct directories, and we don't want to add another one just yet. - Set an ACL for this directory. This won't work after boot, because PHP may not be running yet, but we can add the same to our
occ
wrapper script:
/usr/bin/setfacl -m u:nextcloud:rwx /var/run/php_tmp
-- that should do the trick.
Caching
According to the documentation, we can use several caching techniques.
APC
php-apcu needs to be installed and enabled:
$ cat /etc/php/conf.d/apcu.ini extension=apcu.so apc.enable_cli=1
So we should have something like this:
$ php -r 'phpinfo();' | grep apc apc.enable_cli => On => On apc.enabled => On => On [...]
Enable APCu
in NextCloud config.php
'memcache.local' => '\OC\Memcache\APCu',
We could also enable the APC statistics page:
$ ln -s /usr/share/webapps/php-apcu/apc.php /var/www/apc.php $ cat /var/www/apc.conf.php <?php defaults('ADMIN_USERNAME','admin'); defaults('ADMIN_PASSWORD','s3cr3t'); ?>
Redis
While we could use Memcached for caching, Redis appears[8] to be the better choice. YMMV though.
Install Redis and configure as needed:
$ grep ^[a-z] /etc/redis.conf bind 127.0.0.1 protected-mode yes port 0 unixsocket /var/run/redis/redis.sock unixsocketperm 700 [...]
Make the socket available to the user running the web server:
setfacl -m u:http:rwx /var/run/redis/{,redis.sock}
We will also need the PHP module:
git clone https://github.com/phpredis/phpredis.git phpredis-git cd phpredis-git phpize && ./configure && make sudo install -m0755 -o root -g root modules/redis.so /usr/local/lib/
Enable the module in our PHP config:
$ grep redis /etc/php/conf.d/local.ini extension=/usr/local/lib/redis.so
...and in Nextcloud:
$ cat ../nextcloud/config/config.php [...] 'memcache.local' => '\OC\Memcache\APCu', 'memcache.distributed' => '\OC\Memcache\Redis', 'memcache.locking' => '\OC\Memcache\Redis', 'redis' => [ 'host' => '/var/run/redis/redis.sock', 'port' => 0, ],
TBD:
Previews
With PreviewGenerator installed, showing previews of pictures should be much faster.
occ app:install previewgenerator occ app:enable previewgenerator occ preview:generate-all
Install the following as a cronjob (every 10 minutes):
occ preview:pre-generate
Generate only a pre-defined set of preview image sizes:
$ for o in squareSizes widthSizes heightSizes; do occ config:app:set --value="64 256 1024" previewgenerator ${o}; done Config value squareSizes for app previewgenerator set to 64 256 1024 Config value widthSizes for app previewgenerator set to 64 256 1024 Config value heightSizes for app previewgenerator set to 64 256 1024
Previews will be generated in a sub directory hierarchy:[9]
This lovely like is the result of the way the new previews are stored * We take the md5 of the name (fileid) and split the first 7 chars. That way
* there are not a gazillion files in the root of the preview appdata.
Let's see:
nextcloud=> \x Expanded display is on. nextcloud=> select fileid,name,to_timestamp(storage_mtime)::date from oc_filecache where name like 'PXL%.jpg' order by storage_mtime desc limit 2; -[ RECORD 1 ]+--------------------------- fileid | 923652 name | PXL_20230830_072605631.jpg to_timestamp | 2023-08-30 -[ RECORD 2 ]+--------------------------- fileid | 923765 name | PXL_20230830_173111087.jpg to_timestamp | 2023-08-30 ^D $ printf 923652 | md5sum | cut -c-7 | sed 's|.|&/|g;s|$|923652|' 4/1/2/d/d/d/d/923652
$ ls -lhgtr /var/lib/nextcloud/data/appdata*/preview/4/1/2/d/d/d/d/923652
total 1.5M
-rw-r--r-- 1 nextcloud 535K Aug 30 09:41 1920-2560-max.jpg
-rw-r--r-- 1 nextcloud 14K Aug 30 09:41 256-256-crop.jpg
-rw-r--r-- 1 nextcloud 1.9K Aug 30 09:45 64-64-crop.jpg
-rw-r--r-- 1 nextcloud 135K Aug 30 09:45 1024-1024-crop.jpg
Databases
sqlite
TBD!
PostgreSQL
TBD!
sudo -u postgres psql CREATE USER nextcloud WITH PASSWORD 'nextcloud'; CREATE DATABASE nextcloud WITH OWNER nextcloud TEMPLATE template0 ENCODING 'UTF8';
https://pgtune.leopard.in.ua/ vi /etc/postgresql/10/main/postgresql.conf
Update
The built-in updater appears to work just fine. We have to make some preparations first:
DOCROOT=/var/www # Adjust as needed! chown -R www-data:www-data $DOCROOT/nextcloud/
Start the web updater and let it run until:
Keep maintenance mode active? [x] Maintenance mode will kept active. Now trigger the migration via command line: ./occ upgrade
And we'll do just that:
sudo -u www-data php $DOCROOT/nextcloud/occ upgrade
If all went well, disable the maintenance mode:
sudo -u www-data php $DOCROOT/nextcloud/occ maintenance:mode --off
Adjust ownerships again:
sudo chown -R root:root $DOCROOT/nextcloud/ sudo chown -cR www-data:www-data $DOCROOT/nextcloud/{.htaccess,.user.ini,3rdparty,apps,config,data}