Skip to content

Storage integration

Connect Nextcloud step by step

Install richdocuments, run activate-config with wopi_url and wopi_callback_url, set alias groups and certificates, verify in seven steps, and fix common errors.

On this page

Nextcloud talks to the O3O editor server through the richdocuments app (shown as “Nextcloud Office”). This page goes from zero to opening a .docx file inside Nextcloud, using the nextcloud profile that ships in online/docker/compose.dev.yml. The commands were run for real on Nextcloud 30.0.17 with richdocuments 8.5.17.

The big picture#

ComponentName on o3o-netExposed on your machine
o3o-proxyo3o-proxy:8080http://localhost:8080
Editor servero3o-online:9980not exposed, goes through the proxy
o3o-gateo3o-gate:8070only /o3o/ through the proxy
Nextcloud 30o3o-nextcloud:80http://localhost:8081
MariaDB 11, Redis 7o3o-nextcloud-db, o3o-nextcloud-redisnot exposed

The most common trap: you open Nextcloud at http://localhost:8081, but localhost inside the o3o-online container is that container itself. So we give richdocuments an internal callback address (wopi_callback_url = http://o3o-nextcloud) so that WOPISrc uses a name the editor server can reach.

Steps#

  1. Prepare

    Set up the DEV Docker bundle following the compose guide and run the secrets script (online/.env must not contain CHANGE_ME; MariaDB refuses empty passwords). Ports 8080 and 8081 must be free.
  2. Start the nextcloud profile

    Command in the first code block below. On first start Nextcloud installs itself, which takes a few minutes.
  3. Install richdocuments

    The machine needs Internet access to download the app from the Nextcloud app store.
  4. Run activate-config with both -w and -c

    It writes wopi_url and wopi_callback_url, tests discovery and capabilities, then derives public_wopi_url.
  5. Check the O3O-side variables

    aliasgroup2 must contain http://o3o-nextcloud, and Nextcloud's trusted domains must include o3o-nextcloud.
  6. Try it

    Sign in at http://localhost:8081 with O3O_NC_ADMIN_USER / O3O_NC_ADMIN_PASSWORD, upload a .docx file and click it.
BashStep 2 — start the nextcloud profile
cd online
# Start the nextcloud profile too (Nextcloud 30 + MariaDB 11 + Redis 7)
docker compose --env-file .env -f docker/compose.dev.yml --profile nextcloud up -d

# Wait until Nextcloud reports "installed":true
curl -s http://localhost:8081/status.php
Bashocc shortcut
cd online
# Shortcut for occ inside the o3o-nextcloud container
alias occ='docker compose --env-file .env -f docker/compose.dev.yml --profile nextcloud exec --user www-data o3o-nextcloud php occ'
occ status
BashStep 3 — install richdocuments
occ app:install richdocuments
# On Nextcloud 30 this installs richdocuments 8.5.x. If the app is already present, just enable it:
occ app:enable richdocuments
BashStep 4 — activate-config
# -w: address Nextcloud uses to reach the editor server (internal name on the o3o-net network)
# -c: address the editor server uses to call Nextcloud back (becomes the origin of WOPISrc)
occ richdocuments:activate-config -w http://o3o-online:9980 -c http://o3o-nextcloud
BashExpected output (trimmed)
✓ Set WOPI url to http://o3o-online:9980
✓ Set callback url to http://o3o-nextcloud
Checking configuration
🛈 Configured WOPI URL: http://o3o-online:9980
🛈 Configured public WOPI URL: http://localhost:8080
🛈 Configured callback URL: http://o3o-nextcloud

