NextCloud - OpenBSD 7.3

Page content

NextCloud on OpenBSD 7.3

some install notes …

  • Powerup Fresh VM
  • Upgrade to 7.3 Beta (7.3 is not yet released)

pkg_info nextcloud

pkg_info -Q nextcloud -D snap
nextcloud-23.0.12p0
nextcloud-24.0.10
nextcloud-25.0.4
nextcloudclient-3.7.4

adding 25.0.4

pkg_add -D snap nextcloud 
quirks-6.121 signed on 2023-03-21T18:57:42Z
Ambiguous: choose package for nextcloud
a	0: <None>
	1: nextcloud-23.0.12p0
	2: nextcloud-24.0.10
	3: nextcloud-25.0.4
Your choice: 3

installed:

  • php-8.1
  • lot of stuff

got some readme

...
nextcloud-25.0.4:gd-2.3.3: ok
nextcloud-25.0.4:php-gd-8.1.16: ok
nextcloud-25.0.4:icu4c-72.1v0: ok
nextcloud-25.0.4:icu4c-wwwdata-72.1v0: ok
nextcloud-25.0.4:php-intl-8.1.16: ok
nextcloud-25.0.4:php-curl-8.1.16p0: ok
nextcloud-25.0.4:pecl81-redis-5.3.7p0: ok
nextcloud-25.0.4: ok
Running tags: ok
The following new rcscripts were installed: /etc/rc.d/php81_fpm
See rcctl(8) for details.
New and changed readme(s):
	/usr/local/share/doc/pkg-readmes/femail-chroot
	/usr/local/share/doc/pkg-readmes/nextcloud
	/usr/local/share/doc/pkg-readmes/php-8.1

readme is for loosers, right ? so, let’s have a look …

Readme PHP 8.1

cat /usr/local/share/doc/pkg-readmes/php-8.1 
+-----------------------------------------------------------------------
| Running php-8.1 on OpenBSD
+-----------------------------------------------------------------------

Connecting your web server software to php
==========================================
Web server programs such as httpd(8), nginx and Apache listen for
network requests and decide whether to respond themselves (as is the
case with simple "static" files) or pass the request on to other
software for handling. The web server must be configured to handle
this - different methods are used depending on the server software.

FastCGI: httpd(8), NGINX, lighttpd, etc
---------------------------------------
Most modern web servers support FastCGI which is a simple method of
interfacing to many kinds of application server. This is usually the
preferred method of passing requests to php, and is the only method
possible for many servers such as httpd(8), nginx and lighttpd.

The main OpenBSD php packages include php-fpm, FastCGI Process Manager.
This manages pools of FastCGI processes: starts/restarts them and
maintains a minimum and maximum number of spare processes as
configured. You can use rcctl(8) to enable php-fpm at boot,
and start it at runtime:

    rcctl enable php81_fpm
    rcctl start php81_fpm

php-fpm has its own configuration file, by default /etc/php-fpm.conf.
This controls how the php processes are started. The default settings
are suitable for many standard cases, but can be changed to provide
greater control for sites handling high loads or to provide
separation between different php applications by running them
under different uids or in individual chroot(2) jails.

Your HTTP server needs to be configured to pass requests for PHP
resources to php-fpm, usually done by unix socket. See the documentation
and sample configuration. For nginx, see the "FastCGI server listening
on unix socket" example provided in /usr/local/share/nginx/nginx.conf.
For OpenBSD base's httpd(8) you can use a configuration fragment like:

	location "*.php" {
		fastcgi socket "/run/php-fpm.sock"
	}

If you need to run multiple versions of PHP on one machine, create
another configuration file (e.g. php-fpm-X.Y.conf) and set it to use a
different socket path. Configure rc.d(8) to pass the parameter when
starting php-fpm, for example

    rcctl set phpXY_fpm flags -y /etc/php-fpm-X.Y.conf

