Euro-Office

Euro-Office

Docker app from junkerderprovinz's Repository

Overview

Euro Office Document Server - a sovereign, European document server for browser-based editing of text documents, spreadsheets and presentations. It is a maintained fork of the OnlyOffice Document Server, so it speaks the same WOPI and OnlyOffice APIs and plugs straight into OpenCloud (and Nextcloud/ownCloud). Use it to edit .docx / .xlsx / .pptx and .odt / .ods / .odp files right in your browser, without any desktop office suite. This is a thin wrapper (github.com/junkerderprovinz/euro-office) around the official image that fixes a real upstream bug: the vendor's own build skips handing ownership of the Data folder to the user its services actually run as, so on a fresh bind-mounted volume - exactly what Unraid creates - the admin panel and parts of document handling fail with a permission error. This wrapper heals that automatically; nothing else about the upstream image is changed. This is NOT a standalone app - it is the EDITOR back-end for a file server. You point your cloud (e.g. the OpenCloud container) at this document server and edit files stored in that cloud. On its own it only serves an internal welcome page. How it fits together (with OpenCloud): • Install this container. Set a JWT secret below and remember it. • In the OpenCloud template set "Web office suite" = euro-office, "Office document server URL" = http://[THIS-SERVER-IP]:9900 (the port you map below), and "Office WOPI secret" = the SAME value as the JWT secret here. The two secrets MUST match. • If you reach OpenCloud over https, that http:// editor URL will NOT work - the browser blocks it as mixed content. Configure the TLS fields under Advanced View and use https://[THIS-SERVER-IP]:9943 instead. See "HTTPS / mixed content" below. • Open a document in OpenCloud - it now opens in Euro Office. OpenCloud uses Euro Office for Microsoft formats by default and Collabora for ODF, but Euro Office edits both. First start: • The document server bundles its own database and converter and takes a minute or two to come up on the very first start. Wait until http://[IP]:9900/hosting/discovery returns XML before opening a document from your cloud. • Leave the "Database" and "Logs" fields under Advanced View BLANK. Neither is required, and mounting a fresh empty folder over either one hides a directory the image ships pre-built, which stops the container from starting (see Troubleshooting below). Security / reverse proxy: • Keep "JWT enabled" = true (the default). The JWT secret signs every request between your cloud and the editor - never leave it blank. • By default the container serves plain HTTP on the mapped port. There are two ways to get TLS. Either put it behind a reverse proxy that terminates TLS (e.g. https://office.example.com) and use that https URL in OpenCloud, or let the document server terminate TLS itself with the "TLS certificate" and "TLS private key" fields under Advanced View - no proxy needed, which is the simpler route on a LAN. • Whichever route you pick: if your cloud is on https, the editor MUST be on https too. See "HTTPS / mixed content" below for the full four-step setup. • If your cloud uses a self-signed certificate, set "Allow self-signed upstream" = true so the editor can fetch documents from it. Troubleshooting - container loops "PostgreSQL ... is not accessible or does not exist": • Your "Database" field under Advanced View has a path in it. Open the container's Edit page, switch on Advanced View, clear the "Database" field completely, then Apply. The bundled, already-initialised database takes over and the container starts normally within a minute. Troubleshooting - container loops "Starting nginx nginx ...fail!": • Your "Logs" field under Advanced View has a path in it. The image keeps its log tree at /var/log/euro-office/documentserver, so mounting an empty folder over /var/log/euro-office hides it, nginx cannot open its error log there, and the entrypoint aborts before the editor comes up. Open the container's Edit page, switch on Advanced View, clear the "Logs" field completely, then Apply. • The logs are not lost by clearing the field - the Unraid log button on the container still shows everything the server prints. HTTPS / mixed content - documents never open, the editor area stays blank, or the browser says "this content is blocked, contact the site owner": • This is a browser security rule, NOT a bug in either app. If OpenCloud is served over https and Euro Office over plain http, the browser refuses to load the http editor inside the https page. It never sends the request, so NEITHER service logs anything - the OpenCloud log and the Euro Office log both look perfectly healthy. Only the browser's developer console shows it, as a "Mixed Content" line. • The fix is to let Euro Office serve HTTPS itself. Switch on Advanced View on this container's Edit page and do all four steps - step 3 is the one people miss. • 1. Put a certificate and its private key into the Certificates folder (default /mnt/user/appdata/euro-office/certs). A self-signed pair is fine on a LAN; on the Unraid console run: openssl req -x509 -newkey rsa:2048 -nodes -keyout /mnt/user/appdata/euro-office/certs/key.pem -out /mnt/user/appdata/euro-office/certs/cert.pem -days 3650 -subj "/CN=YOUR-SERVER-IP". The key MUST stay unencrypted, which is exactly what -nodes does - passphrase-protected keys are not supported. Unraid's own combined *_Unraid_bundle.pem works too: copy it in and point BOTH fields at that one file. • 2. Set "TLS certificate" = /certs/cert.pem and "TLS private key" = /certs/key.pem. Both must be filled in and both files must really exist, or TLS is skipped SILENTLY and the server stays on plain http with no warning anywhere. • 3. Map the "HTTPS Port" (default 9943). This is NOT optional. Once a certificate is configured the editor listens on container port 443, and the plain HTTP port stops serving the editor - it becomes a redirect that drops the port number, so http://[IP]:9900 bounces you to https://[IP], which on Unraid is the Unraid WebUI, not Euro Office. • 4. In OpenCloud set "Office document server URL" = https://[THIS-SERVER-IP]:9943. With a self-signed certificate, open https://[IP]:9943/hosting/discovery once in the same browser and accept the certificate, otherwise the browser blocks the editor again - this time for an untrusted certificate rather than for mixed content. • Check it worked: the container log MUST contain the line "SSL enabled with cert=". If that line is missing, TLS did not come up and the server is still on plain http - one of the two paths is wrong or points at a file that does not exist INSIDE the container (the path you enter is the /certs/... path, not the /mnt/user/... path). • The WebUI button on this container stays on http://[IP]:9900. That is correct for the default HTTP install and cannot switch itself. After enabling TLS, edit the WebUI field on the container's Edit page to https://[IP]:[PORT:443]/ if you want the button to work. About Euro Office: • Euro Office is an open, sovereignty-focused document server developed in Europe as an OnlyOffice-compatible fork. Because it is API-compatible, any guide for "OnlyOffice Document Server + OpenCloud/Nextcloud" applies here as well. Project: https://github.com/euro-office/documentserver This is an independent, community-maintained Unraid packaging and is not affiliated with the Euro Office project.
Euro Office

