mirror of
https://github.com/freedombox/FreedomBox.git
synced 2026-01-21 07:55:00 +00:00
nextcloud: Use php-fpm container instead of apache container
- Configuring just php-fpm is easier compared to configuring Apache + mod_php. There is no need to configure trusted proxies as the requests are made using the FastCGI protocol. - There is no need for a full web server as we already run Apache. - Place nextcloud data in /var/lib/container so that non-PHP files can be served directly without php-fpm involved. This location is more suitable for switching to nextcloud based on a .deb file (if ever). This is done by configuring the volume to serve a bind mounted directory of our choice. - Update Apache configuration to proxy to php-fpm instead of another web server. Include the changes needed for Apache configuration to serve non-php files directly. - Managed the volume using quadlet podman systemd generator. Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org> Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
This commit is contained in:
parent
e7e1a6b41d
commit
85cc9f08fa
@ -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()
|
||||
|
||||
@ -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',
|
||||
|
||||
@ -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
|
||||
|
||||
<Location /nextcloud>
|
||||
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
|
||||
</Location>
|
||||
<IfModule proxy_fcgi_module>
|
||||
ProxyPassMatch "^/nextcloud/(.*\.php(/.*)?)$" "fcgi://localhost:9000/var/www/html/$1"
|
||||
</IfModule>
|
||||
|
||||
<Directory /var/lib/nextcloud/>
|
||||
<IfModule !mod_php7.c>
|
||||
<IfModule proxy_fcgi_module>
|
||||
# Enable http authorization headers
|
||||
<IfModule setenvif_module>
|
||||
SetEnvIfNoCase ^Authorization$ "(.+)" HTTP_AUTHORIZATION=$1
|
||||
</IfModule>
|
||||
|
||||
<FilesMatch ".+\.phps$">
|
||||
# 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
|
||||
</FilesMatch>
|
||||
# Deny access to files without filename (e.g. '.php')
|
||||
<FilesMatch "^\.ph(ar|p|ps|tml)$">
|
||||
Require all denied
|
||||
</FilesMatch>
|
||||
</IfModule>
|
||||
</IfModule>
|
||||
|
||||
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
|
||||
</Directory>
|
||||
|
||||
@ -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']
|
||||
}
|
||||
}
|
||||
|
||||
@ -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'''<?php
|
||||
$CONFIG = [
|
||||
'memcache.distributed' => '\OC\Memcache\Redis',
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user