From 6be4a50f8fc3196dca64bc7878a891402f8e61a7 Mon Sep 17 00:00:00 2001 From: Bert-Jan Fikse Date: Fri, 6 Mar 2026 17:00:33 +0100 Subject: [PATCH] chore: ensure we can use the same collabora instance for multiple cloud instances Signed-off-by: Bert-Jan Fikse --- roles/collabora/defaults/main.yml | 13 +- roles/collabora/tasks/main.yml | 13 + roles/collabora/templates/coolwsd.xml.j2 | 340 ++++++++++++++++++ .../collabora/templates/docker-compose.yml.j2 | 8 +- roles/nextcloud/tasks/collabora.yml | 7 +- roles/opencloud/defaults/main.yml | 5 + .../opencloud/templates/docker-compose.yml.j2 | 31 +- 7 files changed, 405 insertions(+), 12 deletions(-) create mode 100644 roles/collabora/templates/coolwsd.xml.j2 diff --git a/roles/collabora/defaults/main.yml b/roles/collabora/defaults/main.yml index f5b48c8..3cfb559 100644 --- a/roles/collabora/defaults/main.yml +++ b/roles/collabora/defaults/main.yml @@ -9,6 +9,7 @@ docker_volume_base_dir: /srv/data # Collabora-specific configuration collabora_service_name: collabora collabora_docker_compose_dir: "{{ docker_compose_base_dir }}/{{ collabora_service_name }}" +collabora_docker_volume_dir: "{{ docker_volume_base_dir }}/{{ collabora_service_name }}" # Service configuration collabora_domain: "office.local.test" @@ -20,9 +21,15 @@ collabora_extra_hosts: [] collabora_traefik_network: "proxy" collabora_use_ssl: true -# Allowed WOPI host domains (Nextcloud, OpenCloud, etc.) -# These domains are allowed to open documents via Collabora. +# SSL verification for WOPI callbacks (set to false for self-signed certs) +collabora_ssl_verification: true + +# Allowed WOPI host domains (Nextcloud, OpenCloud WOPI server, etc.) +# These domains are allowed to send WOPI requests to Collabora. # Each entry is used as a regex pattern (dots are auto-escaped). collabora_allowed_domains: - "nextcloud.local.test" - - "opencloud.local.test" \ No newline at end of file + +# Domains allowed to embed Collabora in an iframe (Nextcloud, OpenCloud, etc.) +collabora_frame_ancestors: + - "nextcloud.local.test" \ No newline at end of file diff --git a/roles/collabora/tasks/main.yml b/roles/collabora/tasks/main.yml index 1893498..b6146c7 100644 --- a/roles/collabora/tasks/main.yml +++ b/roles/collabora/tasks/main.yml @@ -8,6 +8,19 @@ state: directory mode: '0755' +- name: Create collabora volume directory + file: + path: "{{ collabora_docker_volume_dir }}" + state: directory + mode: '0755' + +- name: Create coolwsd configuration + template: + src: coolwsd.xml.j2 + dest: "{{ collabora_docker_volume_dir }}/coolwsd.xml" + mode: '0644' + notify: restart collabora + - name: Create docker-compose file for collabora template: src: docker-compose.yml.j2 diff --git a/roles/collabora/templates/coolwsd.xml.j2 b/roles/collabora/templates/coolwsd.xml.j2 new file mode 100644 index 0000000..df5dd50 --- /dev/null +++ b/roles/collabora/templates/coolwsd.xml.j2 @@ -0,0 +1,340 @@ + + + + + + false + + + de_DE en_GB en_US es_ES fr_FR it nl pt_BR pt_PT ru + + + false + + + + true + + + + + false + + + + + + + true + + + + false + true + + + 4 + 10 + true + + + 4 + 5 + 5 + 120 + false + 96 + 3600 + 30 + 300 + true + true + false + 0 + 8000 + 0 + 0 + 100 + 5 + 100 + 500 + 5000 + + 10000 + 60 + 300 + 3072 + 85 + 120 + + + + + 300 + 900 + + 6 + + + + + + true + warning + trace + Socket,WebSocket,Admin,Pixel + notice + fatal + false + -INFO-WARN + + /var/log/coolwsd.log + never + timestamp + true + 10 days + 10 + true + false + + + false + 82589933 + + false + false + false + + + true + + + true + true + + /var/log/coolwsd-ui-cmd.log + 10 + true + false + + + + + /var/log/coolwsd.trace.json + + + false + + + + + + + + false + + + + + all + any + + + 192\.168\.[0-9]{1,3}\.[0-9]{1,3} + ::ffff:192\.168\.[0-9]{1,3}\.[0-9]{1,3} + 127\.0\.0\.1 + ::ffff:127\.0\.0\.1 + ::1 + 172\.1[6789]\.[0-9]{1,3}\.[0-9]{1,3} + ::ffff:172\.1[6789]\.[0-9]{1,3}\.[0-9]{1,3} + 172\.2[0-9]\.[0-9]{1,3}\.[0-9]{1,3} + ::ffff:172\.2[0-9]\.[0-9]{1,3}\.[0-9]{1,3} + 172\.3[01]\.[0-9]{1,3}\.[0-9]{1,3} + ::ffff:172\.3[01]\.[0-9]{1,3}\.[0-9]{1,3} + 10\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3} + ::ffff:10\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3} + + + 192\.168\.[0-9]{1,3}\.[0-9]{1,3} + ::ffff:192\.168\.[0-9]{1,3}\.[0-9]{1,3} + 127\.0\.0\.1 + ::ffff:127\.0\.0\.1 + ::1 + 172\.1[6789]\.[0-9]{1,3}\.[0-9]{1,3} + ::ffff:172\.1[6789]\.[0-9]{1,3}\.[0-9]{1,3} + 172\.2[0-9]\.[0-9]{1,3}\.[0-9]{1,3} + ::ffff:172\.2[0-9]\.[0-9]{1,3}\.[0-9]{1,3} + 172\.3[01]\.[0-9]{1,3}\.[0-9]{1,3} + ::ffff:172\.3[01]\.[0-9]{1,3}\.[0-9]{1,3} + 10\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3} + ::ffff:10\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3} + localhost + + + {{ collabora_frame_ancestors | map('regex_replace', '^(.*)$', 'https://\\1') | join(' ') }} + 30 + false + + + + true + false + /etc/coolwsd/cert.pem + /etc/coolwsd/key.pem + /etc/coolwsd/ca-chain.cert.pem + false + + + 1000 + + + + + false + 31536000 + + + + + true + true + 1800 + false + 1 + false + false + false + + + + + + + + 0.2 + + + + + default + true + true + + + + + + 0 + + 900 + + + +{% for domain in collabora_allowed_domains %} + + https://{{ domain }}:443 + +{% endfor %} + + + false + + + true + + + + + + + + + + true + false + + + + true + true + true + true + + + + + + + 250 + 5 + + 3000 + + + + + 1000 + + + + false + false + false + false + false + false + + + + 3600 + + + + + + + false + + + + + + + log + + + + + 180 + + false + + + + + + + + false + + + + true + + + https://help.collaboraoffice.com/help.html? + + + false + + + + false + false + + + + true + + + \ No newline at end of file diff --git a/roles/collabora/templates/docker-compose.yml.j2 b/roles/collabora/templates/docker-compose.yml.j2 index cb284fb..c0f589e 100644 --- a/roles/collabora/templates/docker-compose.yml.j2 +++ b/roles/collabora/templates/docker-compose.yml.j2 @@ -4,11 +4,9 @@ services: container_name: {{ collabora_service_name }} restart: unless-stopped environment: - domain: {{ collabora_allowed_domains | map('replace', '.', '\\.') | map('regex_replace', '^(.*)$', '^\\1$$') | join('|') }} - extra_params: >- - --o:ssl.enable=false - --o:ssl.termination=true - --o:net.frame_ancestors={{ collabora_allowed_domains | map('regex_replace', '^(.*)$', 'https://\\1') | join(' ') }} + extra_params: "--o:ssl.enable=false --o:ssl.termination=true --o:ssl.ssl_verification={{ collabora_ssl_verification | string | lower }}" + volumes: + - {{ collabora_docker_volume_dir }}/coolwsd.xml:/etc/coolwsd/coolwsd.xml:ro cap_add: - MKNOD networks: diff --git a/roles/nextcloud/tasks/collabora.yml b/roles/nextcloud/tasks/collabora.yml index a165ffa..05c56e4 100644 --- a/roles/nextcloud/tasks/collabora.yml +++ b/roles/nextcloud/tasks/collabora.yml @@ -14,4 +14,9 @@ - name: Set Collabora WOPI allowlist community.docker.docker_container_exec: container: "{{ nextcloud_docker_compose_dir | basename }}-nextcloud-1" - command: php /var/www/html/occ config:app:set richdocuments wopi_allowlist --value='' \ No newline at end of file + command: php /var/www/html/occ config:app:set richdocuments wopi_allowlist --value='' + +- name: Activate richdocuments configuration (fetch discovery from Collabora) + community.docker.docker_container_exec: + container: "{{ nextcloud_docker_compose_dir | basename }}-nextcloud-1" + command: php /var/www/html/occ richdocuments:activate-config \ No newline at end of file diff --git a/roles/opencloud/defaults/main.yml b/roles/opencloud/defaults/main.yml index b1e6dcf..9e43dcc 100644 --- a/roles/opencloud/defaults/main.yml +++ b/roles/opencloud/defaults/main.yml @@ -41,5 +41,10 @@ opencloud_s3_access_key: "" opencloud_s3_secret_key: "" opencloud_s3_bucket: "opencloud" +# Collabora integration (set opencloud_collabora_domain to enable) +opencloud_collabora_domain: "" +opencloud_wopi_domain: "" +opencloud_collabora_insecure: true + # CSP configuration (extra URLs to allow in connect-src) opencloud_csp_extra_connect_src: [] \ No newline at end of file diff --git a/roles/opencloud/templates/docker-compose.yml.j2 b/roles/opencloud/templates/docker-compose.yml.j2 index 7dff3b3..bc142a2 100644 --- a/roles/opencloud/templates/docker-compose.yml.j2 +++ b/roles/opencloud/templates/docker-compose.yml.j2 @@ -7,8 +7,8 @@ services: - /bin/sh command: ["-c", "opencloud init || true; opencloud server"] volumes: - - {{ opencloud_docker_volume_dir }}/config:/etc/ocis - - {{ opencloud_docker_volume_dir }}/data:/var/lib/ocis + - {{ opencloud_docker_volume_dir }}/config:/etc/opencloud + - {{ opencloud_docker_volume_dir }}/data:/var/lib/opencloud environment: {% if opencloud_use_ssl %} OC_URL: "https://{{ opencloud_domain }}" @@ -19,7 +19,7 @@ services: OC_LOG_LEVEL: "{{ opencloud_log_level }}" PROXY_TLS: "false" {% if opencloud_csp_extra_connect_src | length > 0 %} - PROXY_CSP_CONFIG_FILE_OVERRIDE_LOCATION: "/etc/ocis/csp-override.yaml" + PROXY_CSP_CONFIG_FILE_OVERRIDE_LOCATION: "/etc/opencloud/csp-override.yaml" {% endif %} IDM_ADMIN_PASSWORD: "{{ opencloud_admin_password }}" {% if opencloud_oidc_issuer %} @@ -43,6 +43,19 @@ services: STORAGE_USERS_DECOMPOSEDS3_ACCESS_KEY: "{{ opencloud_s3_access_key }}" STORAGE_USERS_DECOMPOSEDS3_SECRET_KEY: "{{ opencloud_s3_secret_key }}" STORAGE_USERS_DECOMPOSEDS3_BUCKET: "{{ opencloud_s3_bucket }}" +{% endif %} +{% if opencloud_collabora_domain %} + OC_ADD_RUN_SERVICES: "collaboration" + COLLABORA_DOMAIN: "{{ opencloud_collabora_domain }}" + COLLABORATION_APP_NAME: "CollaboraOnline" + COLLABORATION_APP_PRODUCT: "Collabora" + COLLABORATION_APP_ADDR: "https://{{ opencloud_collabora_domain }}" + COLLABORATION_APP_INSECURE: "{{ opencloud_collabora_insecure | string | lower }}" + COLLABORATION_APP_PROOF_DISABLE: "{{ opencloud_collabora_insecure | string | lower }}" + COLLABORATION_CS3API_DATAGATEWAY_INSECURE: "{{ opencloud_collabora_insecure | string | lower }}" + COLLABORATION_HTTP_ADDR: "0.0.0.0:9300" + COLLABORATION_WOPI_SRC: "https://{{ opencloud_wopi_domain }}" + FRONTEND_APP_HANDLER_SECURE_VIEW_APP_ADDR: "eu.opencloud.api.collaboration" {% endif %} networks: - {{ opencloud_traefik_network }} @@ -63,6 +76,18 @@ services: - traefik.http.routers.{{ opencloud_service_name }}.entrypoints=web {% endif %} - traefik.http.services.{{ opencloud_service_name }}.loadbalancer.server.port={{ opencloud_port }} +{% if opencloud_collabora_domain %} + - traefik.http.routers.{{ opencloud_service_name }}.service={{ opencloud_service_name }} + - traefik.http.routers.{{ opencloud_service_name }}-wopi.rule=Host(`{{ opencloud_wopi_domain }}`) + - traefik.http.routers.{{ opencloud_service_name }}-wopi.service={{ opencloud_service_name }}-wopi + - traefik.http.services.{{ opencloud_service_name }}-wopi.loadbalancer.server.port=9300 +{% if opencloud_use_ssl %} + - traefik.http.routers.{{ opencloud_service_name }}-wopi.entrypoints=websecure + - traefik.http.routers.{{ opencloud_service_name }}-wopi.tls=true +{% else %} + - traefik.http.routers.{{ opencloud_service_name }}-wopi.entrypoints=web +{% endif %} +{% endif %} networks: {{ opencloud_traefik_network }}: