Skip to content

OnlyOffice Integration — Operator Guide

Audience: Cesivi administrators who want to enable in-browser document editing. For the developer design doc, see _docs_dev/onlyoffice-integration.md. For Docker scaffolding, see _docs_dev/onlyoffice-docker-setup.md.

Spec: wopi.readthedocs.io · api.onlyoffice.com/editors · github.com/ONLYOFFICE/Docker-DocumentServer#readme


What this enables

When OnlyOffice is active, users can edit documents directly in their browser without downloading. Supported operations depend on the file type:

Category Extensions
Editable (full) .docx, .xlsx, .pptx, .odt, .ods, .odp, .txt, .csv
View-only .pdf (annotations and form-fill)
View with conversion to edit .doc, .xls, .ppt, .rtf (user confirms; original preserved)

A Cesivi document library gains an "Edit in browser" entry in every file's context menu (ECB action). The editor opens in an iframe embedded on a Cesivi page. All saves write directly back to the Cesivi file store; the user never downloads or re-uploads the file.

This integration uses the WOPI protocol, which is the same protocol used by Microsoft Office Online. OnlyOffice acts as the WOPI client; Cesivi acts as the WOPI host. The 20-connection Community Edition cap applies (see below).


Prerequisites

Before enabling, confirm:

  • Docker Desktop or Docker CE is installed and docker compose version succeeds.
  • Host port 8082 is free (this is the registered port for the main worktree — see "Per-worktree port isolation" if you need a different port).
  • At least 2 GB free disk for the initial image pull.
  • At least 4 GB additional RAM headroom for the Document Server container (Community Edition uses a bundled Postgres, RabbitMQ, and Redis).
  • The Cesivi server and the Document Server container can reach each other over the network. In a standard Docker Desktop / Windows dev setup this works out of the box via host.docker.internal.

Enabling the integration

The integration is enabled by default (OnlyOffice:Enabled defaults to true). You just need to start the container and wire up the JWT secret.

Step 1 — Start the container:

bash Scripts/onlyoffice.sh up
# Windows PowerShell:
.\Scripts\onlyoffice.ps1 up

On first run, the script copies .env.example to .env, generates a JWT secret, and starts the container. It polls /healthcheck for up to 120 seconds. "Healthy" response body is true.

Step 2 — Retrieve the JWT secret:

bash Scripts/onlyoffice.sh jwt

This prints the 64-character hex secret stored in docker/onlyoffice/.env.

Step 3 — Configure Cesivi:

Put the secret into Cesivi's appsettings.Production.json (or set the environment variable OnlyOffice__JwtSecret):

{
  "OnlyOffice": {
    "Enabled": true,
    "BaseUrl": "http://localhost:8082",
    "JwtSecret": "<paste-64-hex-chars-here>"
  }
}

Never commit appsettings.Production.json if it contains the secret. Store it via your secret management solution (environment variables, Docker secrets, Kubernetes secrets, etc.).

Step 4 — Restart Cesivi.Server:

# Systemd example:
sudo systemctl restart cesivi-server
# Docker example:
docker restart cesivi-server

Both sides (Document Server and Cesivi) must run with the same JWT secret. If they differ, the editor page loads but operations fail with 403 from the Document Server callback to Cesivi.


Verification

After setup, verify the integration end to end.

Container health:

curl -fsS http://localhost:8082/healthcheck && echo
# → true

WOPI discovery (should list supported file types):

curl -s http://localhost:8082/hosting/discovery | head -20
# → XML starting with <wopi-discovery>

Cesivi capability endpoint:

# Replace 5010 with your Cesivi server port
curl -s http://localhost:5010/_api/onlyoffice/supported-types
# → {"editable":["docx","xlsx","pptx",...],"viewOnly":["pdf"],"convertible":["doc","xls","ppt"]}

If the capability endpoint returns {"editable":[],"viewOnly":[],"convertible":[]} the integration is either disabled or the discovery service has not yet fetched the XML. Check the Cesivi log for WopiDiscoveryService lines.

Browser verification:

  1. Open any Document Library in the Cesivi Web UI.
  2. Click the context menu (three dots or right-click) on a .docx file.
  3. "Edit in browser" should appear.
  4. Click it — the OnlyOffice editor should open inside the page.

Disabling (kill switch)

Set OnlyOffice:Enabled to false in appsettings.json (or the production config) and restart Cesivi.Server:

{
  "OnlyOffice": {
    "Enabled": false
  }
}

Effect when disabled: - All WOPI routes (/wopi/files/…) return HTTP 404. - /_api/onlyoffice/open returns HTTP 404. - /_api/onlyoffice/supported-types returns empty lists, which causes the WebUI to hide the "Edit in browser" menu and ribbon button. - WopiDiscoveryService logs once ("OnlyOffice integration disabled via config; discovery refresh skipped.") and exits its polling loop. - WopiLockCleanupService similarly skips all lock sweeping.

