Files
truenas-apps/ix-dev/community/opencloud/templates/docker-compose.yaml
truenasbot efd88182c0 chore(deps): update updates-patch-minor (#3740)
* chore(deps): update updates-patch-minor

* devbox (#3726)

* bump devbox

* order

* another

* more scripts

* opencloud: fix csp (#3741)

* opencloud: fix csp

* better

---------

Co-authored-by: bugclerk <bugclerk@ixsystems.com>
Co-authored-by: Stavros Kois <47820033+stavros-k@users.noreply.github.com>
2025-11-30 21:10:19 +02:00

181 lines
9.3 KiB
YAML

{% from "macros/app_init.sh" import app_init %}
{% set tpl = ix_lib.base.render.Render(values) %}
{% set c1 = tpl.add_container(values.consts.opencloud_container_name, "image") %}
{% set perm_container = tpl.deps.perms(values.consts.perms_container_name) %}
{% set perms_config = {"uid": values.run_as.user, "gid": values.run_as.group, "mode": "check"} %}
{% set csp = namespace(x={}) %}
{% set extra_services = namespace(x=["notifications"]) %}
{% for key, values in values.consts.csp_config.items() %}
{% do csp.x.update({key: values}) %}
{% endfor %}
{% for x in values.opencloud.additional_csp %}
{% set list_items = x['items'] | map(attribute="value") | list %}
{% set values = csp.x.get(x.directive, []) + list_items %}
{% do csp.x.update({x.directive: values}) %}
{% endfor %}
{# Apps Init #}
{% set app_containers = namespace(x=[]) %}
{% set has_additional_config = namespace(x=False) %}
{% for app_name, enabled in values.opencloud.apps.items() %}
{% set target_path = "%s/web/assets/apps"|format(values.consts.data_path) %}
{% set app_config = values.consts.app_map[app_name] %}
{% set app = tpl.add_container(app_config.container_name, app_config.image) %}
{% do app_containers.x.append(app) %}
{% do c1.depends.add_dependency(app_config.container_name, "service_completed_successfully") %}
{% do app.set_user(0, 0) %}
{% do app.add_caps(["CHOWN", "FOWNER", "DAC_OVERRIDE"]) %}
{% do app.setup_as_helper() %}
{% do app.add_storage(values.consts.data_path, values.storage.data) %}
{% do app.environment.add_env("TARGET_PATH", target_path) %}
{% do app.environment.add_env("APP_ID", app_config.id) %}
{% do app.environment.add_env("SOURCE_PATH", app_config.source) %}
{% do app.environment.add_env("ENABLED", enabled) %}
{% do app.configs.add("app_entrypoint", app_init(values), "/ix-entrypoint.sh", "0755") %}
{% do app.set_entrypoint(["/ix-entrypoint.sh"]) %}
{% if app_config.config_url %}
{% set has_additional_config.x = True %}
{% do tpl.notes.add_info("The app '%s' requires additional configuration. Please see %s for details."|format(app_name, app_config.config_url)) %}
{% endif %}
{% endfor %}
{% set body = namespace(x=values.consts.notes_body) %}
{% if has_additional_config.x %}{% set body.x = "%s\n\n%s"|format(body.x, values.consts.app_config_notes_body) %}{% endif %}
{% do c1.set_user(values.run_as.user, values.run_as.group) %}
{% do c1.healthcheck.set_test("curl", {"port": values.network.web_port.port_number, "path": "/healthz", "scheme": "https"}) %}
{% do c1.configs.add("entrypoint", values.consts.entrypoint_script, "/ix-entrypoint.sh", "0755") %}
{% do c1.set_entrypoint(["/ix-entrypoint.sh"]) %}
{# TIKA #}
{% if values.opencloud.full_text_search.enabled %}
{% set tika = tpl.deps.tika(values.consts.tika_container_name, "tika_image", {"port": values.consts.tika_port}) %}
{% do c1.depends.add_dependency(values.consts.tika_container_name, "service_healthy") %}
{% do c1.environment.add_env("FRONTEND_FULL_TEXT_SEARCH_ENABLED", true) %}
{% do c1.environment.add_env("SEARCH_EXTRACTOR_TYPE", "tika") %}
{% do c1.environment.add_env("SEARCH_EXTRACTOR_TIKA_TIKA_URL", tika.get_url()) %}
{% endif %}
{# Networking #}
{% do c1.environment.add_env("PROXY_HTTP_ADDR", ":%d"|format(values.network.web_port.port_number)) %}
{% if values.network.metrics_port.bind_mode %}
{% do c1.environment.add_env("PROXY_DEBUG_ADDR", ":%d"|format(values.network.metrics_port.port_number)) %}
{% endif %}
{% set url = tpl.funcs.url_to_dict(values.opencloud.app_url, true) %}
{% if url.scheme != "https" %}{% do tpl.funcs.fail("The app URL must be HTTPS") %}{% endif %}
{% do c1.environment.add_env("OC_URL", values.opencloud.app_url.rstrip("/")) %}
{% do c1.environment.add_env("OC_INSECURE", values.opencloud.insecure) %}
{% if values.network.certificate_id %}
{% do c1.environment.add_env("PROXY_TRANSPORT_TLS_KEY", values.consts.ssl_key_path) %}
{% do c1.environment.add_env("PROXY_TRANSPORT_TLS_CERT", values.consts.ssl_cert_path) %}
{% set cert = values.ix_certificates[values.network.certificate_id] %}
{% do c1.configs.add("private", cert.privatekey, values.consts.ssl_key_path) %}
{% do c1.configs.add("public", cert.certificate, values.consts.ssl_cert_path) %}
{% endif %}
{# Collaboration #}
{% if values.opencloud.collaboration.enabled %}
{% set collab_url = tpl.funcs.url_to_dict(values.opencloud.collaboration.url, true) %}
{% if collab_url.scheme != "https" %}{% do tpl.funcs.fail("The collaboration URL must be HTTPS") %}{% endif %}
{% do extra_services.x.append("collaboration") %}
{% do csp.x.update({
"frame-src": csp.x.get("frame-src", []) + [values.opencloud.collaboration.url],
"img-src": csp.x.get("img-src", []) + [values.opencloud.collaboration.url],
}) %}
{% set app_url = values.opencloud.collaboration.url.rstrip("/") %}
{% do c1.environment.add_env("FRONTEND_APP_HANDLER_SECURE_VIEW_APP_ADDR", "eu.opencloud.api.collaboration") %}
{% do c1.environment.add_env("COLLABORATION_STORE", "nats-js-kv") %}
{% do c1.environment.add_env("COLLABORATION_APP_ADDR", values.opencloud.collaboration.url.rstrip("/")) %}
{% do c1.environment.add_env("COLLABORATION_APP_INSECURE", values.opencloud.collaboration.insecure) %}
{% do c1.environment.add_env("COLLABORATION_CS3API_DATAGATEWAY_INSECURE", values.opencloud.collaboration.insecure) %}
{% do c1.environment.add_env("COLLABORATION_WOPI_SRC", values.opencloud.app_url.rstrip("/")) %}
{% do c1.environment.add_env("COLLABORATION_APP_PROOF_DISABLE", values.opencloud.collaboration.proof_disable) %}
{% if values.opencloud.collaboration.type == "collabora" %}
{% do c1.environment.add_env("COLLABORATION_APP_NAME", "CollaboraOnline") %}
{% do c1.environment.add_env("COLLABORATION_APP_PRODUCT", "Collabora") %}
{% do c1.environment.add_env("COLLABORATION_APP_ICON", "%s/favicon.ico"|format(app_url)) %}
{% elif values.opencloud.collaboration.type == "onlyoffice" %}
{% do c1.environment.add_env("COLLABORATION_APP_NAME", "OnlyOffice") %}
{% do c1.environment.add_env("COLLABORATION_APP_PRODUCT", "OnlyOffice") %}
{% do c1.environment.add_env("COLLABORATION_APP_ICON", "%s/web-apps/apps/documenteditor/main/resources/img/favicon.ico"|format(app_url)) %}
{% do c1.environment.add_env("COLLABORATION_JWT_SECRET", values.opencloud.collaboration.jwt_secret) %}
{% endif %}
{% endif %}
{# SMTP #}
{% do c1.environment.add_env("NOTIFICATIONS_SMTP_SENDER", values.opencloud.smtp.sender or "OpenCloud notifications <notifications@cloud.opencloud.test>") %}
{% if values.opencloud.smtp.enabled %}
{% do c1.environment.add_env("NOTIFICATIONS_SMTP_HOST", values.opencloud.smtp.host) %}
{% do c1.environment.add_env("NOTIFICATIONS_SMTP_PORT", values.opencloud.smtp.port) %}
{% do c1.environment.add_env("NOTIFICATIONS_SMTP_INSECURE", values.opencloud.smtp.insecure) %}
{% do c1.environment.add_env("NOTIFICATIONS_SMTP_ENCRYPTION", values.opencloud.smtp.encryption) %}
{% if values.opencloud.smtp.username %}
{% do c1.environment.add_env("NOTIFICATIONS_SMTP_USERNAME", values.opencloud.smtp.username) %}
{% endif %}
{% if values.opencloud.smtp.password %}
{% do c1.environment.add_env("NOTIFICATIONS_SMTP_PASSWORD", values.opencloud.smtp.password) %}
{% endif %}
{% endif %}
{# Services #}
{% if values.opencloud.additional_services %}
{% do extra_services.x.extend(values.opencloud.additional_services) %}
{% endif %}
{% for key, values in csp.x.items() %}
{% do csp.x.update({key: values | unique | list}) %}
{% endfor %}
{% set csp_yaml = tpl.funcs.to_yaml({"directives": csp.x}) %}
{% set csp_notes = "Generated CSP File:\n\n```yaml\n%s```"|format(csp_yaml) %}
{% set body.x = "%s\n\n%s"|format(body.x, csp_notes) %}
{% do c1.configs.add("csp", csp_yaml, values.consts.csp_config_path) %}
{% do c1.environment.add_env("OC_ADD_RUN_SERVICES", extra_services.x | unique | list | join(",")) %}
{% do c1.environment.add_env("IDM_ADMIN_PASSWORD", "admin") %}
{% do c1.environment.add_user_envs(values.opencloud.additional_envs) %}
{# Ports #}
{% do c1.add_port(values.network.web_port) %}
{# Storage #}
{% do c1.environment.add_env("STORAGE_USERS_DRIVER", "posix") %}
{% do c1.environment.add_env("STORAGE_USERS_ID_CACHE_STORE", "nats-js-kv") %}
{% do c1.environment.add_env("OC_BASE_DATA_PATH", values.consts.data_path) %}
{% do c1.environment.add_env("OC_CONFIG_DIR", values.consts.config_path) %}
{% do c1.environment.add_env("PROXY_CSP_CONFIG_FILE_LOCATION", values.consts.csp_config_path) %}
{% do c1.add_storage(values.consts.config_path, values.storage.config) %}
{% do perm_container.add_or_skip_action("config", values.storage.config, perms_config) %}
{% do c1.add_storage(values.consts.data_path, values.storage.data) %}
{% do perm_container.add_or_skip_action("data", values.storage.data, perms_config) %}
{% for store in values.storage.additional_storage %}
{% do c1.add_storage(store.mount_path, store) %}
{% do perm_container.add_or_skip_action(store.mount_path, store, perms_config) %}
{% endfor %}
{% if perm_container.has_actions() %}
{% do perm_container.activate() %}
{% do c1.depends.add_dependency(values.consts.perms_container_name, "service_completed_successfully") %}
{% for c in app_containers.x %}
{% do c.depends.add_dependency(values.consts.perms_container_name, "service_completed_successfully") %}
{% endfor %}
{% endif %}
{% do tpl.portals.add(values.network.web_port, {"scheme": "https"}) %}
{% do tpl.notes.set_body(body.x) %}
{{ tpl.render() | tojson }}