Build  Upstream  Image  OpenCloud  Unraid  License: AGPL-3.0

A plug-and-play Unraid Community Applications template for Euro Office, the sovereign European document server. It edits Word, Excel and PowerPoint files (and their OpenDocument equivalents) in the browser and plugs straight into OpenCloud over WOPI. Install from the Unraid Apps tab, set one shared secret, done.


Maintained solo, in whatever spare time there is. Questions via the support thread, bugs, ideas and feature requests via GitHub issues. If it's useful to you, a coffee is always welcome.

Buy me a coffee   PayPal   Donate with crypto


Table of Contents

  1. What is this?
  2. Why this image exists
  3. Features
  4. Quick Start on Unraid
  5. Wiring it to OpenCloud
  6. Configuration
  7. Updating
  8. Troubleshooting
  9. Contributing / License
  10. Support this project

1. What is this?

Euro Office is a sovereign, European document server for browser-based editing of text documents, spreadsheets and presentations. It is a maintained fork of the OnlyOffice Document Server, so it speaks the same OnlyOffice and WOPI APIs and drops straight into OpenCloud, Nextcloud or ownCloud.

This repository is not a fork of Euro Office. It builds a thin wrapper image around the upstream ghcr.io/euro-office/documentserver, adding exactly one thing: a small supervisor program that repairs the ownership of the Data volume on boot. Section 2 explains why that is needed. The Unraid template lives in unraid-apps and points at the wrapper image published here.