The Document Server container can keep running; Cesivi just ignores it. To also stop the container: bash Scripts/onlyoffice.sh down.


JWT secret rotation

Both sides must be updated simultaneously; a mismatch causes all editor operations to fail with 403.

  1. Stop the Document Server container:
    bash Scripts/onlyoffice.sh down
    
  2. Edit docker/onlyoffice/.env — replace JWT_SECRET with a new value:
    openssl rand -hex 32
    
  3. Update the same secret in Cesivi's config (appsettings.Production.json or environment variable OnlyOffice__JwtSecret).
  4. Restart both services:
    bash Scripts/onlyoffice.sh up
    sudo systemctl restart cesivi-server   # or docker restart cesivi-server
    

Any active editing sessions at rotation time will receive a 403 on the next autosave callback. The user will see an error card in the editor. They can download the current version (Document Server has a local copy) and re-upload, or re-open the file after the rotation.

Rotation window: Aim for off-peak hours. Active sessions cannot survive the secret change gracefully.


20-connection Community cap

OnlyOffice Community Edition limits concurrent editing sessions to 20 simultaneous open editors. This is a hard limit from OnlyOffice; Cesivi cannot extend it.

Detecting the cap being hit: When the limit is reached, OnlyOffice returns HTTP 503 or an error payload to the iframe. The Cesivi "Edit in browser" page renders an error card instead of the editor with the text from OnlyOffice. In the Cesivi log, WopiDiscoveryService does not report the cap — only the editor page itself shows the error.

User impact: More than 20 simultaneous open editors (not just tabs, but active document connections) results in new edit attempts failing. Users can still download and edit locally. The Cesivi "Edit in browser" action is not disabled — the error manifests inside the already-open editor frame.

Workaround (Community): Instruct users to close editor tabs when done rather than leaving them open. Each editor tab holds a connection until the tab is closed or the Unlock timeout fires (WopiLockCleanupService sweeps expired locks every 5 minutes by default).

Upgrade paths:

Tier Cap Notes
Community (current) 20 Free, AGPL. Works for dev and small teams.
Enterprise Unlimited Commercial license from ONLYOFFICE.com. Same Docker image, different license file.
Collabora Online Unlimited (paid) Alternative WOPI-compatible editor under MPL-2.0 connector license. Drop-in replacement for the BaseUrl configuration.

To upgrade from Community to Enterprise: purchase a license, place the license file in the container's /var/www/onlyoffice/Data/license.lic, and restart the container. No Cesivi configuration change is needed.


Upgrade paths

If the 20-connection limit becomes a constraint, two paths exist:

OnlyOffice Enterprise Edition: Purchase a license from OnlyOffice. Drop the license file into the container volume (documentserver-data) and restart. No Cesivi change required — the WOPI API surface is identical.

Collabora Online / CODE: Collabora is a LibreOffice-based WOPI-compatible server. Change OnlyOffice:BaseUrl to point at your Collabora server. Cesivi's WOPI host is protocol-agnostic; the same WopiController endpoints serve both editors. Collabora's connector module is under MPL-2.0, which does not bind Cesivi.


Per-worktree port isolation (dev environments)

When running parallel Cesivi worktrees (for CI or multiple feature branches), each worktree needs its own Document Server instance on a separate port to avoid the 20-connection cap being shared and to keep test isolation.

The following ports are registered in C:\Source\_AI\worktree-ports.json:

Worktree OnlyOffice HTTP port
main 8082
main1 8092
main2 8093
main3 8094
main4 8095
main5 8096

To run OnlyOffice in a non-main worktree, override the port in the worktree's .env:

# In the worktree directory (e.g., C:\Source\_AI\SharePointMock1):
echo "ONLYOFFICE_HTTP_PORT=8092" >> docker/onlyoffice/.env
bash Scripts/onlyoffice.sh up

Update OnlyOffice:BaseUrl in the worktree's local appsettings.json to match:

"BaseUrl": "http://localhost:8092"


Degraded-mode fallback

If the Document Server container is unreachable (down, misconfigured, or never started), Cesivi degrades gracefully:

  • WopiDiscoveryService logs a warning on initial fetch failure and retries on each refresh interval. Until the first successful fetch, IsAvailable is false.
  • /_api/onlyoffice/supported-types returns HTTP 503 with {"error":"onlyoffice_unavailable"} when the discovery cache is empty.
  • The WebUI's allitems-custom-actions.js calls supported-types on page load. When it receives 503 or an empty editable list, the "Edit in browser" ECB menu and ribbon button are hidden. No error is shown to the user — the action simply does not appear.
  • If a user has the editor page open and the container goes down mid-session, the editor shows an error card. The user can download the in-progress version from the editor's "Download" button before closing.

