NextCloud

NextCloud

Jail Creation

bastille create nextcloud 14.2-RELEASE 10.0.0.20/8 bastille0

Installation

Database

We use mariadb as the database for NextCloud since it is the best supported option.

bastille pkg nextcloud install mariadb1011-server
bastille sysrc nextcloud mysql_enable=YES
bastille service nextcloud "mysql start"

To set up the database we connect to the mariadb instance in the jail. Use an empty password if promted:

bastille cmd nextcloud mysql -u root -P

Then, in the shell that opens, enter the following SQL commands. Replace changeme with a password of your choice. Be sure to use the ip address of the nextcloud jail as host for the nextcloud use (the part after the @).

CREATE DATABASE nextcloud;
CREATE USER 'nextcloud'@'10.0.0.20' IDENTIFIED by 'changeme';
GRANT ALL PRIVILEGES ON nextcloud. * TO 'nextcloud'@'10.0.0.20';
GRANT ALL PRIVILEGES ON *.* TO 'nextcloud'@'10.0.1.20' IDENTIFIED BY 'changeme' WITH GRANT OPTION;
--- exit the shell
exit

Nextcloud

Thankfully, we have a nextcloud package for FreeBSD which installs all the dependencies and puts all application files at /usr/local/www/nextcloud. We still need to install the SQlite PDO adapter, since this is required by Nextcloud Collectives.

bastille pkg nextcloud install nextcloud-php83 php83-pdo_sqlite

Webserver

Now we need a way to serve the Nextcloud files. Apache is often used for this, but we opt again for Caddy, since using it with PHP-FPM is dead simple.

bastille pkg nextcloud install caddy

Edit the Caddyfile of the nextcloud jail:

micro /usr/local/bastille/jails/nextcloud/root/usr/local/etc/caddy/Caddyfile

Note

Alternatively, you can also install an editor in the nextcloud jail and use bastille cmd nextcloud micro /usr/local/etc/caddy/Caddyfile to edit the file.

Use the following Configuration:

/usr/local/etc/caddy/Caddyfile
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
# Our Reverse Proxy takes care of tls.
# Internally, we can deal with HTTP, so only expose the server on port 80
:80 {
  # Define the installation directory of Nextcloud as our root dir.
	root * /usr/local/www/nextcloud

	# Enable the static file server:
	file_server

  # Enable php by connecting to php_fpm
	php_fastcgi localhost:9000

	# Enable logging:
	log {
		output file /var/log/caddy/access.log
		# Caddy's structured log format:
		format json
	}
}

PHP Configuration

Use the production template as a starting point:

cp /usr/local/etc/php.ini-production /usr/local/etc/php.ini

Change the following values in the newly created php.ini

/usr/local/etc/php.ini
0
1
2
3
4
5
6
upload_max_filesize = 16G
post_max_size = 16G
max_input_time = 3600
max_execution_time = 3600
upload_tmp_dir = /var/nextcloud_temp/
output_buffering = 0
memory_limit = 2048M

Caching

The FreeBSD Nextcloud package allready set up APCu for local caching. We want to improve on it by using redis.

First, install redis, enable and start it:

bastille pkg nextcloud install redis
bastille sysrc nextcloud redis_enable=YES
bastille service nextcloud 'redis start'

Due to Localhost Pitfalls in Jails, we need to bind redis to the ip address of the jail. Edit the following two values in /usr/local/etc/redis.conf

/usr/local/etc/redis.conf
0
1
2
3
# Bind to internal ip address
bind 10.0.1.20
# Also disable protected mode
protected-mode no

Now we are ready to adapt nextclouds caching settings in /usr/local/www/nextcloud/config/config.php. Change the following values in this file:

/usr/local/www/nextcloud/config/config.php
0
1
2
3
4
5
6
'memcache.local' => '\OC\Memcache\APCu',
'memcache.distributed' => '\OC\Memcache\Redis',
'memcache.locking' => '\OC\Memcache\Redis',
'redis' => [
     'host' => 'localhost',
     'port' => 6379,
],

Reverse-Proxy

TODO: Add caddy config

NextCloud Configuration

LDAP Integration

Install or activate the app “LDAP user and group backend”. Open the Administrative Settings and navigate to “LDAP/AD integration”. Now follow the guide from lldap on how to integrate nextcloud, or simply adopt the settings from the following screenshots:

ldap_config_01 ldap_config_01 ldap_config_01 ldap_config_01

Document Backend

Without a Document Backend, users won’t be able to edit office documents in Nextcloud. They would only be able to Up- and Download files. There are currently two available document backends: Collabora and OnlyOffice. Collabora is based on LibreOffice and the default choice for Nextcloud. But Collabora has no plans of supporting FreeBSD and attemps to port it to FreeBSD are currently stuck. OnlyOffice on the other hand, provides native FreeBSD packages. So we choose OnlyOffice.

Jail Setup

The document backend is a separate application intended to run on a separate host or container. So we are creating a jail for it:

bastille create onlyoffice 14.2-RELEASE 10.0.0.21/8 bastille0

# for PostgreSQL we need to set an additional option for the jail
bastille config onlyoffice set allow.sysvipc 1

# restart it for good measure
bastille restart onlyoffice

Lets install the packages required for this container and enable all the services these will install (we will also install micro to have an editor ready in the jail):

bastille pkg onlyoffice install onlyoffice-documentserver py311-importlib-resources py311-setuptools postgresql16-server micro

bastille sysrc onlyoffice postgresql_enable=YES
bastille sysrc onlyoffice nginx_enable=YES
bastille sysrc onlyoffice rabbitmq_enable=YES
bastille sysrc onlyoffice supervisord_enable=YES

