diff --git a/plinth/action_utils.py b/plinth/action_utils.py
index 97201bb32..61783f21a 100644
--- a/plinth/action_utils.py
+++ b/plinth/action_utils.py
@@ -489,22 +489,44 @@ def is_package_manager_busy():
return False
-def podman_create(container_name: str, image_name: str,
- volumes: dict[str, str] | None = None,
+def podman_create(container_name: str, image_name: str, volume_name: str,
+ volume_path: str, volumes: dict[str, str] | None = None,
env: dict[str, str] | None = None):
"""Remove and recreate a podman container."""
+ service_stop(f'{volume_name}-volume.service')
service_stop(container_name)
directory = pathlib.Path('/etc/containers/systemd')
directory.mkdir(parents=True, exist_ok=True)
+ subprocess.run(['podman', 'volume', 'rm', '--force', volume_name],
+ check=False)
+
+ directory = pathlib.Path('/etc/containers/systemd')
+ directory.mkdir(parents=True, exist_ok=True)
+
+ pathlib.Path(volume_path).mkdir(parents=True, exist_ok=True)
+ # Create storage volume
+ volume_file = directory / f'{volume_name}.volume'
+ contents = f'''[Volume]
+Device={volume_path}
+Driver=local
+VolumeName={volume_name}
+Options=bind
+'''
+ volume_file.write_text(contents)
+
service_file = directory / f'{container_name}.container'
volume_lines = '\n'.join([
f'Volume={source}:{dest}' for source, dest in (volumes or {}).items()
])
env_lines = '\n'.join(
[f'Environment={key}={value}' for key, value in (env or {}).items()])
- contents = f'''[Container]
+ contents = f'''[Unit]
+Requires=nextcloud-freedombox-volume.service
+After=nextcloud-freedombox-volume.service
+
+[Container]
AutoUpdate=registry
ContainerName=%N
{env_lines}
@@ -522,11 +544,18 @@ WantedBy=default.target
service_daemon_reload()
-def podman_uninstall(container_name: str, volume_name: str, image_name: str):
+def podman_uninstall(container_name: str, volume_name: str, image_name: str,
+ volume_path: str):
"""Remove a podman container's components and systemd unit."""
- subprocess.run(['podman', 'volume', 'rm', volume_name], check=True)
- subprocess.run(['podman', 'image', 'rm', image_name], check=True)
+ subprocess.run(['podman', 'volume', 'rm', '--force', volume_name],
+ check=True)
+ subprocess.run(['podman', 'image', 'rm', '--ignore', image_name],
+ check=True)
+ volume_file = pathlib.Path(
+ '/etc/containers/systemd/') / f'{volume_name}.volume'
+ volume_file.unlink(missing_ok=True)
service_file = pathlib.Path(
'/etc/containers/systemd/') / f'{container_name}.container'
service_file.unlink(missing_ok=True)
+ shutil.rmtree(volume_path, ignore_errors=True)
service_daemon_reload()
diff --git a/plinth/modules/nextcloud/__init__.py b/plinth/modules/nextcloud/__init__.py
index f21e3f1aa..9ae5dc3f7 100644
--- a/plinth/modules/nextcloud/__init__.py
+++ b/plinth/modules/nextcloud/__init__.py
@@ -87,7 +87,7 @@ class NextcloudApp(app_module.App):
self.add(firewall)
firewall_local_protection = FirewallLocalProtection(
- 'firewall-local-protection-nextcloud', ['8181'])
+ 'firewall-local-protection-nextcloud', ['9000'])
self.add(firewall_local_protection)
webserver = Webserver('webserver-nextcloud', 'nextcloud-freedombox',
diff --git a/plinth/modules/nextcloud/data/usr/share/freedombox/etc/apache2/conf-available/nextcloud-freedombox.conf b/plinth/modules/nextcloud/data/usr/share/freedombox/etc/apache2/conf-available/nextcloud-freedombox.conf
index 8d3758f54..b201d0e2f 100644
--- a/plinth/modules/nextcloud/data/usr/share/freedombox/etc/apache2/conf-available/nextcloud-freedombox.conf
+++ b/plinth/modules/nextcloud/data/usr/share/freedombox/etc/apache2/conf-available/nextcloud-freedombox.conf
@@ -16,10 +16,36 @@ Redirect 301 /.well-known/caldav /nextcloud/remote.php/dav
Redirect 301 /.well-known/webfinger /nextcloud/index.php/.well-known/webfinger
Redirect 301 /.well-known/nodeinfo /nextcloud/index.php/.well-known/nodeinfo
-
- ProxyPass http://127.0.0.1:8181
+Alias /nextcloud/ /var/lib/nextcloud/
- ## Send the scheme from user's request to enable Nextcloud to redirect URLs,
- ## set cookies, set absolute URLs (if any) properly.
- RequestHeader set X-Forwarded-Proto 'https' env=HTTPS
-
+
+ ProxyPassMatch "^/nextcloud/(.*\.php(/.*)?)$" "fcgi://localhost:9000/var/www/html/$1"
+
+
+
+
+
+ # Enable http authorization headers
+
+ SetEnvIfNoCase ^Authorization$ "(.+)" HTTP_AUTHORIZATION=$1
+
+
+
+ # Deny access to raw php sources by default
+ # To re-enable it's recommended to enable access to the files
+ # only in specific virtual host or directory
+ Require all denied
+
+ # Deny access to files without filename (e.g. '.php')
+
+ Require all denied
+
+
+
+
+ Require all granted
+
+ # Allow a limited set of directives in .htaccess files found in /, /config,
+ # and /data directories of nextcloud.
+ AllowOverride AuthConfig FileInfo Indexes Limit Options
+
diff --git a/plinth/modules/nextcloud/manifest.py b/plinth/modules/nextcloud/manifest.py
index 31a1fce10..fa875a67a 100644
--- a/plinth/modules/nextcloud/manifest.py
+++ b/plinth/modules/nextcloud/manifest.py
@@ -48,9 +48,7 @@ clients = [{
backup = {
'data': {
- 'directories': [
- '/var/lib/containers/storage/volumes/nextcloud-volume-freedombox/'
- ],
+ 'directories': ['/var/lib/nextcloud/'],
'files': ['/var/lib/plinth/backups-data/nextcloud-database.sql']
}
}
diff --git a/plinth/modules/nextcloud/privileged.py b/plinth/modules/nextcloud/privileged.py
index dd19ef49a..ac9358a61 100644
--- a/plinth/modules/nextcloud/privileged.py
+++ b/plinth/modules/nextcloud/privileged.py
@@ -17,8 +17,8 @@ from plinth.actions import privileged
CONTAINER_NAME = 'nextcloud-freedombox'
SERVICE_NAME = 'nextcloud-freedombox'
-VOLUME_NAME = 'nextcloud-volume-freedombox'
-IMAGE_NAME = 'docker.io/library/nextcloud:stable-apache'
+VOLUME_NAME = 'nextcloud-freedombox'
+IMAGE_NAME = 'docker.io/library/nextcloud:stable-fpm'
DB_HOST = 'localhost'
DB_NAME = 'nextcloud_fbx'
@@ -26,8 +26,7 @@ DB_USER = 'nextcloud_fbx'
GUI_ADMIN = 'nextcloud-admin'
REDIS_DB = 8 # Don't clash with other redis apps
-_volume_path = pathlib.Path(
- '/var/lib/containers/storage/volumes/') / VOLUME_NAME
+_data_path = pathlib.Path('/var/lib/nextcloud/')
_systemd_location = pathlib.Path('/etc/systemd/system/')
_cron_service_file = _systemd_location / 'nextcloud-cron-freedombox.service'
_cron_timer_file = _systemd_location / 'nextcloud-cron-freedombox.timer'
@@ -55,16 +54,18 @@ def setup():
'/run/slapd/ldapi': '/run/slapd/ldapi',
VOLUME_NAME: '/var/www/html'
}
- env = {'TRUSTED_PROXIES': '127.0.0.1', 'OVERWRITEWEBROOT': '/nextcloud'}
+ env = {'OVERWRITEWEBROOT': '/nextcloud'}
action_utils.podman_create(container_name=CONTAINER_NAME,
- image_name=IMAGE_NAME, volumes=volumes, env=env)
+ image_name=IMAGE_NAME, volume_name=VOLUME_NAME,
+ volume_path=str(_data_path), volumes=volumes,
+ env=env)
action_utils.service_start(CONTAINER_NAME)
# OCC isn't immediately available after the container is spun up.
# Wait until CAN_INSTALL file is available.
timeout = 300
while timeout > 0:
- if (_volume_path / '_data/config/CAN_INSTALL').exists():
+ if (_data_path / 'config/CAN_INSTALL').exists():
break
timeout = timeout - 1
@@ -278,7 +279,8 @@ def uninstall():
_drop_database()
action_utils.podman_uninstall(container_name=CONTAINER_NAME,
volume_name=VOLUME_NAME,
- image_name=IMAGE_NAME)
+ image_name=IMAGE_NAME,
+ volume_path=str(_data_path))
for path in [_cron_service_file, _cron_timer_file]:
path.unlink(missing_ok=True)
@@ -366,7 +368,7 @@ def _get_dbpassword():
def _create_redis_config():
"""Create a php file for Redis configuration."""
- config_file = _volume_path / '_data/config/freedombox.config.php'
+ config_file = _data_path / 'config/freedombox.config.php'
file_content = fr''' '\OC\Memcache\Redis',