✓ Fetched /hosting/discovery endpoint
✓ Valid mimetype response
✓ Valid capabilities entry
✓ Fetched /hosting/capabilities endpoint
✓ Detected WOPI server: <editor server name and version>
BashStep 4 — read the configuration back
occ config:app:get richdocuments wopi_url            # http://o3o-online:9980
occ config:app:get richdocuments public_wopi_url     # http://localhost:8080  (derived, never set by hand)
occ config:app:get richdocuments wopi_callback_url   # http://o3o-nextcloud
occ config:app:get richdocuments wopi_allowlist      # empty on a DEV machine
BashStep 5 — O3O-side variables for the DEV bundle
# online/.env
O3O_ONLINE_SERVER_NAME=localhost:8080
O3O_ONLINE_ALIASGROUP2=http://o3o-nextcloud,http://localhost:8081
O3O_NC_TRUSTED_DOMAINS="localhost localhost:8081 o3o-nextcloud"
# Lets the gate ask CheckFileInfo once the cap is reached, so read-only sessions are not refused
O3O_WOPI_ALLOWED_HOSTS=http://o3o-nextcloud
BashApply the new variables
cd online
docker compose --env-file .env -f docker/compose.dev.yml --profile nextcloud up -d o3o-online o3o-gate
curl -s http://localhost:8080/o3o/status

The four richdocuments settings#

richdocuments app settings

  • wopi_urlURLrequired
    Address Nextcloud (server-side PHP) uses to call /hosting/discovery and /hosting/capabilities. May be an internal name. DEV: http://o3o-online:9980.
  • public_wopi_urlURLoptionalDefault: derived
    Address the browser uses. richdocuments takes the origin of urlsrc on every activate-config run and uses it to build the Content-Security-Policy. NEVER set it by hand. If it is wrong, fix O3O_ONLINE_SERVER_NAME and re-run activate-config. DEV: http://localhost:8080.
  • wopi_callback_urlURLoptionalDefault: empty = browser address
    Origin of WOPISrc, i.e. the address the editor server uses to call Nextcloud back. Set it with activate-config -c. DEV: http://o3o-nextcloud.
  • wopi_allowlistIP/CIDR listoptionalDefault: empty = anywhere
    Only accept WOPI calls from these addresses. Separate entries with spaces, commas, semicolons or |. DEV: leave empty. Production: the IP of the editor server.
  • disable_certificate_verification<code>yes</code> / emptyoptionalDefault: empty
    yes disables certificate checks when Nextcloud calls wopi_url over HTTPS. Only for internal self-signed certificates.

Variables in online/.env

  • O3O_ONLINE_SERVER_NAMEhost[:port]requiredDefault: <code>localhost:8080</code>
    Public name of the editor server. Decides urlsrc in discovery and therefore public_wopi_url.
  • O3O_ONLINE_SSL_TERMINATIONtrue / falseoptionalDefault: <code>false</code>
    true when users come in over https through a TLS proxy; urlsrc then starts with https://.
  • O3O_ONLINE_ALIASGROUP2listrequiredDefault: <code>http://o3o-nextcloud,http://localhost:8081</code>
    Allowed WOPI host. The first entry is the main host, the following ones are aliases and are regular expressions (escape dots as \.). aliasgroup1 is always reserved for the gate; do not change it.
  • O3O_NC_TRUSTED_DOMAINSspace-separatedrequiredDefault: <code>localhost localhost:8081 o3o-nextcloud</code>
    Nextcloud trusted domains. Must include o3o-nextcloud because the editor server calls WOPI with that name.
  • O3O_WOPI_ALLOWED_HOSTSlist of URL originsoptionalDefault: empty
    Once the connection cap is reached, the gate calls CheckFileInfo on these origins to recognise read-only sessions and let them in. Empty means the gate never calls out. DEV: http://o3o-nextcloud.

Certificates and production#

On a real server, TLS is terminated at a proxy in front of o3o-proxy (see reverse proxy). The editor server still speaks HTTP internally but must know users arrive over https, so set O3O_ONLINE_SSL_TERMINATION=true. Nextcloud and O3O must both use https, otherwise the browser blocks mixed content.