Database

We will use Postgresql as the Database for OnlyOffice. Lets set it up now. We will have to execute quite a few commands and edit multiple files. It will be easier if we perform these steps directly in the jail. So let’s enter it:

bastille console onlyoffice

From here, lets initialize the database:

service postgresql initdb

We need to tell postgres to listen on the ip of the jail. Edit the file /var/db/postgres/data16/pg_hba.conf and add the folowing at the end of the file. This will tell postgres to trust every connection coming from this address (the local jail).

/var/db/postgres/data16/pg_hba.conf
1
host    all             all             10.0.0.21/32            trust

We also need to edit /var/db/postgres/data16/postgres.conf to tell postgres to listen on this interface. Edit the file and change the line containing listen_addresses to the following:

/var/db/postgres/data16/postgres.conf
1
listen_addresses = 'localhost,10.0.0.21'

Now we are ready to create and configure the database for onlyoffice:

service postgresql start
psql -U postgres -c "CREATE DATABASE onlyoffice;"
psql -U postgres -c "CREATE USER onlyoffice WITH password 'onlyoffice';"
psql -U postgres -c "GRANT ALL privileges ON DATABASE onlyoffice TO onlyoffice;"
psql -U postgres -c "ALTER DATABASE onlyoffice OWNER to onlyoffice;"
psql -h10.0.0.21 -Uonlyoffice -d onlyoffice -f /usr/local/www/onlyoffice/documentserver/server/schema/postgresql/createdb.sql

RabbitMQ

RabbitMQ provides a Message Queue which OnlyOffice depends on. We configure it as follows:

service rabbitmq start
rabbitmqctl --erlang-cookie `cat /var/db/rabbitmq/.erlang.cookie` add_user onlyoffice onlyoffice # usr=onlyoffice, pw=onlyoffice
rabbitmqctl --erlang-cookie `cat /var/db/rabbitmq/.erlang.cookie` set_user_tags onlyoffice administrator
rabbitmqctl --erlang-cookie `cat /var/db/rabbitmq/.erlang.cookie` set_permissions -p / onlyoffice ".*" ".*" ".*"

Documentserver

Now we are finally ready to configure the OnlyOffice Documentserver. We need to add our database and rabbitmq credentials to the configuratioon and add a specific block to set request-filtering-agent to allow requests from private ip addresses. You can edit the configuration with micro /usr/local/etc/onlyoffice/documentserver/local.json. Following is the content of this file, after adaption.

/usr/local/etc/onlyoffice/documentserver/local.json
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
{
  "services": {
    "CoAuthoring": {
      "CoAuthoring": {
      "request-filtering-agent": {
        "allowPrivateIPAddress": true,
        "allowMetaIPAddress": true
      },
      "sql": {
        "type": "postgres",
        "dbHost": "10.0.0.21", 
        "dbPort": "5432",
        "dbName": "onlyoffice",
        "dbUser": "onlyoffice",
        "dbPass": "onlyoffice"
      },
      "token": {
        "enable": {
          "request": {
            "inbox": false,
            "outbox": false
          },
          "browser": false
        },
        "inbox": {
          "header": "Authorization"
        },
        "outbox": {
          "header": "Authorization"
        }
      },
      "secret": {
        "inbox": {
          "string": "secret"
        },
        "outbox": {
          "string": "secret"
        },
        "session": {
          "string": "secret"
        }
      }
    }
  },
  "rabbitmq": {
    "url": "amqp://onlyoffice:onlyoffice@localhost"
  }
}

Open the supervisord configuration and add an include statement to include the onlyoffice supervisord files:

micro /usr/local/etc/supervisord.conf
/usr/local/etc/supervisord.conf
1
2
[include]
files = /usr/local/etc/onlyoffice/documentserver/supervisor/*.conf

Now we can start supervisord

service supervisord start

nginx

OnlyOffice comes with pre-made configuration files for nginx. We will use this to expose it internally (but we still use our caddy reverse-proxy to expose it externally).

Lets edit /usr/local/etc/nginx/nginx.conf and on the line after http { enter the following include statement

/usr/local/etc/nginx/nginx.conf
1
include /usr/local/etc/onlyoffice/documentserver/nginx/ds.conf;

There is already a server {} block in this file (inside the http { block). Remove the whole block. Now run the following script:

documentserver-update-secureLink.sh

After the script has run, open /usr/local/etc/onlyoffice/documentserver/nginx/ds.conf and remove the line listen [::]:80 default_server;. Our jail does not have a ipv6 stack and this line will cause an error. After that, rerun the previous script

documentserver-update-secureLink.sh

Now the output should state that the config is sane and we are ready to start the nginx service

service nginx start

We now have everything set up in our onlyoffice-jail. Exit the shell to return to our hosts shell:

exit

Caddy Configuration

To expose the documentserver open the Caddyfile of our reverse-proxy jail with micro /usr/local/bastille/jails/nextcloud/root/usr/local/etc/caddy/Caddyfile and add the following block:

/usr/local/etc/caddy/Caddyfile
1
2
3
docs.<domain> {
	reverse_proxy 10.0.0.21:80
}

And restart caddy:

bastille service caddy 'caddy restart'

Nextcloud Configuration

Log in to Nextcloud as an admin and install the ONLYOFFICE app. Open the administrator settings and in the OnlyOffice settings add https://docs.<domain> as the Docs address. Input http://10.0.0.21 as the address for internal request and http://10.0.0.20 as the Nextcloud address for internal requests.

Talk Backend