nextcloud: Connect to redis using Unix socket

- Connecting using Unix socket allows us to drop having to make redis listen on
the containers IP address.

- Instead configure redis to listen on unix socket.

- Keep the configuration file separate and include it the main configuration
file. This allows easier configuration changes in the future.

- Ensure that the drop-in configuration is available during setup.

- Ensure that redis is running during setup. This is important when app is
upgraded while it is disabled. Or when setup is re-run.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
This commit is contained in:
Sunil Mohan Adapa 2024-04-02 14:16:57 -07:00 committed by James Valleroy
parent 0f2760fbf8
commit 858d4a4337
No known key found for this signature in database
GPG Key ID: 77C0C75E7B650808
3 changed files with 38 additions and 25 deletions

View File

@ -74,6 +74,7 @@ class NextcloudApp(app_module.App):
'/etc/apache2/conf-available/nextcloud-freedombox.conf',
'/etc/fail2ban/jail.d/nextcloud-freedombox.conf',
'/etc/fail2ban/filter.d/nextcloud-freedombox.conf',
'/etc/redis/conf.d/freedombox.conf',
])
self.add(dropin_configs)
@ -115,10 +116,15 @@ class NextcloudApp(app_module.App):
"""Install and configure the app."""
super().setup(old_version)
with self.get_component(
'shared-daemon-nextcloud-mysql').ensure_running():
# Database needs to be running for successful initialization or
# upgrade of Nextcloud database.
privileged.setup()
'shared-daemon-nextcloud-redis').ensure_running():
with self.get_component(
'shared-daemon-nextcloud-mysql').ensure_running():
# Database needs to be running for successful initialization or
# upgrade of Nextcloud database.
# Drop-in configs need to be enabled for setup to succeed
self.get_component('dropin-configs-nextcloud').enable()
privileged.setup()
if not old_version:
self.enable()

View File

@ -0,0 +1,5 @@
# Listen on Unix socket for incoming connections in addition to listening on a
# TCP address/port.
unixsocket /run/redis/redis-server.sock
# Allow all users to connect to redis server using this socket
unixsocketperm 777

View File

@ -36,9 +36,6 @@ _cron_timer_file = _systemd_location / 'nextcloud-cron-freedombox.timer'
DB_BACKUP_FILE = pathlib.Path(
'/var/lib/plinth/backups-data/nextcloud-database.sql')
REDIS_CONFIG = '/etc/redis/redis.conf'
REDIS_CONFIG_AUG = f'/files{REDIS_CONFIG}'
@privileged
def setup():
@ -46,14 +43,23 @@ def setup():
database_password = _generate_secret_key(16)
administrator_password = _generate_secret_key(16)
# Setup database
_create_database()
_set_database_privileges(database_password)
# Setup redis for caching
_redis_listen_socket()
_set_redis_password(_generate_secret_key(16))
action_utils.service_restart('redis-server')
action_utils.podman_run(
network_name=NETWORK_NAME, subnet='172.16.16.0/24',
bridge_ip=BRIDGE_IP, host_port='8181', container_port='80',
container_ip=CONTAINER_IP, container_name=CONTAINER_NAME,
image_name=IMAGE_NAME, extra_run_options=[
'--volume=/run/mysqld/mysqld.sock:/run/mysqld/mysqld.sock',
'--volume=/run/redis/redis-server.sock:'
'/run/redis/redis-server.sock',
f'--volume={VOLUME_NAME}:/var/www/html',
f'--env=TRUSTED_PROXIES={BRIDGE_IP}',
'--env=OVERWRITEWEBROOT=/nextcloud'
@ -71,9 +77,6 @@ def setup():
time.sleep(1)
_nextcloud_setup_wizard(database_password, administrator_password)
_bind_redis(f'127.0.0.1 -::1 {BRIDGE_IP}')
_set_redis_password(_generate_secret_key(16))
action_utils.service_restart('redis-server')
_create_redis_config(_get_redis_password())
_configure_ldap()
@ -282,10 +285,6 @@ WantedBy=timers.target
@privileged
def uninstall():
"""Uninstall Nextcloud"""
# Set bind setting back to default in case other apps
# are still using it
_bind_redis('127.0.0.1 -::1')
action_utils.service_restart('redis-server')
_drop_database()
_configure_firewall(action='remove', interface_name=NETWORK_NAME)
action_utils.podman_uninstall(container_name=CONTAINER_NAME,
@ -378,8 +377,7 @@ $CONFIG = [
'memcache.locking' => '\\\\OC\\\\Memcache\\\\Redis',
'memcache.distributed' => '\\\\OC\\\\Memcache\\\\Redis',
'redis' => [
'host' => '{BRIDGE_IP}',
'port' => '6379',
'host' => '/run/redis/redis-server.sock',
'password' => '{password}',
],
];
@ -392,27 +390,31 @@ def _load_augeas():
"""Initialize Augeas."""
aug = augeas.Augeas(flags=augeas.Augeas.NO_LOAD +
augeas.Augeas.NO_MODL_AUTOLOAD)
aug.transform('Spacevars', REDIS_CONFIG)
aug.set('/augeas/context', REDIS_CONFIG_AUG)
redis_config = '/etc/redis/redis.conf'
aug.transform('Spacevars', redis_config)
aug.set('/augeas/context', '/files' + redis_config)
aug.load()
return aug
def _bind_redis(ip_address):
"""Configure Redis to listen on the podman bridge adapter."""
def _redis_listen_socket():
"""Configure Redis to listen on a UNIX socket."""
aug = _load_augeas()
aug.set(REDIS_CONFIG_AUG + '/bind', ip_address)
value = '/etc/redis/conf.d/*.conf'
found = any((aug.get(match_) == value for match_ in aug.match('include')))
if not found:
aug.set('include[last() + 1]', value)
aug.save()
def _set_redis_password(password):
def _set_redis_password(password: str):
if _get_redis_password() is None:
aug = _load_augeas()
aug.set(REDIS_CONFIG_AUG + '/requirepass', password)
aug.set('requirepass', password)
aug.save()
def _get_redis_password() -> str:
aug = _load_augeas()
password = aug.get(REDIS_CONFIG_AUG + '/requirepass')
return password
return aug.get('requirepass')