So I decide install a new Open Project instance server for the new production.
Update (September 2026): This server now runs OpenProject 17.9 with Node.js 24. The Hocuspocus section below documents the working collaborative document editing setup. The original v16 installation notes, including the Ruby setup, remain as historical context; use the Ruby version specified by the deployed release's .ruby-version.
Disable SELinux
Disable SELinux
vi /etc/selinux/config
grubby --update-kernel ALL --args selinux=0
Install htop and atop
Install htop and atop
sudodnfupdate
sudodnfinstallepel-release
sudodnfinstallhtop
sudodnfinstallatop
Install nginx
Install nginx
sudodnfinstallnginx
Install Node.js 24
Using the NodeSource distribution. For this OpenProject 17.9 deployment, use Node.js 24, version 24.15.0 or later within the 24.x series.
sudojournalctl-upuma_plm# check system log and fix errors
sudosystemctlstartpuma_plm
Configure Hocuspocus for OpenProject 17.9
OpenProject uses Hocuspocus for real-time collaborative editing in the Documents module. The server source is bundled in extensions/op-blocknote-hocuspocus in the deployed OpenProject release. Use that copy so it stays aligned with the application version.
The working PPP setup uses this connection path:
Collaborative editing connection
Browser -> wss://plm-ppp.thape.com.cn/hocuspocus (Nginx, port 443)
-> ws://127.0.0.1:1234 (Hocuspocus)
Install the Hocuspocus dependencies
Run as open_project, using Node.js 24. Install the pnpm version specified by packageManager in the deployed extension's package.json, then install its production dependencies:
Node must also be available to systemd through /usr/local/bin:/usr/bin:/bin. If using a version manager, adjust the service's PATH to include the installed Node.js 24 binary directory.
Configure the shared environment
Add these entries to /var/www/open_project/shared/.env. Replace the placeholder with a secret generated using openssl rand -hex 32:
Keep this file readable only by the deployment account and root. The explicit enablement setting also overrides a previously saved disabled setting.
Puma and GoodJob must load this file after /etc/environment:
Environment files in the application service units
EnvironmentFile=/etc/environment
EnvironmentFile=/var/www/open_project/shared/.env
The earlier puma_plm.service example only loads /etc/environment, so add the second line when following that example. The PPP deployment uses puma_ppp.service; substitute the actual service name in the commands below if yours differs.
Hocuspocus expects SECRET, so the service maps the OpenProject secret variable to that name. Keep the double dollar sign in ExecStart: systemd passes a literal dollar sign to the shell for expansion.
Add this location inside the existing HTTPS server block for plm-ppp.thape.com.cn. This assumes Nginx and Hocuspocus run on the same host and the HTTPS virtual host already has a valid certificate.
Restart the existing GoodJob service in its configured system or user service scope as well, so it reloads the shared environment. Keep direct external access to port 1234 blocked; browsers connect through HTTPS port 443. Hocuspocus must also be able to reach OpenProject's public URL to authenticate users and save document content.
Verify collaboration and troubleshoot
Check Administration -> Documents to confirm collaboration is enabled.
Create a new document under Project -> Documents and open it as two users. Confirm live edits and cursors, then close and reopen it to verify persistence.
In the browser's developer tools, check Network -> WS. The connection should use wss://plm-ppp.thape.com.cn/hocuspocus and return 101 Switching Protocols.
Existing documents with kind: classic continue using CKEditor. Enabling collaboration does not convert their content, and this feature does not replace CKEditor in work package fields.
An HTTPS page cannot connect to ws:// because browsers block mixed content. Merely changing the URL to wss://plm-ppp.thape.com.cn:1234 does not enable TLS on Hocuspocus. Use the Nginx endpoint on port 443 shown above.
If the browser still attempts the old ws:// URL, restart Puma and hard-refresh the document page. Restarting Hocuspocus alone does not change the URL Rails renders. Inspect the rendered setting in the browser console: