From 9a4bf912769a72361d2220306b2d39ef47a5827e Mon Sep 17 00:00:00 2001 From: Kevin Veen-Birkenbach Date: Tue, 21 Oct 2025 13:44:11 +0200 Subject: [PATCH] feat(nextcloud): enable custom Alpine-based Whiteboard image with Chromium & ffmpeg support - Added role tasks to deploy templated Dockerfile for Whiteboard service - Configured build context and custom image name (nextcloud_whiteboard_custom) - Increased PID limits and shm_size for stable recording - Adjusted user ID variable naming consistency - Integrated path_join for service directory variables - Fixed build permissions (install as root, revert to nobody) Reference: ChatGPT conversation https://chatgpt.com/share/68f771c6-0e98-800f-99ca-9e367f4cd0c2 --- roles/web-app-nextcloud/config/main.yml | 4 +-- .../web-app-nextcloud/tasks/01_fullstack.yml | 19 +++++++++++-- .../templates/Dockerfiles/Whiteboard.j2 | 27 +++++++++++++++++++ .../templates/docker-compose.yml.j2 | 7 ++++- roles/web-app-nextcloud/templates/env.j2 | 2 -- roles/web-app-nextcloud/vars/main.yml | 5 +++- 6 files changed, 56 insertions(+), 8 deletions(-) create mode 100644 roles/web-app-nextcloud/templates/Dockerfiles/Whiteboard.j2 diff --git a/roles/web-app-nextcloud/config/main.yml b/roles/web-app-nextcloud/config/main.yml index d5a4af3e..7a482575 100644 --- a/roles/web-app-nextcloud/config/main.yml +++ b/roles/web-app-nextcloud/config/main.yml @@ -82,7 +82,7 @@ docker: cpus: "1.0" mem_reservation: "256m" mem_limit: "1g" - pids_limit: 512 + pids_limit: 1024 whiteboard: name: "nextcloud-whiteboard" image: "ghcr.io/nextcloud-releases/whiteboard" @@ -92,7 +92,7 @@ docker: cpus: "0.25" mem_reservation: "128m" mem_limit: "512m" - pids_limit: 256 + pids_limit: 1024 enabled: "{{ applications | get_app_conf('web-app-nextcloud', 'features.oidc', False, True, True) }}" # Activate OIDC for Nextcloud # floavor decides which OICD plugin should be used. # Available options: oidc_login, sociallogin diff --git a/roles/web-app-nextcloud/tasks/01_fullstack.yml b/roles/web-app-nextcloud/tasks/01_fullstack.yml index a97f76f1..d3d251d3 100644 --- a/roles/web-app-nextcloud/tasks/01_fullstack.yml +++ b/roles/web-app-nextcloud/tasks/01_fullstack.yml @@ -14,6 +14,21 @@ vars: docker_compose_flush_handlers: false +- block: + - name: "Create '{{ NEXTCLOUD_WHITEBOARD_SERVICE_DIRECTORY }}' Directory" + file: + path: "{{ NEXTCLOUD_WHITEBOARD_SERVICE_DIRECTORY }}" + state: directory + mode: "0755" + + - name: "Deploy Whiteboard Dockerfile to '{{ NEXTCLOUD_WHITEBOARD_SERVICE_DOCKERFILE }}'" + template: + src: "Dockerfiles/Whiteboard.j2" + dest: "{{ NEXTCLOUD_WHITEBOARD_SERVICE_DOCKERFILE }}" + notify: docker compose build + + when: NEXTCLOUD_WHITEBOARD_ENABLED | bool + - name: "create {{ NEXTCLOUD_HOST_CONF_ADD_PATH }}" file: path: "{{ NEXTCLOUD_HOST_CONF_ADD_PATH }}" @@ -24,8 +39,8 @@ template: src: "{{ item }}" dest: "{{ NEXTCLOUD_HOST_CONF_ADD_PATH }}/{{ item | basename | regex_replace('\\.j2$', '') }}" - owner: "{{ NEXTCLOUD_DOCKER_USER_id }}" - group: "{{ NEXTCLOUD_DOCKER_USER_id }}" + owner: "{{ NEXTCLOUD_DOCKER_USER_ID }}" + group: "{{ NEXTCLOUD_DOCKER_USER_ID }}" loop: "{{ lookup('fileglob', role_path ~ '/templates/config/*.j2', wantlist=True) }}" notify: docker compose up diff --git a/roles/web-app-nextcloud/templates/Dockerfiles/Whiteboard.j2 b/roles/web-app-nextcloud/templates/Dockerfiles/Whiteboard.j2 new file mode 100644 index 00000000..0341980b --- /dev/null +++ b/roles/web-app-nextcloud/templates/Dockerfiles/Whiteboard.j2 @@ -0,0 +1,27 @@ +FROM {{ NEXTCLOUD_WHITEBOARD_IMAGE }}:{{ NEXTCLOUD_WHITEBOARD_VERSION }} + +# Temporarily switch to root so we can install packages +USER 0 + +# Install Chromium, ffmpeg, fonts, and runtime libraries for headless operation on Alpine +RUN apk add --no-cache \ + chromium \ + ffmpeg \ + nss \ + freetype \ + harfbuzz \ + ttf-dejavu \ + ttf-liberation \ + udev \ + ca-certificates \ + && update-ca-certificates + +# Ensure a consistent Chromium binary path +RUN if [ -x /usr/bin/chromium-browser ]; then ln -sf /usr/bin/chromium-browser /usr/bin/chromium; fi + +# Environment variables used by Puppeteer +ENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium \ + PUPPETEER_SKIP_DOWNLOAD=true + +# Switch back to the original non-root user (nobody) +USER 65534 diff --git a/roles/web-app-nextcloud/templates/docker-compose.yml.j2 b/roles/web-app-nextcloud/templates/docker-compose.yml.j2 index ef0f5d2b..18065d72 100644 --- a/roles/web-app-nextcloud/templates/docker-compose.yml.j2 +++ b/roles/web-app-nextcloud/templates/docker-compose.yml.j2 @@ -67,8 +67,12 @@ {{ service_name }}: {% set container_port = NEXTCLOUD_WHITEBOARD_PORT_INTERNAL %} {% include 'roles/docker-container/templates/base.yml.j2' %} + build: + context: . + dockerfile: {{ NEXTCLOUD_WHITEBOARD_SERVICE_DOCKERFILE }} + pull_policy: never {% include 'roles/docker-container/templates/healthcheck/nc.yml.j2' %} - image: "{{ NEXTCLOUD_WHITEBOARD_IMAGE }}:{{ NEXTCLOUD_WHITEBOARD_VERSION }}" + image: "{{ NEXTCLOUD_WHITEBOARD_CUSTOM_IMAGE }}" container_name: {{ NEXTCLOUD_WHITEBOARD_CONTAINER }} volumes: - whiteboard_tmp:/tmp @@ -76,6 +80,7 @@ expose: - "{{ container_port }}" + shm_size: 1g networks: default: ipv4_address: 192.168.102.71 diff --git a/roles/web-app-nextcloud/templates/env.j2 b/roles/web-app-nextcloud/templates/env.j2 index 96033d70..993d4a0a 100644 --- a/roles/web-app-nextcloud/templates/env.j2 +++ b/roles/web-app-nextcloud/templates/env.j2 @@ -65,6 +65,4 @@ CHROMIUM_FLAGS=--headless=new --no-sandbox --disable-gpu --disable-dev-shm-usage # Falls das Image Chromium mitbringt – Pfad meistens /usr/bin/chromium oder /usr/bin/chromium-browser: PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium PUPPETEER_SKIP_DOWNLOAD=true -# Deactivated @todo implement -WHITEBOARD_ENABLE_RECORDING=false {% endif %} \ No newline at end of file diff --git a/roles/web-app-nextcloud/vars/main.yml b/roles/web-app-nextcloud/vars/main.yml index f7c843af..334556bb 100644 --- a/roles/web-app-nextcloud/vars/main.yml +++ b/roles/web-app-nextcloud/vars/main.yml @@ -120,6 +120,7 @@ NEXTCLOUD_WHITEBOARD_SERVICE: "whiteboard" NEXTCLOUD_WHITEBOARD_CONTAINER: "{{ applications | get_app_conf(application_id, 'docker.services.' ~ NEXTCLOUD_WHITEBOARD_SERVICE ~'.name') }}" NEXTCLOUD_WHITEBOARD_IMAGE: "{{ applications | get_app_conf(application_id, 'docker.services.' ~ NEXTCLOUD_WHITEBOARD_SERVICE ~'.image') }}" NEXTCLOUD_WHITEBOARD_VERSION: "{{ applications | get_app_conf(application_id, 'docker.services.' ~ NEXTCLOUD_WHITEBOARD_SERVICE ~'.version') }}" +NEXTCLOUD_WHITEBOARD_CUSTOM_IMAGE: "nextcloud_whiteboard_custom" NEXTCLOUD_WHITEBOARD_ENABLED: "{{ applications | get_app_conf(application_id, 'plugins.' ~ NEXTCLOUD_WHITEBOARD_SERVICE ~'.enabled') }}" NEXTCLOUD_WHITEBOARD_PORT_INTERNAL: "3002" NEXTCLOUD_WHITEBOARD_JWT: "{{ applications | get_app_conf(application_id, 'credentials.' ~ NEXTCLOUD_WHITEBOARD_SERVICE ~'_jwt_secret') }}" @@ -127,12 +128,14 @@ NEXTCLOUD_WHITEBOARD_LOCATION: "/whiteboard/" NEXTCLOUD_WHITEBOARD_URL: "{{ [ NEXTCLOUD_URL, NEXTCLOUD_WHITEBOARD_LOCATION ] | url_join }}" NEXTCLOUD_WHITEBOARD_TMP_VOLUME: "{{ applications | get_app_conf(application_id, 'docker.volumes.whiteboard_tmp') }}" NEXTCLOUD_WHITEBOARD_FRONTCACHE_VOLUME: "{{ applications | get_app_conf(application_id, 'docker.volumes.whiteboard_fontcache') }}" +NEXTCLOUD_WHITEBOARD_SERVICE_DIRECTORY: "{{ [ docker_compose.directories.services, 'whiteboard' ] | path_join }}" +NEXTCLOUD_WHITEBOARD_SERVICE_DOCKERFILE: "{{ [ NEXTCLOUD_WHITEBOARD_SERVICE_DIRECTORY, 'Dockerfile' ] | path_join }}" ### Collabora NEXTCLOUD_COLLABORA_URL: "{{ domains | get_url('web-svc-collabora', WEB_PROTOCOL) }}" ## User Configuration -NEXTCLOUD_DOCKER_USER_id: 82 # UID of the www-data user +NEXTCLOUD_DOCKER_USER_ID: 82 # UID of the www-data user NEXTCLOUD_DOCKER_USER: "www-data" # Name of the www-data user (Set here to easy change it in the future) ## Execution