BashO3O-side variables in production
# online/.env on a real server (TLS terminated by the front proxy)
O3O_PUBLIC_URL=https://office.example.com
O3O_ONLINE_SERVER_NAME=office.example.com
O3O_ONLINE_SSL_TERMINATION=true
O3O_ONLINE_ALIASGROUP2=https://cloud.example.com
O3O_WOPI_ALLOWED_HOSTS=https://cloud.example.com
BashNextcloud-side commands in production
# Run on the real Nextcloud server
occ richdocuments:activate-config -w https://office.example.com -c https://cloud.example.com
occ config:app:get richdocuments public_wopi_url        # https://office.example.com

# Accept WOPI calls from the editor server only (IP or CIDR, separated by space, comma, semicolon or |)
occ config:app:set richdocuments wopi_allowlist --value="203.0.113.10/32"

# ONLY when Nextcloud calls the editor server over https with an internal self-signed certificate
occ config:app:set richdocuments disable_certificate_verification --value=yes

Seven-step verification#

Stop at the first failing step and fix that step.

BashVerification
cd online
# 1. urlsrc must carry the public address (http://localhost:8080/browser/<hash>/cool.html?)
curl -s http://localhost:8080/hosting/discovery | grep -m1 -o 'urlsrc="[^"]*"'
# 2. capabilities returns JSON
curl -s http://localhost:8080/hosting/capabilities
# 3. the gate sees the editor server: "coolwsd": "ok"
curl -s http://localhost:8080/o3o/status
# 4. Nextcloud reaches the editor server: every ✓ line, exit code 0
occ richdocuments:activate-config -w http://o3o-online:9980 -c http://o3o-nextcloud; echo "exit=$?"
# 5. public address Nextcloud derived
occ config:app:get richdocuments public_wopi_url
# 6. open a .docx on http://localhost:8081, type something, then check the editing sessions
curl -s http://localhost:8080/o3o/status | grep -o '"current": *[0-9]*'
# 7. logs on both sides
docker compose --env-file .env -f docker/compose.dev.yml logs --tail 100 o3o-online
occ log:tail 50

Common errors#

SymptomCauseFix
o3o-online log shows Unauthorized WOPI hostThe WOPISrc origin is not in aliasgroup2Add the exact origin (both internal and public names if you use both) to O3O_ONLINE_ALIASGROUP2, restart o3o-online.
Blank editor frame, the browser refuses to frame itpublic_wopi_url is wrong, so Nextcloud's Content-Security-Policy blocks the editor addressFix O3O_ONLINE_SERVER_NAME, restart o3o-online, re-run activate-config with -w and -c.
Document fails to load; o3o-online log shows a connection error to localhost:8081wopi_callback_url is empty (missing -c, or activate-config re-run without -c)Run occ richdocuments:activate-config -w http://o3o-online:9980 -c http://o3o-nextcloud.
Nextcloud log shows WOPI request denied from <ip>wopi_allowlist lacks the editor server IP, or Nextcloud sees the proxy's IPAdd the right IP/CIDR; configure trusted_proxies if there is a proxy.
Nextcloud answers WOPI calls with an “untrusted domain” pageo3o-nextcloud is not a trusted domainAdd it to O3O_NC_TRUSTED_DOMAINS (or occ config:system:set trusted_domains 10 --value=o3o-nextcloud).
activate-config prints Failed to fetch discovery endpointWrong wopi_url, o3o-online not running, or a self-signed certificateCheck curl http://localhost:8080/hosting/discovery; for a self-signed certificate set disable_certificate_verification=yes.
The browser blocks mixed contentNextcloud is on https while the editor is on http, or the reverseUse the same scheme for both; with TLS set O3O_ONLINE_SSL_TERMINATION=true.
The “connection limit reached” page appearsConcurrent editing sessions reached the plan's capOpen read-only or retry later; see connection counting and plans.
o3o-online log shows Could not open proof RSA keyv1 does not provide a proof key to the editor serverNo effect on Nextcloud 30: richdocuments 8.5.17 does not check proof signatures. See WOPI security.