This is not a standalone app. It is the editor back-end for a file server. On its own it only serves an internal welcome page. You point your cloud (the OpenCloud container) at it, and then edit files that live in that cloud.


2. Why this image exists

The upstream image ships with a real permission bug. The chown -R ds:ds step that should hand ownership of the Data volume to the ds user, the account every internal service actually runs as, is commented out in the vendor's own build. On a freshly bind-mounted Data folder, which is exactly what Unraid creates, the document server's admin panel and in some configurations editing itself fail with a permission error.

This image adds one thing to the upstream image and nothing else: a small supervisor program that re-asserts Data's ownership during the first seconds of boot, before the ds-* services start. ENTRYPOINT and the vendor's own entrypoint.sh are untouched. See unraid-apps#7 for the report that turned this up.


3. Features

  • ✅ Edits .docx / .xlsx / .pptx and .odt / .ods / .odp right in the browser
  • ✅ WOPI protocol pre-enabled (WOPI_ENABLED=true), so OpenCloud can open and save documents
  • ✅ One shared JWT secret signs every request between cloud and editor
  • ✅ Sensible Unraid defaults: HTTP on a mapped port, optional persistence volumes, --restart=unless-stopped
  • ✅ Reverse-proxy friendly, terminate TLS in front and hand the editor plain HTTP
  • ✅ Bundles its own database and converter, no external services to run
  • ✅ AGPL-3.0 wrapper, fork and adapt it under the same license

4. Quick Start on Unraid

This is a plug-and-play Community Applications template. No SSH, no config-file editing.

Step 1: install from Apps

In the Unraid Web UI:

  1. Go to the Apps tab.
  2. Search for Euro Office.
  3. Click Install.

Step 2: set the JWT secret

The template's one required field is the JWT secret. Pick a long random string and remember it, you will paste the same value into OpenCloud in the next section. Leave Enable WOPI on true.

Hit Apply. First start pulls the image and warms up the bundled database and converter, this takes a minute or two on the very first boot.

Step 3: wait for the server to be ready

Open a shell and confirm the WOPI discovery endpoint answers with XML:

curl -s http://<unraid-ip>:9900/hosting/discovery | head -c 200

Once that returns an <wopi-discovery> document, the editor is ready. Then wire it to OpenCloud (next section).

Manual install (pre-CA-listing)

Until this repo is accepted into the Community Applications index, you can load the template by hand. Run this once on the Unraid console or via SSH:

mkdir -p /boot/config/plugins/dockerMan/templates-user && \
curl -fsSL -o /boot/config/plugins/dockerMan/templates-user/my-Euro-Office.xml \
  https://raw.githubusercontent.com/junkerderprovinz/unraid-apps/main/euro-office/euro-office.xml

Then in the Unraid Web UI: Docker → Add Container → in the Template dropdown, pick Euro-Office under User templates.

Plain Docker (no Unraid)

docker run -d \
  --name euro-office \
  --restart unless-stopped \
  -p 9900:80 \
  -e WOPI_ENABLED=true \
  -e JWT_ENABLED=true \
  -e JWT_SECRET=change-me-to-a-long-random-string \
  ghcr.io/euro-office/documentserver:latest

5. Wiring it to OpenCloud

Euro Office is the editor; OpenCloud is the cloud that stores your files. Connect them in the OpenCloud template:

OpenCloud field Value
Web office suite euro-office
Office document server URL http://<euro-office-ip>:9900 (or your reverse-proxy https URL)
Office WOPI secret the same string you set as the JWT secret here

The two secrets must be identical, that is what lets the cloud and the editor trust each other. After applying both containers, open a document in OpenCloud, it now opens in Euro Office. OpenCloud uses Euro Office for Microsoft formats by default and Collabora for OpenDocument, but Euro Office edits both.

