From 832f232972c65e7ebed62000aefe825cf8d8ff38 Mon Sep 17 00:00:00 2001 From: Joe Carstairs Date: Thu, 6 Aug 2026 10:45:03 +0100 Subject: ansible-ise etherpad --- ansible/playbook.yml | 9 ++ ansible/roles/etherpad/tasks/main.yml | 65 +++++++++++ ansible/roles/etherpad/templates/openrc/etherpad | 36 ++++++ ansible/roles/etherpad/templates/settings.json | 134 +++++++++++++++++++++++ ansible/vars/etherpad.yml | 9 ++ etherpad.Dockerfile | 11 -- etherpad/.gitignore | 2 - etherpad/Makefile | 27 ----- etherpad/install.mk | 13 --- etherpad/settings.json.template | 134 ----------------------- make/vars.mk | 5 - 11 files changed, 253 insertions(+), 192 deletions(-) create mode 100644 ansible/roles/etherpad/tasks/main.yml create mode 100644 ansible/roles/etherpad/templates/openrc/etherpad create mode 100644 ansible/roles/etherpad/templates/settings.json create mode 100644 ansible/vars/etherpad.yml delete mode 100644 etherpad.Dockerfile delete mode 100644 etherpad/.gitignore delete mode 100644 etherpad/Makefile delete mode 100644 etherpad/install.mk delete mode 100644 etherpad/settings.json.template diff --git a/ansible/playbook.yml b/ansible/playbook.yml index 4320e8f..c0b5abc 100644 --- a/ansible/playbook.yml +++ b/ansible/playbook.yml @@ -17,3 +17,12 @@ - ln vars_files: - common.yml + +- name: Install etherpad + hosts: "{{ services.etherpad.host }}" + become: true + roles: + - etherpad + vars_files: + - common.yml + - etherpad.yml diff --git a/ansible/roles/etherpad/tasks/main.yml b/ansible/roles/etherpad/tasks/main.yml new file mode 100644 index 0000000..8709049 --- /dev/null +++ b/ansible/roles/etherpad/tasks/main.yml @@ -0,0 +1,65 @@ +- name: Install PNPM and Git + community.general.apk: + name: + - pnpm + - git + +- name: Install tsx globally + ansible.builtin.shell: pnpm install --global tsx + register: pnpm_install_tsx + changed_when: "'Already up to date' not in pnpm_install_tsx.stdout" + environment: + PNPM_HOME: "{{ ansible_facts.env.HOME }}/.local/share/pnpm" + PATH: "{{ ansible_facts.env.PATH }}:{{ ansible_facts.env.HOME }}/.local/share/pnpm" + +- name: Checkout source code for latest etherpad release + register: etherpad_src + ansible.builtin.git: + repo: https://github.com/ether/etherpad.git + dest: "{{ etherpad_src_dir }}" + depth: 1 + version: master + +- name: Install etherpad settings + register: etherpad_settings + ansible.builtin.template: + src: settings.json + dest: "{{ etherpad_src_dir }}/settings.json" + mode: "640" + +- name: Install etherpad dependencies + register: etherpad_dependencies + changed_when: "'Already up to date' not in etherpad_dependencies.stdout" + ansible.builtin.command: + chdir: "{{ etherpad_src_dir }}" + cmd: pnpm install + +- name: Install etherpad service + register: etherpad_service + ansible.builtin.template: + src: openrc/etherpad + dest: /etc/init.d/etherpad + mode: "755" + +- name: Restart etherpad service and configure to start on boot + when: + etherpad_src is changed + or etherpad_service is changed + or etherpad_settings is changed + or etherpad_dependencies is changed + ansible.builtin.service: + name: etherpad + enabled: true + state: restarted + +- name: Start etherpad service and configure to start on boot + when: + not ( + etherpad_src is changed + or etherpad_settings is changed + or etherpad_service is changed + or etherpad_dependencies is changed ) + ansible.builtin.service: + name: etherpad + enabled: true + state: started diff --git a/ansible/roles/etherpad/templates/openrc/etherpad b/ansible/roles/etherpad/templates/openrc/etherpad new file mode 100644 index 0000000..5c31e4b --- /dev/null +++ b/ansible/roles/etherpad/templates/openrc/etherpad @@ -0,0 +1,36 @@ +#!/sbin/openrc-run + +description="Run etherpad document server" + +start() +{ + ebegin "Starting etherpad" + start-stop-daemon --start \ + --env NODE_ENV={{ etherpad_node_env }} \ + --exec /usr/bin/pnpx \ + --background \ + --chdir {{ etherpad_src_dir }} \ + --stdout /var/log/etherpad.log \ + --stderr /var/log/etherpad.log \ + --make-pidfile \ + --pidfile /run/etherpad.pid \ + -- tsx src/node/server.ts + eend $? +} + +stop() +{ + ebegin "Stopping etherpad" + start-stop-daemon --stop \ + --exec /usr/bin/pnpx \ + --pidfile /run/etherpad.pid + eend $? +} + +restart() +{ + ebegin "Restarting etherpad" + svc_stop + svc_start + eend $? +} diff --git a/ansible/roles/etherpad/templates/settings.json b/ansible/roles/etherpad/templates/settings.json new file mode 100644 index 0000000..7818d93 --- /dev/null +++ b/ansible/roles/etherpad/templates/settings.json @@ -0,0 +1,134 @@ +{ + "title": "joeac's docs", + "showRecentPads": true, + "favicon": null, + "skinName": "colibris", + "skinVariants": "super-light-toolbar super-light-editor light-background", + "ip": "0.0.0.0", + "port": {{ services.etherpad.port }}, + "showSettingsInAdminPage": true, + "enableMetrics": "${ENABLE_METRICS:true}", + "cleanup": { + "enabled": false, + "keepRevisions": 5 + }, + "dbType": "sqlite", + "dbSettings": { + "filename": "var/sqlite.db" + }, + "defaultPadText" : "", + "padOptions": { + "noColors": false, + "showControls": true, + "showChat": true, + "showLineNumbers": true, + "useMonospaceFont": false, + "userName": null, + "userColor": null, + "rtl": false, + "alwaysShowChat": false, + "chatAndUsers": false, + "lang": null + }, + "padShortcutEnabled" : { + "altF9": true, + "altC": true, + "cmdShift2": true, + "delete": true, + "return": true, + "esc": true, + "cmdS": true, + "tab": true, + "cmdZ": true, + "cmdY": true, + "cmdI": true, + "cmdB": true, + "cmdU": true, + "cmd5": true, + "cmdShiftL": true, + "cmdShiftN": true, + "cmdShift1": true, + "cmdShiftC": true, + "cmdH": true, + "ctrlHome": true, + "pageUp": true, + "pageDown": true + }, + "updateServer": "https://etherpad.org/ep_infos", + "suppressErrorsInPadText": false, + "requireSession": false, + "editOnly": false, + "minify": true, + "maxAge": 21600, + "soffice": null, + "docxExport": true, + "allowUnknownFileEnds": true, + "requireAuthentication": false, + "requireAuthorization": false, + "trustProxy": false, + "cookie": { + "keyRotationInterval": 86400000, + "sameSite": "Lax", + "sessionLifetime": 864000000, + "sessionRefreshInterval": 86400000, + "sessionCleanup": true + }, + "disableIPlogging": false, + "automaticReconnectionTimeout": 0, + "scrollWhenFocusLineIsOutOfViewport": { + "percentage": { + "editionAboveViewport": 0, + "editionBelowViewport": 0 + }, + "duration": 0, + "scrollWhenCaretIsInTheLastLineOfViewport": false, + "percentageToScrollWhenUserPressesArrowUp": 0 + }, + "users": { + "admin": { + "password": "{{ etherpad_admin_password }}", + "is_admin": true + } + }, + "socketTransportProtocols" : ["websocket", "polling"], + "socketIo": { + "maxHttpBufferSize": 1000000 + }, + "loadTest": false, + "dumpOnUncleanExit": false, + "importExportRateLimiting": { + "windowMs": 90000, + "max": 10 + }, + "importMaxFileSize": 52428800, // 50 * 1024 * 1024 + "authenticationMethod": "${AUTHENTICATION_METHOD:sso}", + "enableDarkMode": "${ENABLE_DARK_MODE:true}", + "enablePadWideSettings": "${ENABLE_PAD_WIDE_SETTINGS:false}", + "commitRateLimiting": { + "duration": 1, + "points": 10 + }, + "logLayoutType": "colored", + "customLocaleStrings": {}, + "enableAdminUITests": false, + "lowerCasePadIds": false, + "sso": { + "issuer": "${SSO_ISSUER:http://localhost:{{ services.etherpad.port }}}", + "clients": [ + { + "client_id": "${ADMIN_CLIENT:admin_client}", + "client_secret": "${ADMIN_SECRET:admin}", + "grant_types": ["authorization_code"], + "response_types": ["code"], + "redirect_uris": ["${ADMIN_REDIRECT:http://localhost:{{ services.etherpad.port }}/admin/}"] + }, + { + "client_id": "${USER_CLIENT:user_client}", + "client_secret": "${USER_SECRET:user}", + "grant_types": ["authorization_code"], + "response_types": ["code"], + "redirect_uris": ["${USER_REDIRECT:http://localhost:{{ services.etherpad.port }}/}"] + } + ] + } +} diff --git a/ansible/vars/etherpad.yml b/ansible/vars/etherpad.yml new file mode 100644 index 0000000..1c14232 --- /dev/null +++ b/ansible/vars/etherpad.yml @@ -0,0 +1,9 @@ +etherpad_src_dir: /usr/local/lib/etherpad +etherpad_node_env: production +etherpad_admin_password: !vault | + $ANSIBLE_VAULT;1.2;AES256;ansible + 61323133386365613235326230313139396433653533613638353163336561363930326463366638 + 6264633965363664333862666536636537383331326637630a643336646561643133613863386561 + 33613830613461653432383534356533643938383063326363633833653939356232363836336565 + 3961383965323537650a666430646338363637383233633531313735353931386433323337313133 + 30663632646631396335333263336132616234663539623766366364626633313831 diff --git a/etherpad.Dockerfile b/etherpad.Dockerfile deleted file mode 100644 index fd76a88..0000000 --- a/etherpad.Dockerfile +++ /dev/null @@ -1,11 +0,0 @@ -ARG ALPINE_VERSION=3.23 -FROM docker.io/alpine:${ALPINE_VERSION} -RUN mkdir -p /var/app -WORKDIR /var/app -ARG ETHERPAD_VERSION -RUN apk --no-cache add pnpm \ - && ENV=~/.profile SHELL=sh pnpm setup \ - && source ~/.profile \ - && pnpm install --global tsx -COPY etherpad/etherpad-${ETHERPAD_VERSION} . -CMD pnpx tsx src/node/server.ts diff --git a/etherpad/.gitignore b/etherpad/.gitignore deleted file mode 100644 index 455789d..0000000 --- a/etherpad/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -var -etherpad-* diff --git a/etherpad/Makefile b/etherpad/Makefile deleted file mode 100644 index aa010d5..0000000 --- a/etherpad/Makefile +++ /dev/null @@ -1,27 +0,0 @@ -ETHERPAD_VERSION := 3.3.2 -SRC_DIR := etherpad-$(ETHERPAD_VERSION) - -.PHONY: all -all: download_etherpad install_deps - -.PHONY: download_etherpad -download_etherpad: $(SRC_DIR) - -$(SRC_DIR): - wget -O- https://github.com/ether/etherpad/archive/refs/tags/v3.3.2.tar.gz | tar -xz - -.PHONY: install_deps -install_deps: $(SRC_DIR)/node_modules - -$(SRC_DIR)/node_modules: $(SRC_DIR) $(SRC_DIR)/settings.json $(SRC_DIR)/package.json $(SRC_DIR)/pnpm-lock.yaml - cd $(SRC_DIR) && pnpm install - -$(SRC_DIR)/settings.json: $(SRC_DIR) settings.json.template -ifdef ETHERPAD_PORT - ETHERPAD_PORT=$(ETHERPAD_PORT) envsubst -no-unset -i settings.json.template -o $(SRC_DIR)/settings.json -else - $(error ETHERPAD_PORT is not defined) -endif - -clean: - rm -rf etherpad-*/ diff --git a/etherpad/install.mk b/etherpad/install.mk deleted file mode 100644 index 17d9bbf..0000000 --- a/etherpad/install.mk +++ /dev/null @@ -1,13 +0,0 @@ -.PHONY: install -install: $(ETHERPAD_DATA_DIR) - -.PHONY: reinstall -reinstall: $(ETHERPAD_DATA_DIR) - -$(ETHERPAD_DATA_DIR): - sudo mkdir -p $(ETHERPAD_DATA_DIR) - ETHERPAD_USER=$(whoami) && sudo chown $$ETHERPAD_USER:$$ETHERPAD_USER $(ETHERPAD_DATA_DIR) - -.PHONY: uninstall -uninstall: - $(info Nothing to do) diff --git a/etherpad/settings.json.template b/etherpad/settings.json.template deleted file mode 100644 index 09cf5c7..0000000 --- a/etherpad/settings.json.template +++ /dev/null @@ -1,134 +0,0 @@ -{ - "title": "joeac's docs", - "showRecentPads": true, - "favicon": null, - "skinName": "colibris", - "skinVariants": "super-light-toolbar super-light-editor light-background", - "ip": "0.0.0.0", - "port": ${ETHERPAD_PORT}, - "showSettingsInAdminPage": true, - "enableMetrics": "$${ENABLE_METRICS:true}", - "cleanup": { - "enabled": false, - "keepRevisions": 5 - }, - "dbType": "sqlite", - "dbSettings": { - "filename": "var/etherpad.sq3" - }, - "defaultPadText" : "", - "padOptions": { - "noColors": false, - "showControls": true, - "showChat": true, - "showLineNumbers": true, - "useMonospaceFont": false, - "userName": null, - "userColor": null, - "rtl": false, - "alwaysShowChat": false, - "chatAndUsers": false, - "lang": null - }, - "padShortcutEnabled" : { - "altF9": true, - "altC": true, - "cmdShift2": true, - "delete": true, - "return": true, - "esc": true, - "cmdS": true, - "tab": true, - "cmdZ": true, - "cmdY": true, - "cmdI": true, - "cmdB": true, - "cmdU": true, - "cmd5": true, - "cmdShiftL": true, - "cmdShiftN": true, - "cmdShift1": true, - "cmdShiftC": true, - "cmdH": true, - "ctrlHome": true, - "pageUp": true, - "pageDown": true - }, - "updateServer": "https://etherpad.org/ep_infos", - "suppressErrorsInPadText": false, - "requireSession": false, - "editOnly": false, - "minify": true, - "maxAge": 21600, - "soffice": null, - "docxExport": true, - "allowUnknownFileEnds": true, - "requireAuthentication": false, - "requireAuthorization": false, - "trustProxy": false, - "cookie": { - "keyRotationInterval": 86400000, - "sameSite": "Lax", - "sessionLifetime": 864000000, - "sessionRefreshInterval": 86400000, - "sessionCleanup": true - }, - "disableIPlogging": false, - "automaticReconnectionTimeout": 0, - "scrollWhenFocusLineIsOutOfViewport": { - "percentage": { - "editionAboveViewport": 0, - "editionBelowViewport": 0 - }, - "duration": 0, - "scrollWhenCaretIsInTheLastLineOfViewport": false, - "percentageToScrollWhenUserPressesArrowUp": 0 - }, - "users": { - "admin": { - "password": "admin", - "is_admin": true - } - }, - "socketTransportProtocols" : ["websocket", "polling"], - "socketIo": { - "maxHttpBufferSize": 1000000 - }, - "loadTest": false, - "dumpOnUncleanExit": false, - "importExportRateLimiting": { - "windowMs": 90000, - "max": 10 - }, - "importMaxFileSize": 52428800, // 50 * 1024 * 1024 - "authenticationMethod": "$${AUTHENTICATION_METHOD:sso}", - "enableDarkMode": "$${ENABLE_DARK_MODE:true}", - "enablePadWideSettings": "$${ENABLE_PAD_WIDE_SETTINGS:false}", - "commitRateLimiting": { - "duration": 1, - "points": 10 - }, - "logLayoutType": "colored", - "customLocaleStrings": {}, - "enableAdminUITests": false, - "lowerCasePadIds": false, - "sso": { - "issuer": "$${SSO_ISSUER:http://localhost:${ETHERPAD_PORT}}", - "clients": [ - { - "client_id": "$${ADMIN_CLIENT:admin_client}", - "client_secret": "$${ADMIN_SECRET:admin}", - "grant_types": ["authorization_code"], - "response_types": ["code"], - "redirect_uris": ["$${ADMIN_REDIRECT:http://localhost:${ETHERPAD_PORT}/admin/}"] - }, - { - "client_id": "$${USER_CLIENT:user_client}", - "client_secret": "$${USER_SECRET:user}", - "grant_types": ["authorization_code"], - "response_types": ["code"], - "redirect_uris": ["$${USER_REDIRECT:http://localhost:${ETHERPAD_PORT}/}"] - } - ] - } -} diff --git a/make/vars.mk b/make/vars.mk index 8daf287..1eb3d93 100644 --- a/make/vars.mk +++ b/make/vars.mk @@ -24,20 +24,17 @@ SUBDOMAIN_vaultwarden := pwd SUBDOMAIN_etherpad := docs PORT_actualbudget := 5006 -PORT_etherpad := 9001 PORT_http := 8080 PORT_gemini := 1965 PORT_smtp := 2500 PORT_vaultwarden := 9000 export ACTUALBUDGET_DATA_DIR := /var/joeac.net-actualbudget/var -export ETHERPAD_DATA_DIR := /var/etherpad/var export GEMINI_CERTIFICATES_DIR := /var/joeac.net-gemini/certificates export GEMINI_COMITIUM_DATA_DIR := /var/joeac.net-gemini/comitium-data export VAULTWARDEN_DATA_DIR := /var/vaultwarden/data ALPINE_VERSION := 3.23 -ETHERPAD_VERSION := 3.3.2 $(foreach module,$(ALL_MODULES),$(if $(PORT_$(module)),$(eval \ export $(call capitalise,$(module))_PORT := $(PORT_$(module))))) @@ -65,8 +62,6 @@ COMPOSE_CMD := \ IMAGE_PREFIX="$(IMAGE_PREFIX)" \ GEMINI_CERTIFICATES_DIR="$(GEMINI_CERTIFICATES_DIR)" \ GEMINI_COMITIUM_DATA_DIR="$(GEMINI_COMITIUM_DATA_DIR)" \ - ETHERPAD_DATA_DIR="$(ETHERPAD_DATA_DIR)" \ - ETHERPAD_VERSION="$(ETHERPAD_VERSION)" \ VAULTWARDEN_DATA_DIR="$(VAULTWARDEN_DATA_DIR)" \ LOCAL_SMTP_PORT=$(PORT_smtp) \ $(foreach module,$(ALL_MODULES),$(call capitalise,$(module))_PORT=$(PORT_$(module))) \ -- cgit v1.2.3