NGINX Unit
----------
NGINX Unit (https://unit.nginx.org/) is a standalone application server,
distinct to the standard NGINX web server. It uses its own compiled module
to provide PHP support. Install the relevant package (e.g.  unit-php81)
and follow the usual documentation for Unit.

Apache httpd
------------
For Apache, the most common option is with the mod_php Apache module
provided in the php-apache package. This is loaded directly as part of
the web server process. Configuration is fairly simple, but in this
case the operating system can't provide memory protection between
the two; therefore bugs in php can potentially do more damage.

Another option is to use FastCGI via php-fpm as in the above section;
you can use mod_proxy_fcgi to interface it with Apache.

If you wish to use the Apache module, make sure the php-apache-8.1
package is installed, then enable it by creating a symbolic link:

    # ln -sf /var/www/conf/modules.sample/php-8.1.conf \
	/var/www/conf/modules/php.conf

To disable:

    # rm -f /var/www/conf/modules/php.conf

After making either of these changes, restart Apache.

php configuration
=================
The recommended php configuration has been installed to:
    /etc/php-8.1.ini.

Modify this as required for your use.

Extension modules
=================
Many language features in php are provided by extensions, which come
in several classes.

- some extensions are included in the main PHP package and are always
enabled; they don't need to be installed or enabled separately.

- opcache is in the main package but must be configured.

- some 'core' extensions with extra dependencies are packaged separately
(e.g. php-pdo_mysql, php-ldap, php-soap, and others) and can be installed
with pkg_add(1).

- various useful third-party extensions from the PECL repository have
also been packaged. Examples include pecl81-memcached (for use with
sysutils/memcached), pecl81-imagick (image manipulation using ImageMagick),
pecl81-redis (for use with databases/redis), etc.

For all extensions packaged separately (and for opcache), you will find a
file named /etc/php-8.1.sample/(MODULE_NAME).ini. To enable it,
add a symlink into /etc/php-8.1 and restart:

    ln -sf ../php-8.1.sample/MODULE_NAME.ini /etc/php-8.1/

To disable, remove the symlink from /etc/php-8.1 and restart:

    rm /etc/php-8.1/MODULE_NAME.ini

If you have installed a number of extensions and wish to enable them all,
you can use these shell commands:

    # cd /etc/php-8.1.sample
    # for i in *; do ln -sf ../php-8.1.sample/$i ../php-8.1/; done

After enabling or disabling extensions (or otherwise modifying php's
configuration), use rcctl(8) to restart php81_fpm or Apache.

Living with chroot
==================
The chroot jail commonly used with PHP on OpenBSD means that only files
inside /var/www can be accessed, and path references should omit /var/www
prefixes.

File paths
----------
Sometimes it is hard to work with file paths in this case (for example
applications with some parts run from the web and some from the command
line); in those cases it can help to create a symlink so that /var/www
from _inside_ the chroot points to the expected locations. This can be
done with "mkdir -p /var/www/var; ln -s .. /var/www/var/www".

Socket paths for MariaDB
------------------------
See mariadb's pkg-readme file for information.

Making network connections
--------------------------
To resolve DNS host names, you will need to copy /etc/resolv.conf
into the /var/www chroot jail. To make TLS connections, you'll also
need /etc/ssl/cert.pem for CA certificates.

Additionally, if your scripts use PHP's key generation functions they
may need access to /etc/ssl/openssl.cnf.

To use these, copy the relevant files into the /var/www jail:

    # mkdir -p /var/www/etc/ssl
    # install -m 444 -o root -g bin /etc/resolv.conf /var/www/etc/
    # install -m 444 -o root -g bin /etc/ssl/cert.pem /etc/ssl/openssl.cnf \
          /var/www/etc/ssl/

As these files are updated from time to time, you might like to add
the above "install" lines to /etc/rc.local.

Executing other commands
------------------------
To run commands from inside the chroot using PHP's file execution functions
(exec, passthru, popen, etc) or the old mail() function which executes
/usr/sbin/sendmail, you must either create a statically-linked binary,
or install the relevant libraries and support files inside the chroot. 
Additionally you will need to provide /bin/sh inside the chroot, for
example: "cp /bin/sh /var/www/bin". Again you will want to make sure
that this is kept up to date. (In the specific case of mail, it is
normally preferred to use PHPMailer or similar, and submit the mail by
SMTP instead).

readme nextcloud

cat /usr/local/share/doc/pkg-readmes/nextcloud
+-----------------------------------------------------------------------
| Running nextcloud on OpenBSD
+-----------------------------------------------------------------------

Nextcloud is installed under
    /var/www/nextcloud

Official documentation is available at:
    https://docs.nextcloud.com/server/25/admin_manual/

Post-installation instructions
==============================

*** It is highly recommended to use SSL on the webserver (HTTPS).

chroot(2)
---------
When running Nextcloud under a chrooted environment, make sure to read the
"PHP's OpenSSL functions" section of:
    /usr/local/share/doc/pkg-readmes/php-8.1

The HTTP server must be able to resolve hostnames:
    # mkdir -p /var/www/etc
    # cp /etc/resolv.conf /var/www/etc

The configuration of an SQLite database path is set relatively to the chroot in
Nextcloud which will break background jobs run by cron(8) (see below).
A symlink can be created to workaround this issue:
    # ln -sf /var/www/nextcloud /nextcloud

OpenBSD HTTP daemon
-------------------
httpd(8) example configuration for Nextcloud:

---8<---------------------------------------------------------------------------
server "domain.tld" {
	listen on egress tls port 443

	hsts max-age 15768000

	tls {
		certificate "/etc/ssl/domain.tld_fullchain.pem"
		key "/etc/ssl/private/domain.tld_private.pem"
	}

	# Set max upload size to 513M (in bytes)
	connection max request body 537919488
	connection max requests 1000
	connection request timeout 3600
	connection timeout 3600

	block drop

	# Ensure that no '*.php*' files can be fetched from these directories
	location "/nextcloud/config/*" {
		block drop
	}

	location "/nextcloud/data/*" {
		block drop
	}

	# Note that this matches "*.php*" anywhere in the request path.
	location "/nextcloud/*.php*" {
		root "/nextcloud"
		request strip 1
		fastcgi socket "/run/php-fpm.sock"
		pass
	}

	location "/nextcloud/apps/*" {
		root "/nextcloud"
		request strip 1
		pass
	}

	location "/nextcloud/dist/*" {
		root "/nextcloud"
		request strip 1
		pass
	}

	location "/nextcloud/core/*" {
		root "/nextcloud"
		request strip 1
		pass
	}

	location "/nextcloud" {
		block return 301 "$DOCUMENT_URI/index.php"
	}

	location "/nextcloud/" {
		block return 301 "$DOCUMENT_URI/index.php"
	}

	location "/.well-known/carddav" {
		block return 301 "https://$SERVER_NAME/nextcloud/remote.php/dav"
	}

	location "/.well-known/caldav" {
		block return 301 "https://$SERVER_NAME/nextcloud/remote.php/dav"
	}

	location "/.well-known/webfinger" {
		block return 301 "https://$SERVER_NAME/nextcloud/public.php?service=webfinger"
	}

	location match "/nextcloud/oc[ms]%-provider/*" {
		directory index index.php
		pass
	}
}
---8<---------------------------------------------------------------------------

nginx
-----
See:
    https://docs.nextcloud.com/server/25/admin_manual/installation/nginx.html

Apache HTTPD
------------
Apache configuration for Nextcloud is stored under:
    /var/www/conf/modules.sample/apache-nextcloud.conf

It needs to be enabled by running the following command after the apache-httpd
package is installed:
# ln -s ../modules.sample/apache-nextcloud.conf /var/www/conf/modules
# rcctl restart apache2

The rewrite_module needs to be enabled by uncommenting the following line in
/etc/apache2/httpd2.conf:
    #LoadModule rewrite_module /usr/local/lib/apache2/mod_rewrite.so

PHP
---
Default PHP values for Apache are set under:
    /var/www/nextcloud/.htaccess
    /var/www/nextcloud/config/.htaccess

OpenBSD HTTP daemon users can match these .htaccess file values by editing
/etc/php-8.1.ini or /etc/php-fpm.conf.

nginx users can match these .htaccess file values by configuring fastcgi_param
with a PHP_VALUE in /etc/nginx/nginx.conf.

For enhanced performance, a PHP opcode cache can be used (built-in to PHP 5.5+,
enable "opcache.ini" to use it).
Recommended values for /etc/php-8.1.ini:
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

Database configuration
----------------------
See the following URL for setting up a database for Nextcloud:
    https://docs.nextcloud.com/server/25/admin_manual/configuration_database/linux_database_configuration.html

Nextcloud can work with a PostgreSQL, MariaDB or SQLite3 database. The
corresponding package needs to be installed *before* setting up Nextcloud:
    php-pdo_sqlite, php-pdo_pgsql or php-pdo_mysql

Configuration file
------------------
Configuration is done under:
    /var/www/nextcloud/config/config.php
and the default "datadirectory" is set to:
    /var/www/nextcloud/data
When running chrooted, /var/www must be stripped from the paths.

Cron job
--------
Nextcloud needs to run background jobs on a regular basis. By default, it will
execute one task with each page loaded ("AJAX" option in the admin interface).
The prefered way is to use a cron(8) job instead.
(see https://<hostname>/nextcloud/index.php/settings/admin#backgroundjobs)
e.g.
*/15	*	*	*	*	su -m www -c "/usr/local/bin/php-8.1 -f /var/www/nextcloud/cron.php"

Memory caching and file locking
-------------------------------
Nextcloud server performance can be significantly improved with memory caching
and memory-based locking. Distributed caching and Transactional File Locking is
provided by Redis, an in-memory data structure store. More information and
configuration example are available at:
    https://docs.nextcloud.com/server/25/admin_manual/configuration_server/caching_configuration.html#id4

TL;DR
You need a redis server running (available in the redis package) then adapt and
append the following to:
    /var/www/nextcloud/config/config.php

  'filelocking.enabled' => true,
  'memcache.local' => '\OC\Memcache\Redis',
  'memcache.locking' => '\OC\Memcache\Redis',
  'redis' => array(
    'host' => 'localhost',
    'port' => 6379,
    'timeout' => 0.0,
    'password' => '', // Optional, if not defined no password will be used.
  ),

Authentication backends
-----------------------
When using a non-default user authentication backend (LDAP, IMAP, ...), extra
packages may be needed (e.g. php-ldap, php-imap).

Finishing and validating the installation
-----------------------------------------
Make sure the web server can resolve its hostname (e.g. if chrooted, by creating
/var/www/etc/hosts and/or /var/www/etc/resolv.conf).

Create the file "CAN_INSTALL" to allow web-based installation:

    # touch /var/www/nextcloud/config/CAN_INSTALL

Accessing https://<hostname>/nextcloud with a Web browser will finish the
installation and create a new admin user.

Updating
========
Before updating to a new release, read:
    https://docs.nextcloud.com/server/25/admin_manual/maintenance/upgrade.html

WebDAV access
=============
The personal WebDAV share can be accessed using the following URL (e.g. with
Nautilus, Thunar or Doplhin) and the corresponding user and password for the
share:
    https://<hostname>/nextcloud/remote.php/webdav/

Synchronization
===============
The "nextcloudclient" package (net/nextcloudclient) is a graphical (Qt)
application to synchronize with a Nextcloud server.

Apps and dependencies
=====================
To keep dependencies to a minimum, not all dependencies for all installed apps
are enforced. It is the job of the administrator to manually install required
packages according to the non-default apps (s)he wants to enable.

enable php

readme told me to enable and start php_fpm …

rcctl enable php81_fpm
rcctl start php81_fpm

allow resolv.conf

our webserver runs chrootet. so, we allow him to use resolv.confg

mkdir -p /var/www/etc
cp /etc/resolv.conf /var/www/etc
ln -sf /var/www/nextcloud /nextcloud

we wanna have tls cert

cp /etc/examples/acme-client.conf /etc/
sed -i 's/example.com/nc.puffy.work/' /etc/acme-client.conf
sed -i '/alternative names.*/d' /etc/acme-client.conf

build temp httpd.conf

cp /etc/examples/httpd.conf /etc/
sed -i 's/example.com/nc.puffy.work/' /etc/httpd.conf

enable & start webserver

rcctl enable httpd
rcctl restart httpd

allow http/https

you should update your firewall to allow http/https from any to your host if not yet done.

# Full Access/Block Port 80
pass  in  log quick inet  proto tcp   from any  to (self) port 80
pass  in  log quick inet6 proto tcp   from any  to (self) port 80

# Full Access/Block Port 443
pass  in  log quick inet  proto tcp   from any  to (self) port 443
pass  in  log quick inet6 proto tcp   from any  to (self) port 443

restart pf

pfctl -nf /etc/pf.conf && pfctl -f /etc/pf.conf

get tls cert

acme-client nc.puffy.work

-> got priv. key & cert

-r--r--r--  1 root  wheel  5934 Mar 23 04:26 /etc/ssl/nc.puffy.work.fullchain.pem
-r--------  1 root  wheel  3272 Mar 23 04:17 /etc/ssl/private/nc.puffy.work.key

create httpd.conf

cat << EOF > /etc/httpd.conf
server "nc.puffy.work" {
	listen on egress tls port 443

	hsts max-age 15768000

	tls {
		certificate "/etc/ssl/nc.puffy.work.fullchain.pem"
		key "/etc/ssl/private/nc.puffy.work.key"
	}

	# Set max upload size to 513M (in bytes)
	connection max request body 537919488
	connection max requests 1000
	connection request timeout 3600
	connection timeout 3600

	block drop

	# Ensure that no '*.php*' files can be fetched from these directories
	location "/nextcloud/config/*" {
		block drop
	}

	location "/nextcloud/data/*" {
		block drop
	}

	# Note that this matches "*.php*" anywhere in the request path.
	location "/nextcloud/*.php*" {
		root "/nextcloud"
		request strip 1
		fastcgi socket "/run/php-fpm.sock"
		pass
	}

	location "/nextcloud/apps/*" {
		root "/nextcloud"
		request strip 1
		pass
	}

	location "/nextcloud/dist/*" {
		root "/nextcloud"
		request strip 1
		pass
	}

	location "/nextcloud/core/*" {
		root "/nextcloud"
		request strip 1
		pass
	}

	location "/nextcloud" {
		block return 301 "$DOCUMENT_URI/index.php"
	}

	location "/nextcloud/" {
		block return 301 "$DOCUMENT_URI/index.php"
	}

	location "/.well-known/carddav" {
		block return 301 "https://$SERVER_NAME/nextcloud/remote.php/dav"
	}

	location "/.well-known/caldav" {
		block return 301 "https://$SERVER_NAME/nextcloud/remote.php/dav"
	}

	location "/.well-known/webfinger" {
		block return 301 "https://$SERVER_NAME/nextcloud/public.php?service=webfinger"
	}

	location match "/nextcloud/oc[ms]%-provider/*" {
		directory index index.php
		pass
	}
}
EOF

restart httpd

rcctl restart httpd

nextcloud config

cd /var/www/nextcloud/config
cp config.sample.php config.php
sed -i 's#/nextcloud/data##' config.php

ready to go ?

create a temp. install file

touch /var/www/nextcloud/config/CAN_INSTALL

https://nc.puffy.work/nextcloud/index.php

-> Internal Server Error

check log

==> /var/www/logs/error.log <==
PHP message: PHP Fatal error:  Uncaught Error: Class "RedisCluster" not found in /nextcloud/config/config.php:1411
Stack trace:
#0 /nextcloud/lib/private/Config.php(233): include()
#1 /nextcloud/lib/private/Config.php(71): OC\Config->readData()
#2 /nextcloud/lib/base.php(153): OC\Config->__construct()
#3 /nextcloud/lib/base.php(598): OC::initPaths()
#4 /nextcloud/lib/base.php(1144): OC::init()
#5 /nextcloud/index.php(34): require_once('...')
#6 {main}

after installing redis, there were further errors concerning database, app paths and so on. need to invest some time another day …


Any Comments ?

sha256: 2ddd14ba2a44330ac48e7fae27bb786bbcf5c8eaf18af479563c115267a0d9d0