[!TIP] Behind the internet, put Euro Office behind a reverse proxy that terminates TLS (e.g. https://office.example.com) and use that https URL in OpenCloud. If OpenCloud itself uses a self-signed certificate, set Allow self-signed upstream = true on this container so the editor can fetch documents from it.


6. Configuration

Variable Default Description
JWT_SECRET (required) Shared secret that signs cloud ↔ editor traffic. Must equal OpenCloud's Office WOPI secret.
WOPI_ENABLED true Enables the WOPI protocol OpenCloud uses. Keep true.
JWT_ENABLED true Require the signed JWT on every request. Keep true; only disable for isolated LAN testing.
USE_UNAUTHORIZED_STORAGE false Set true when the cloud serves a self-signed certificate.

Ports & Volumes

Port Purpose Volume (optional) Purpose
80 → 9900 Document server HTTP / WOPI /var/www/euro-office/Data Keys, fonts cache, forgotten files
/var/log/euro-office Server logs, leave unmounted, see below
/var/lib/postgresql Bundled database, leave unmounted, see below

Data is optional: for a pure WOPI back-end the editor is effectively stateless (your documents live in OpenCloud), mount it only to persist the internal cache across restarts. It is empty inside the image, so a bind mount there hides nothing.

Logs and Database are different and default to unmounted on purpose. The image ships both directories pre-built, and a bind mount from an empty host folder hides what is inside them, which stops the container from starting: over /var/log/euro-office it hides the log tree nginx writes to, over /var/lib/postgresql it hides the already-initialised database (see Troubleshooting for both). Leave them blank unless the folder already holds a copy of what the image put there. Clearing Logs costs you nothing, the Unraid log button still shows everything the server prints.


7. Updating

On Unraid: Docker tab → click the container → Force Update. Euro Office tracks the upstream ghcr.io/euro-office/documentserver:latest image. To pin a specific version, set an explicit tag in the template's Repository field (Advanced View).


8. Troubleshooting

Documents won't open in OpenCloud ("error finding app providers" / editor never loads)
  • Confirm the discovery endpoint answers: curl -s http://<ip>:9900/hosting/discovery | head should return <wopi-discovery> XML. If it times out, the server is still starting, wait a minute after first boot.
  • The JWT secret here and OpenCloud's Office WOPI secret must be byte-for-byte identical. A mismatch fails silently.
  • Make sure OpenCloud's Office document server URL is reachable from the OpenCloud container (use the LAN IP or a resolvable proxy hostname, not localhost).
"Download failed" when saving, or the editor can't fetch the file
  • If OpenCloud uses a self-signed certificate, set Allow self-signed upstream = true (USE_UNAUTHORIZED_STORAGE=true) on this container.
  • If you front OpenCloud with a reverse proxy, make sure the URL you gave OpenCloud is the one the editor can actually reach.
First start is slow / high CPU right after boot
  • Normal. The bundled database and converter warm up on the first start. It settles once /hosting/discovery returns XML, usually within a minute or two.
Container loops "PostgreSQL ... is not accessible or does not exist" and never starts
  • The Database field (Advanced View) has a path in it. The image ships with an already-initialised database baked in; mounting a fresh empty folder over /var/lib/postgresql hides it, and the entrypoint has no way to initialise a database in an empty volume (upstream bug, no fix yet: euro-office/documentserver#299).
  • Fix: open the container's Edit page, switch on Advanced View, clear the Database field completely, then Apply. The container starts normally within a minute using the bundled database, which simply resets on the next recreate, fine for WOPI use with OpenCloud.
  • Only fill in Database if that folder already contains a working euro-office Postgres data directory (for example one copied out of a running container first).
Container loops "Starting nginx nginx ...fail!" on a fresh install
  • The Logs field (Advanced View) has a path in it. The image builds its log tree at /var/log/euro-office/documentserver (that is where nginx.error.log and one folder per service live), and the entrypoint never recreates it. Mounting a fresh empty folder over /var/log/euro-office hides the whole tree, so nginx aborts with open() "/var/log/euro-office/documentserver/nginx.error.log" failed (2: No such file or directory). The entrypoint runs under set -e, so that one failure ends the boot and --restart=unless-stopped starts the same failure over again.
  • Fix: open the container's Edit page, switch on Advanced View, clear the Logs field completely, then Apply. The container comes up within a minute and /hosting/discovery starts answering.
  • You do not lose the logs: the Unraid log button on the container shows everything the server prints either way.
  • Only fill in Logs if that folder already contains the log tree copied out of a running container first.

9. Contributing / License

Pull requests welcome. Issues: https://github.com/junkerderprovinz/euro-office/issues.

Licensing, dual:

  • This wrapper (Dockerfile, chown-heal.sh, print-banner.sh, Unraid template, README and banner/icon artwork) is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0).
  • Euro Office itself is developed by the Euro Office project and retains its upstream license, see https://github.com/euro-office/documentserver. When you run, redistribute or rebuild the resulting container image, you must comply with all upstream licenses, not only with this wrapper's AGPL-3.0.

Credits


10. Support this project

Questions? Check the support thread. Bugs, ideas or feature requests? Please open a GitHub issue.

This is a one-person project. I put a lot of time and effort into building and maintaining it, in whatever free time I have. If it's helped you, I'd genuinely appreciate the support: you're welcome to buy me a coffee.

Buy me a coffee   PayPal   Donate with crypto

Install Euro-Office on Unraid in a few clicks.

Find Euro-Office in Community Apps on your Unraid server, review the template, and click Install. Unraid handles the Docker app or plugin setup from the published template.

Open the Apps tab on your Unraid server Search Community Apps for Euro-Office Review the template variables and paths Click Install

Related apps

Explore more like this

Explore all

Details

Repository
ghcr.io/junkerderprovinz/euro-office:latest
Last Updated2026-09-25
First Seen2026-08-20

Runtime arguments

Web UI
http://[IP]:[PORT:80]/
Network
bridge
Shell
sh
Privileged
false
Extra Params
--restart=unless-stopped

Template configuration

WebUI PortPorttcp

HTTP port the document server listens on. This is the address your cloud (OpenCloud) talks to and the URL that must return XML at /hosting/discovery. Behind a reverse proxy, point the proxy at this port.

Target
80
Default
9900
Value
9900
JWT secretVariable

Shared secret that signs every request between your cloud and this editor. REQUIRED. Pick a long random string. It MUST be identical to the 'Office WOPI secret' you set in the OpenCloud template. Keep it secret.

Target
JWT_SECRET
Enable WOPIVariable

Turns on the WOPI protocol that OpenCloud uses to open and save documents. Keep 'true' - with 'false' OpenCloud cannot use this editor.

Target
WOPI_ENABLED
Default
true|false
Value
true
Enable JWTVariable

Require the signed JWT on every request. Keep 'true' for security. Only set 'false' for isolated testing on a trusted LAN.

Target
JWT_ENABLED
Default
true|false
Value
true
Allow self-signed upstreamVariable

Set 'true' when your cloud (OpenCloud) serves a self-signed certificate, so the editor can fetch and save documents from it. Leave 'false' when the cloud has a valid certificate or you talk to it over plain http.

Target
USE_UNAUTHORIZED_STORAGE
Default
false|true
Value
false
DataPathrw

Optional. Persistent document-server data (keys, fonts cache, forgotten files). Recommended for a permanent install; can be omitted for a purely stateless WOPI backend.

Target
/var/www/euro-office/Data
Default
/mnt/user/appdata/euro-office/data
Value
/mnt/user/appdata/euro-office/data
LogsPathrw

Leave BLANK for a normal install. The image builds its log tree at /var/log/euro-office/documentserver (nginx.error.log plus one folder per service). Mounting an EMPTY folder over /var/log/euro-office hides that tree, nginx then cannot open its error log and fails with 'Starting nginx nginx ...fail!', and because the entrypoint stops on that error the container crash-loops on every boot. You lose nothing by leaving this blank: the Unraid log button still shows everything the server prints. Only set a path here if it already contains the log tree copied out of a running container first.

Target
/var/log/euro-office
DatabasePathrw

Leave BLANK for a normal install. The image ships with an already-initialised database baked in; mounting an EMPTY folder here hides that database and the container fails to start with 'PostgreSQL ... is not accessible or does not exist' on every boot (an upstream bug: the entrypoint cannot initialise a database in a fresh empty volume - see euro-office/documentserver#299). Without this mount the DB simply resets on container recreate, which is fine for WOPI use with OpenCloud. Only set a path here if it already contains a working euro-office Postgres data directory copied out of a running container first.

Target
/var/lib/postgresql
HTTPS PortPorttcp

Only used once you fill in 'TLS certificate' and 'TLS private key' below. From that moment the document server serves the editor over https on THIS port, and the plain 'WebUI Port' above stops serving the editor entirely - it turns into a redirect that drops the port number, so http://[IP]:9900 bounces to https://[IP], which on an Unraid box is the Unraid WebUI. Point OpenCloud's 'Office document server URL' at https://[THIS-SERVER-IP]:9943 in that case. Without TLS this mapping is harmless: nothing listens on container port 443, so you can leave it as it is or remove it.

Target
443
Default
9943
Value
9943
CertificatesPathro

Optional. Folder holding the TLS certificate and private key used by the two fields below. Leave it as it is if you are not using TLS - an empty folder here changes nothing, because /certs is not a directory the image ships. Drop cert.pem and key.pem into /mnt/user/appdata/euro-office/certs on the server, then set the two fields below to /certs/cert.pem and /certs/key.pem. Mounted READ-ONLY: the server only ever reads them. Do NOT put certificates in the Data folder instead - this wrapper re-asserts ownership of that whole tree to the container's internal 'ds' user for the first 30 seconds of every boot, so your certificate files would get their host-side ownership rewritten on each start.

Target
/certs
Default
/mnt/user/appdata/euro-office/certs
Value
/mnt/user/appdata/euro-office/certs
TLS certificateVariable

Leave BLANK for plain HTTP (the default). Fill this in to let the document server serve HTTPS itself, which is REQUIRED when your cloud runs on https - otherwise the browser silently blocks the editor as mixed content and shows only 'this content is blocked, contact the site owner', with nothing in either service's log. Put the certificate in the 'Certificates' folder above and enter its IN-CONTAINER path here, e.g. /certs/cert.pem (not the /mnt/user/... path). A self-signed certificate is fine on a LAN. If you use Unraid's own combined *_unraid_bundle.pem, which holds the certificate and the key in ONE file, point this field AND 'TLS private key' at that same file. IMPORTANT: this and 'TLS private key' must BOTH be set and both files must exist, or TLS is skipped SILENTLY and the server stays on plain http. Also map the 'HTTPS Port' above - the editor moves to port 443 once TLS is on. After Apply, check the container log for the line 'SSL enabled with cert=': if it is missing, one of the two paths is wrong.

Target
SSL_CERTIFICATE_PATH
TLS private keyVariable

Leave BLANK for plain HTTP (the default). IN-CONTAINER path to the private key belonging to 'TLS certificate' above, e.g. /certs/key.pem. The key must NOT be passphrase-protected - encrypted keys are not supported by the document server, so generate it with openssl's '-nodes' option. With Unraid's combined *_unraid_bundle.pem, enter that same file path in both fields. Both this and 'TLS certificate' must be filled in and both files must exist, or TLS is skipped SILENTLY and the server stays on plain http.

Target
SSL_KEY_PATH
Send HSTS headerVariable

Only has any effect once TLS is configured above. 'true' (the default) tells browsers to remember to use https for this host for a year. Set 'false' if this container shares a hostname with other services you still reach over plain http, e.g. unraid.example.com - the browser stores that rule per HOSTNAME and ignores the port, so it would force https on your Unraid WebUI and everything else on that name too. It does nothing at all when you reach the editor by IP address or with a self-signed certificate, because browsers ignore HSTS in both of those cases.

Target
ONLYOFFICE_HTTPS_HSTS_ENABLED
Default
true|false
Value
true