-------------------------------------------
* **onlyoffice**
* **Jonathan Haack**
* **Haack's Networking**
* **webmaster@haacksnetworking.org**
-------------------------------------------
//OnlyOffice//
-------------------------------------------
~~NOTOC~~
==== Introduction ====
This tutorial is for Debian users who wish to spin up an Only Office container using podman. It presumes you have a Cockpit container VM/host setup already. If not, head over to [[https://wiki.haacksnetworking.org/doku.php?id=computing:cockpit|Cockpit]] before you start here. Once podman is setup and you have a dedicated rootless user, you can proceed. To begin with, let's setup a directory for this container and generate our jwt secret:
==== 1. Directories and secret (worker) ====
mkdir -p ~/onlyoffice/{data,logs,lib,db}
umask 077
openssl rand -hex 32 | tee ~/onlyoffice/jwt.secret
chmod 600 ~/onlyoffice/jwt.secret
This will generate the secret and use ''tee'' to place it in the expected directory and file.
==== 2. Quadlet ====
After the secret is cut, we can now build our quadlet unit to manage the container, restart it on reboot/failure, etc. To do that, let's create our systemd directory and then create our quadlet configuration.
mkdir -p ~/.config/containers/systemd
cat > ~/.config/containers/systemd/container-onlyoffice.container << 'EOF'
[Container]
ContainerName=onlyoffice
Image=docker.io/onlyoffice/documentserver:latest
PublishPort=127.0.0.1:8082:80
Environment=JWT_ENABLED=true
Environment=JWT_SECRET=replace-with-your-jwt-secret
Environment=JWT_HEADER=Authorization
Environment=ALLOW_PRIVATE_IP_ADDRESS=false
Volume=/home/worker/onlyoffice/logs:/var/log/onlyoffice:Z
Volume=/home/worker/onlyoffice/data:/var/www/onlyoffice/Data:Z
Volume=/home/worker/onlyoffice/lib:/var/lib/onlyoffice:Z
Volume=/home/worker/onlyoffice/db:/var/lib/postgresql:Z
Volume=/home/worker/podman-local/volumes/84a360c1a5dd357b0cfe5af71a59f7338eeca694336b1ea8bef5d5c41fe7deb7/_data:/usr/share/fonts/truetype/custom:Z
PodmanArgs=--cpus=4 --memory=8g
[Service]
Restart=always
TimeoutStopSec=120
[Install]
WantedBy=default.target
EOF
systemctl --user daemon-reload
systemctl --user reset-failed container-onlyoffice.service
systemctl --user start container-onlyoffice.service
==== 3. Verify ====
Once the quadlet is built, we now need to verify the container is up and running. Wait a minute or two so the container can spin up, then check its status as follows:
systemctl --user is-active container-onlyoffice.service
podman inspect onlyoffice --format '{{.Name}} cpus={{.HostConfig.NanoCpus}} memory={{.HostConfig.Memory}}'
curl -sS -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8082/healthcheck
podman exec onlyoffice supervisorctl status
Look for ''active'', ''cpus=4000000000'', ''memory=8589934592'', HTTP ''200'', and ''ds:converter'' / ''ds:docservice'' ''RUNNING'' in the output and the endpoint check that you ran with curl. If your service is not accessible, stop here and debug.
==== 4. Upgrade script ====
Now that the quadlet unit is built, we can create a simple script to update the container. To do that, let's create a script called ''nano /usr/local/bin/upgrade-onlyoffice.sh''. Inside the script, let's put something like the following:
#!/bin/bash
set -euo pipefail
export XDG_RUNTIME_DIR=/run/user/$(id -u)
export DBUS_SESSION_BUS_ADDRESS=unix:path=${XDG_RUNTIME_DIR}/bus
podman pull docker.io/onlyoffice/documentserver:latest
systemctl --user stop container-onlyoffice.service
systemctl --user daemon-reload
systemctl --user reset-failed container-onlyoffice.service
systemctl --user start container-onlyoffice.service
sleep 90 #let's the container start up before verifying the endpoint
curl -sS -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8082/healthcheck
==== 5. Apache reverse proxy (root) ====
Alright, now that the container is running and the unit for managing it is ready to go, we can create a reverse proxy virtual host so it can be accessed externally. Let's enable the appropriate packages in apache and cut the cert:
sudo a2enmod proxy proxy_http proxy_wstunnel headers rewrite ssl authz_host
sudo certbot certonly --apache -d files.haacksnetworking.org
Now let's configure the virtual host with ''nano /etc/apache2/sites-available/files.haacksnetworking.org.conf'':
ServerName files.haacksnetworking.org
RewriteEngine On
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
You can add the TLS block to the same virtual host and/or, if you prefer, create a dedicated vhost. I prefer a dedicated vhost, so I create ''nano /etc/apache2/sites-available/files.haacksnetworking.org-ssl.conf'' and enter the following in it:
ServerName files.haacksnetworking.org
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/files.haacksnetworking.org/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/files.haacksnetworking.org/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
SetEnvIf Host "^(.*)$" THE_HOST=$1
RequestHeader setifempty X-Forwarded-Proto "https"
RequestHeader setifempty X-Forwarded-Host %{THE_HOST}e
ProxyAddHeaders Off
ProxyPreserveHost On
RewriteEngine On
RewriteCond %{HTTP:Upgrade} websocket [NC]
RewriteCond %{HTTP:Connection} upgrade [NC]
RewriteRule ^/?(.*) "ws://127.0.0.1:8082/$1" [P,L]
ProxyPass / http://127.0.0.1:8082/
ProxyPassReverse / http://127.0.0.1:8082/
ErrorLog ${APACHE_LOG_DIR}/onlyoffice-error.log
CustomLog ${APACHE_LOG_DIR}/onlyoffice-access.log combined
Once the virtual hosts are created, let's enable them and check the endpoint:
a2ensite files.haacksnetworking.org.conf
apache2ctl configtest && systemctl reload apache2
curl -sI https://files.haacksnetworking.org/healthcheck
If anything barfs here, stop and debug. If not, we can move on to configuring Nextcloud.
==== 6. Nextcloud ====
In Nextcloud, go to apps and disable the default Office Suites. After that, install Only Office and then go to Admin Settings > OnlyOffice and enter in your credentials:
* Document Editing Service address: ''https://files.haacksnetworking.org''
* Secret: contents of ''~/onlyoffice/jwt.secret''
Click Save and then navigate to an office file and test it out. If it works, you are done. If not, debug and trace back over the steps taken.
--- //[[alerts@haacksnetworking.org|oemb1905]] 2026/10/10 03:27//