Troubleshooting

Symptom Likely cause Resolution
"Edit in browser" action does not appear Enabled=false, discovery unavailable, or empty supported-types response Check OnlyOffice:Enabled in config; run curl /_api/onlyoffice/supported-types; check Cesivi log for WopiDiscoveryService warnings
Editor iframe shows blank or "Error loading document" JWT secret mismatch between Cesivi and Document Server Run bash Scripts/onlyoffice.sh jwt and compare with OnlyOffice:JwtSecret in Cesivi config
HTTP 403 on editor open or autosave Permission denied at list/file level, OR JWT mismatch Check file permissions in Cesivi; verify JWT secret is identical on both sides
HTTP 409 when trying to open file Another editor already has the file locked (WOPI conflict) Wait for the other editor to close (lock auto-expires in LockSweepInterval, default 5 min); or check WopiLockCleanupService logs
Healthcheck returns true but editor shows "can't download file" Container networking — Document Server cannot reach Cesivi at localhost Use host.docker.internal as the Cesivi hostname in the editor config; see _docs_dev/onlyoffice-docker-setup.md for details
Editor loads but shows 503 or "Document Server is unavailable" 20-connection cap reached Close unused editor tabs; consider upgrading to Enterprise
WopiDiscoveryService: initial fetch from ... failed in Cesivi log Container not running or unreachable Start container: bash Scripts/onlyoffice.sh up

Security notes

JWT secret storage: Never store JwtSecret in source-controlled config files. Use environment variable OnlyOffice__JwtSecret or a secrets management tool. The secret controls who can issue tokens to the Document Server — exposure means anyone can forge editor sessions.

Network isolation: The Document Server container listens on 0.0.0.0:8082 (or the configured port) on the host. In a production environment, restrict access using a firewall rule or Docker network to allow only the Cesivi server and authorized browser clients. There is no built-in authentication on the /hosting/discovery endpoint.

Token TTL: Tokens issued by WopiTokenService expire after 1 hour by default. After expiry the Document Server rejects autosave callbacks. Long-running editing sessions should autosave within 60 minutes or the user will receive an error card.

AGPL note: OnlyOffice Community Edition is AGPL-3.0. Cesivi consumes it as an unmodified network service. Running Document Server as a network service without modifying its source code does not trigger the AGPL copyleft for Cesivi. If you ever modify Document Server's source, consult your legal team.


Verification Procedure

Verified 2026-05-28 against OnlyOffice Document Server 8.2.2 (Community Edition) with Cesivi on .NET 10.

This procedure demonstrates the full edit-and-save round-trip. Run it after any upgrade or configuration change to confirm the integration is healthy.

Step 1 — Start the container and confirm it is healthy:

bash Scripts/onlyoffice.sh up
curl http://localhost:8082/healthcheck       # expect: true
curl http://localhost:8082/hosting/discovery # expect: WOPI discovery XML

Step 2 — Open a document library and upload a .docx file (or use an existing one). Right-click the file → "Edit in browser" (or use the context-menu ECB action labelled "Edit in Browser").

Step 3 — Confirm the editor renders (no error card). The OnlyOffice toolbar and document canvas should appear inside the iframe. The URL becomes /OnlyOffice/Edit?fileId=<encoded-id>&mode=edit.

OnlyOffice editor loaded

Step 4 — Make a change and save. The editor auto-saves after ~2 seconds of inactivity. You can also press Ctrl+S. When the Document Server has flushed the save, it calls the Cesivi WOPI PutFile endpoint, which creates a new version.

Step 5 — Confirm version incremented. Navigate to the file's version history (/Lists/<library>/<file>/VersionHistory.aspx or the "Version History" context-menu item). The version counter should increase by 1.

OnlyOffice editor after save

Automated proof: OnlyOfficeBrowserE2ETests.cs in Cesivi.Tests.WebUI automates Steps 2–5. Run:

bash Scripts/run-e2e-batch.sh 188 190   # runs OnlyOfficeBrowserE2ETests + all round-trip tests

All 16 tests (2 browser + 4 edit-page + 10 round-trip) must pass with 0 failures.

Troubleshooting the verification

Symptom Resolution
Error card "Browser editing unavailable" Container not running — bash Scripts/onlyoffice.sh up
#oo-frame iframe visible but blank JWT secret mismatch — bash Scripts/onlyoffice.sh jwt and compare with OnlyOffice:JwtSecret in config
Version count does not increment after save Check WopiLockStore logs; confirm EnableVersioning is on for the library; if the fix from PLAN-1627 is not applied, GetParentListAsync in FileService.cs may silently skip version creation