Nextcloud: add app using podman
Nextcloud is an essential privacy app that has been missing from FreedomBox for a long time. This is due to the difficulty of packaging it into Debian. To include Nextcloud in FreedomBox, we can use podman which can sit between the app and the rest of the system. In this issue, I'd like to list the required actions/configurations to setting up Nextcloud based on my testing. The commands below are executed as root, however, one of podman's great benefits is the ability to run rootless containers. It would be worth investigating a rootless setup for impoved security.
- Create a dedicated virtual bridge adapter with a static IP. This is needed for communication between the container and the host when using MySQL and LDAP. Use the default subnet for the sake of simplicity.
$ podman network create --driver bridge --subnet 172.16.16.0/24 --gateway 172.16.16.1 nextcloud-bridge-fbx. This will createcni-podman0andveth727ced78which ideally should be hidden from users in the Network app. - run the container:
$ podman run --detach \
# Only listen on localhost. This is useful to prevent exposing 8181 to the
# internet in situations discussed in https://salsa.debian.org/freedombox-team/freedombox/-/issues/789
--publish 127.0.0.1:8181:80 \
--network nextcloud-bridge-fbx \
--ip 172.16.16.2 \
# Will be stored under /var/lib/containers/storage/volumes/nextcloud-volume/_data/
--volume nextcloud-volume:/var/www/html \
--name nextcloud-fbx \
# enable autoupdates
--label io.containers.autoupdate=registry \
docker.io/library/nextcloud:stable-apache
- Although for FreedomBox apps it's generally preferable to use SQLite, the official documentation advises against it. During the initial setup, the GUI warns: "SQLite should only be used for minimal and development instances. For production we recommend a different database backend. If you use clients for file syncing, the use of SQLite is highly discouraged."
Install default-mysql-server and create the database as described in the documentation. Instead of loclhost, use the container's IP address that we assigned earlier:
CREATE USER 'nextcloud_fbx'@'172.16.16.2' IDENTIFIED BY 'password';
CREATE DATABASE IF NOT EXISTS nextcloud_fbx CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
GRANT ALL PRIVILEGES ON test.* TO 'nextcloud_fbx'@'172.16.16.2';
FLUSH PRIVILEGES;
-
Under
[mysqld]addbind-address = 172.16.16.1so that the host database the container can communicate with each other. -
Do the initial setup with the Nextcloud console:
podman exec --user www-data nextcloud-fbx php occ maintenance:install --database=mysql --database-name=nextcloud_fbx --database-host=172.16.16.1 --database-port=3306 --database-user=nextcloud_fbx --database-pass=password --admin-user=nextcloud-admin --admin-pass=admin-password -
Configure the url values.
overwriteprotocolandoverwrite.cli.urlshould be http when Nextlcoud is configured with an onion domain:
$ podman exec --user www-data nextcloud-fbx php occ config:system:set trusted_domains 0 --value="localhost:4430"
$ podman exec --user www-data nextcloud-fbx php occ config:system:set trusted_proxies 0 --value="localhost:4430"
$ podman exec --user www-data nextcloud-fbx php occ config:system:set overwritewebroot --value="/nextcloud"
$ podman exec --user www-data nextcloud-fbx php occ config:system:set overwritehost --value="localhost:4430"
$ podman exec --user www-data nextcloud-fbx php occ config:system:set overwrite.cli.url --value="https://localhost:4430/nextcloud"
$ podman exec --user www-data nextcloud-fbx php occ config:system:set overwriteprotocol --value="https"
Apache configuration:
<Location /nextcloud>
ProxyPass http://127.0.0.1:8181
RequestHeader set X-Forwarded-Proto 'https' env=HTTPS
Header always set Strict-Transport-Security "max-age=15552000; includeSubDomains"
</Location>
To surpass warnings shown in the Administration settings about Webadav service discovery the apache virtual host (not the config) has to be modified:
# https://docs.nextcloud.com/server/25/admin_manual/issues/general_troubleshooting.html#service-discovery
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule ^/\.well-known/carddav /nextcloud/remote.php/dav [R=301,L]
RewriteRule ^/\.well-known/caldav /nextcloud/remote.php/dav [R=301,L]
RewriteRule ^/\.well-known/webfinger /nextcloud/index.php/.well-known/webfinger [R=301,L]
RewriteRule ^/\.well-known/nodeinfo /nextcloud/index.php/.well-known/nodeinfo [R=301,L]
</IfModule>
This might conflict with Radicale though.
- Set up SSO
- Create an empty config:
podman exec --user www-data nextcloud-fbx php occ ldap:create-empty-config. In Owncloud it is possible to specify a name for the config, but this feature is missing from Nextcloud, so the config will be named s01. If the FreedomBox setup process fails for some reason and a new empty config is created, the number in the name will increment, so perhaps we should try to delete s01 before creating it. - The configuration values are taken from
podman exec --user www-data nextcloud-fbx php occ ldap:show-configafter configuring ldap on the GUI. Some values were automatically added, please review them:
- Create an empty config:
LDAP_SETTINGS = {
'ldapBase': 'dc=thisbox',
'ldapBaseGroups': 'dc=thisbox',
'ldapBaseUsers': 'dc=thisbox',
'ldapConfigurationActive': '1',
'ldapGroupDisplayName': 'cn',
'ldapGroupFilter': '(&(|(objectclass=posixGroup)))',
'ldapGroupFilterMode': '0',
'ldapGroupFilterObjectclass': 'posixGroup',
'ldapGroupMemberAssocAttr': 'memberUid',
'ldapHost': '172.16.16.1',
'ldapLoginFilter': '(&(|(objectclass=posixAccount))(uid=%uid))',
'ldapLoginFilterEmail': '0',
'ldapLoginFilterMode': '0',
'ldapLoginFilterUsername': '1',
'ldapNestedGroups': '0',
'ldapPort': '389',
'ldapTLS': '0',
'ldapUserDisplayName': 'cn',
'ldapUserFilter': '(|(objectclass=posixAccount))',
'ldapUserFilterMode': '0',
'ldapUserFilterObjectclass': 'account',
'ldapUuidGroupAttribute': 'auto',
'ldapUuidUserAttribute': 'auto',
'turnOffCertCheck': '0',
'turnOnPasswordChange': '0',
'useMemberOfToDetectMembership': '0'
}
for k, v in LDAP_SETTINGS.items():
subprocess.run(
['podman', 'exec', '--user', 'www-data', 'nextcloud-fbx', 'php', 'occ' , 'ldap:set-config',
's01', k, v],
check=True)
- Create a systemd service as described here and here so the container can be properly managed by FreedomBox:
$ export XDG_RUNTIME_DIR=/run/user/0
$ podman generate systemd --new nextcloud-fbx > /etc/systemd/system/nextcloud-fbx.service
$ systemctl daemon-reload
$ systemctl enable nextcloud-fbx.service
$ systemctl start nextcloud-fbx.service
- The admin password can be changed passing an environmental variable into the container:
$ podman exec --user www-data --env=OC_PASS=$password -it nextcloud-fbx sh -c "/var/www/html/occ user:resetpassword --password-from-env nextcloud-admin - Tests to-do: