Author | Nejat Hakan |
nejat.hakan@outlook.de | |
PayPal Me | https://paypal.me/nejathakan |
Office Suite Backend Collabora Online
Introduction Collabora Online
Welcome to this comprehensive guide on self-hosting Collabora Online, the powerful open-source online office suite backend based on LibreOffice technology. This document will take you from the fundamental concepts to advanced deployment strategies, equipping you with the knowledge and practical skills needed to run your own secure and private collaborative document editing environment.
Collabora Online enables users to collaboratively edit text documents, spreadsheets, and presentations directly within a web browser. It acts as a backend service that integrates with various frontend file hosting platforms like Nextcloud, ownCloud, Seafile, Moodle, and others using the standard WOPI (Web Application Open Platform Interface) protocol.
Why self-host Collabora Online?
- Data Sovereignty and Privacy: Keep your sensitive documents entirely within your own infrastructure. You control who has access and where the data resides, eliminating reliance on third-party cloud providers and their privacy policies.
- Control and Customization: Tailor the environment to your specific needs. Modify configuration settings, integrate with existing authentication systems, and even apply custom branding.
- Cost-Effectiveness (Potentially): While requiring server resources and maintenance time, self-hosting can be more cost-effective in the long run compared to per-user subscription fees of commercial cloud services, especially for larger organizations or communities.
- Security: You manage the security updates, firewall rules, and access controls, allowing for security postures tailored to your organization's requirements.
- Learning Opportunity: Setting up and managing a service like Collabora Online provides invaluable experience in server administration, containerization, networking, and security.
This guide is structured into Basic, Intermediate, and Advanced levels, catering to different skill sets and deployment goals. Each section includes theoretical explanations followed by practical workshops designed to reinforce learning through hands-on experience. We assume you have a foundational understanding of Linux server administration, basic networking concepts, and familiarity with the command line.
Let's begin by understanding the core components and architecture. Collabora Online Development Edition (CODE), the freely available version we'll focus on, typically runs as a Docker container. It consists of several key components:
loolwsd
(LibreOffice Online WebSocket Daemon): The main service daemon. It listens for incoming WebSocket connections from the frontend application (via a reverse proxy), manages user sessions, and orchestrates document rendering and editing. It acts as the WOPI host.loolforkit
: A process responsible for spawning sandboxed LibreOffice instances (loolkit
) for each active document being edited. This ensures isolation between documents and users.loolkit
: The actual LibreOffice process, running in a chrooted environment, that handles the document rendering and editing tasks based on instructions received fromloolwsd
.
The typical interaction flow is as follows:
- A user clicks a document in their file hosting platform (e.g., Nextcloud).
- Nextcloud (the WOPI client) makes a request to Collabora Online (
loolwsd
, the WOPI host), providing information about the document and the user via the WOPI protocol. loolwsd
validates the request and instructsloolforkit
to start a dedicatedloolkit
process for that document session.loolwsd
establishes a WebSocket connection back to the user's browser (usually proxied through Nextcloud and a reverse proxy).- Document tiles (rendered images of document parts) and user interface elements are sent to the browser, and user input (keystrokes, mouse clicks) is sent back to
loolwsd
to be processed byloolkit
. - Changes are periodically saved back to the file hosting platform via WOPI
PutFile
requests initiated byloolwsd
.
Understanding this architecture is crucial for installation, configuration, and troubleshooting.
General Prerequisites:
- A Linux server (physical or virtual) with root/sudo access. Distributions like Ubuntu, Debian, or CentOS are common choices.
- Docker and Docker Compose installed on the server.
- A registered domain name (essential for proper SSL/TLS setup, especially beyond basic testing).
- Basic understanding of DNS records (A or CNAME records).
- Familiarity with a command-line text editor (like
nano
,vim
, oremacs
). - Network connectivity allowing connections on specific ports (typically 80, 443, and the Collabora port like 9980).
Let's dive into the basic setup.
1. Basic Level
This section covers the fundamentals of Collabora Online CODE, including its core components, resource needs, basic installation using Docker, and initial integration with a file hosting platform like Nextcloud.
Understanding Collabora Online CODE
Collabora Online Development Edition (CODE) is the freely available version of Collabora Online, provided primarily for home users, developers, and small teams. It contains the full feature set but comes with limitations on the number of concurrent connections and documents compared to the commercially supported version (Collabora Enterprise). For educational purposes and many self-hosting scenarios, CODE is perfectly adequate.
CODE vs. LibreOffice
It's important to distinguish CODE from the standard LibreOffice desktop suite:
- LibreOffice: A powerful, open-source desktop office suite (Writer, Calc, Impress, Draw, Math, Base) installed directly on a user's computer.
- Collabora Online (CODE): A server application that uses the LibreOffice core engine (
libreofficikit
) to render and enable editing of documents within a web browser. It requires integration with a separate file management frontend. Users interact with it via their browser, not a desktop application.
CODE essentially takes the core document processing capabilities of LibreOffice and makes them accessible over the web through the loolwsd
daemon and WebSocket communication.
Key Components Revisited
Let's reiterate the main parts running inside the CODE Docker container:
loolwsd
: The central nervous system. It handles:- WOPI protocol communication with the frontend (Nextcloud, etc.).
- Managing WebSocket connections to user browsers.
- Authentication/Authorization checks based on WOPI tokens.
- Distributing editing tasks to
loolkit
instances. - Saving documents back to the host.
- Serving static assets (JavaScript, CSS) for the editing interface.
loolforkit
: The process spawner. Whenloolwsd
needs a document opened, it asksloolforkit
to create a new, isolatedloolkit
process specifically for that document session. This enhances security and stability.loolkit
: The workhorse. This is a modified LibreOffice instance that actually loads the document, renders it into viewable tiles, processes user input, and calculates changes. Each open document typically gets its ownloolkit
process.
These components work together seamlessly to provide the online editing experience.
Resource Requirements
Collabora Online can be resource-intensive, particularly regarding CPU and RAM, as it effectively runs instances of LibreOffice on the server for each active document.
- Minimum Requirements (for light use, 1-2 concurrent users/documents):
- CPU: 2 Cores
- RAM: 2 GB (+ RAM for the host OS and other services)
- Disk Space: 5 GB (for the Docker image and logs, document storage is handled by the frontend)
- Recommended Requirements (for small teams, ~10 concurrent users/documents):
- CPU: 4+ Cores
- RAM: 4-8 GB (+ RAM for host OS/other services)
- Disk Space: 10+ GB
Important Considerations:
- Concurrent Users vs. Concurrent Documents: CODE's performance is more directly tied to the number of actively edited documents than the total number of users who might use it. Each open document consumes significant RAM and CPU.
- Document Complexity: Large or complex documents (e.g., spreadsheets with many formulas, presentations with high-resolution images) require more resources per session.
- Host System: Ensure the underlying host operating system has sufficient resources in addition to those allocated for Collabora Online. Running other services (like Nextcloud itself, databases, web servers) on the same machine requires careful resource planning.
Insufficient resources will lead to slow loading times, unresponsive editing, and potentially crashes of the loolkit
processes.
Workshop Basic Installation (Docker)
This workshop guides you through installing Collabora Online CODE using the official Docker image. This is the simplest and most recommended way to get started.
Goal: Run a basic CODE instance accessible on your local server.
Prerequisites:
- A Linux server with Docker installed and running.
- Sudo/root privileges.
- Internet connection to download the Docker image.
Steps:
-
Pull the Docker Image: Open a terminal on your server and download the latest CODE image from Docker Hub:
This command fetches the image layers. It might take a few minutes depending on your internet speed. -
Run the CODE Container: Now, start the container. We need to expose the default port
9980
and provide the domain name of the frontend application (like Nextcloud) that will be allowed to connect. Replacenextcloud\.example\.com
with the actual domain name of your Nextcloud instance (or the domain you plan to use). Crucially, you need to escape the dots (.
) with backslashes (\
) because this is treated as a regular expression. If your Nextcloud runs oncloud.mydomain.org
, usecloud\.mydomain\.org
. If you are just testing locally without a real domain yet, you might use the server's IP address, escaping the dots (e.g.,192\.168\.1\.100
).sudo docker run -t -d -p 127.0.0.1:9980:9980 \ -e "domain=nextcloud\.example\.com" \ --restart always \ --cap-add MKNOD \ --name code \ collabora/code:latest
Explanation of options:
-t
: Allocate a pseudo-TTY.-d
: Run the container in detached mode (in the background).-p 127.0.0.1:9980:9980
: Map port9980
inside the container to port9980
on the host machine's localhost interface only. This is a security measure for now; we only want local access until we set up a reverse proxy. If you need access from other machines without a reverse proxy (not recommended for production), you might use-p 9980:9980
.-e "domain=nextcloud\.example\.com"
: Set thedomain
environment variable. This is crucial. It tellsloolwsd
which WOPI client domains are allowed to connect. It's a regular expression, hence the escaped dots. You can allow multiple domains using a pipe|
character, e.g.,"domain=cloud\.example\.com|office\.example\.com"
.--restart always
: Automatically restart the container if it stops or if the server reboots.--cap-add MKNOD
: Required byloolwsd
to create device nodes within its chroot jail environment. This capability allows the container process to create special files using themknod
system call, which is necessary for the sandboxing mechanism (loolforkit
) to function correctly.--name code
: Assign a convenient name (code
) to the container for easier management (e.g.,docker logs code
,docker stop code
).collabora/code:latest
: The image to use.
-
Verify Container Status: Check if the container is running:
You should see an entry for thecode
container with status "Up". -
Check Container Logs: View the initial logs to ensure there are no immediate errors:
Look for lines indicatingwsd
(the web service daemon) has started successfully and is listening on port 9980. You might see lines likewsd-000xx-000xx [ loolwsd ] INFO Initialized WOPI storage.
orwsd-000xx-000xx [ loolwsd ] INFO Listening on IPv4 address [::]:9980
. (Note:[::]
indicates it's listening on all interfaces inside the container, but our-p 127.0.0.1:9980:9980
restricts host access to localhost). -
Access Basic Admin Consoles (Optional but Recommended): Even without a frontend connected, CODE provides some endpoints for basic checks. Since we bound it to
127.0.0.1
, you need to access these from the server itself, for example usingcurl
:-
Discovery URL: This XML file tells potential WOPI clients about CODE's capabilities.
You should see XML output describing supported file types and actions. -
Admin Console: CODE has a basic admin interface.
You should get HTML output. To view this properly, you'd typically access it through a browser via a reverse proxy later. For now, getting any HTML back confirms the service is responding. -
Health Check: A simple health check endpoint.
You should see anok
response.
-
Outcome: You now have a running Collabora Online CODE container on your server, listening on port 9980 of the localhost interface, and configured to allow connections only from the domain specified in the domain
environment variable. It's ready to be integrated with a frontend application.
Integrating with Nextcloud/ownCloud (Basic)
Collabora Online doesn't function standalone for users; it needs a frontend file management system that acts as a WOPI client. Nextcloud and ownCloud are the most popular choices for this integration.
Conceptual Overview (WOPI Protocol)
The integration relies on the WOPI (Web Application Open Platform Interface) protocol. Think of it as a standardized language that allows a file server (like Nextcloud) to communicate with an office editing server (like Collabora Online).
Here's a simplified breakdown:
- Discovery: Nextcloud needs to know where Collabora Online is and what it can do. It fetches the
/hosting/discovery
XML file from Collabora. - User Action: A user in Nextcloud clicks on a document (e.g.,
mydocument.docx
). - Generate WOPI Token & URL: Nextcloud generates a unique, short-lived access token specific to that user and that document. It then constructs a special URL containing:
- The Collabora server's editing endpoint (e.g.,
https://collabora.example.com/loleaflet/dist/loleaflet.html
). - A
WOPISrc
parameter pointing back to a unique URL on the Nextcloud server for that specific file. - An
access_token
parameter containing the generated token.
- The Collabora server's editing endpoint (e.g.,
- Redirect User: Nextcloud redirects the user's browser to this constructed URL.
- Collabora Loads: The user's browser connects to Collabora Online. Collabora's JavaScript (
loleaflet.html
) uses theWOPISrc
URL andaccess_token
to make calls back to Nextcloud (e.g., "CheckFileInfo", "GetFile"). - Nextcloud Validates: Nextcloud receives these calls, validates the
access_token
, and provides Collabora with the file contents or information requested. - Editing Session: Collabora establishes the WebSocket connection for the editing session. Changes are sent back to Nextcloud using WOPI "PutFile" requests.
The key takeaway is that Collabora never directly accesses Nextcloud's file system. All interaction happens via these WOPI API calls, secured by the access token.
Installing the Connector App
Both Nextcloud and ownCloud require a specific "connector" application to enable the WOPI integration.
- For Nextcloud: Navigate to "Apps" -> "Office & text". Find the "Nextcloud Office" app (which bundles the Collabora Connector) and click "Download and enable".
- For ownCloud: Navigate to "Market" -> "Tools". Find the "Collabora Online" app and click "Install".
Basic Configuration (URL)
Once the connector app is enabled, you need to tell Nextcloud/ownCloud where your Collabora Online server is running.
- For Nextcloud: Go to "Administration settings" -> "Nextcloud Office".
- For ownCloud: Go to "Settings" -> "Admin" -> "Additional".
In the relevant section, you will find a field asking for the "URL (and port) of Collabora Online server".
You need to enter the URL that Nextcloud can use to reach your Collabora server. Crucially, this must match what Collabora expects based on its configuration (like the domain
variable and reverse proxy setup, which we'll cover later).
For our basic workshop setup where Collabora is running on http://127.0.0.1:9980
and only accessible from the server itself, direct integration isn't usually possible unless Nextcloud is also running on the exact same server and can access 127.0.0.1:9980
.
The next workshop demonstrates this, assuming a local Nextcloud instance for simplicity. In real-world scenarios, you'll almost always use a reverse proxy, which we'll configure in the Intermediate section.
Workshop Basic Integration
This workshop demonstrates integrating the locally running CODE container (from the previous workshop) with a Nextcloud instance running on the same server. This is primarily for testing the basic connection.
Goal: Connect Nextcloud to the local CODE container and test opening a document.
Prerequisites:
- Collabora Online CODE running locally, listening on
127.0.0.1:9980
(as per the previous workshop). - A Nextcloud instance installed and accessible on the same server. For testing, this could be a Docker-based Nextcloud or a manual installation accessible via
http://localhost
orhttp://<server_IP>
. - The
domain=
parameter used when starting the CODE container must match the domain/IP Nextcloud uses to identify itself (e.g., if Nextcloud is accessed viahttp://192.168.1.100
, the CODE container should have been started withdomain=192\.168\.1\.100
). If they don't match, stop the CODE container (sudo docker stop code
), remove it (sudo docker rm code
), and restart it with the correct-e "domain=..."
value.
Steps:
- Access Nextcloud: Log in to your Nextcloud instance as an administrator.
- Install Nextcloud Office App:
- Go to "Apps" (click your user icon in the top right).
- Navigate to the "Office & text" category.
- Find "Nextcloud Office" and click "Download and enable". Wait for the installation to complete.
-
Configure Collabora Server URL:
- Go to "Administration settings" (click your user icon).
- In the left sidebar under "Administration", click "Nextcloud Office".
- Select "Use your own server".
- In the "URL (and port) of Collabora Online server" field, enter:
http://127.0.0.1:9980
- Click "Save". Nextcloud will attempt to connect to this URL to verify the setup. It should show a success message like "Collabora Online server is reachable." If it fails, double-check:
- Is the CODE container running (
docker ps
)? - Is it listening on
127.0.0.1:9980
? - Are Nextcloud and CODE running on the same machine?
- Check CODE logs (
docker logs code
) for connection attempt errors (e.g., "Unauthorized WOPI host"). This usually means thedomain=
parameter in yourdocker run
command doesn't match how Nextcloud identifies itself.
- Is the CODE container running (
-
Test Document Editing:
- Navigate to "Files" in Nextcloud.
- Click the "+" button -> "New document" (or "New spreadsheet", "New presentation"). Give it a name (e.g.,
Test.docx
). - Click on the newly created file.
- If the integration is working, the Collabora Online interface should load within Nextcloud, allowing you to edit the document.
- Type some text, wait a few seconds for the "Saving..." and "Saved" indicators (usually a checkmark icon).
- Close the document tab/window.
- Re-open the document to verify your changes were saved.
Outcome: You have successfully integrated a local Nextcloud instance with a local Collabora Online CODE container. You can now create and collaboratively edit documents directly within Nextcloud, albeit without the security and accessibility benefits of a proper reverse proxy and SSL setup. This confirms the basic WOPI communication is functional.
2. Intermediate Level
Now that you have a basic understanding and a functional local setup, we'll move on to more robust and realistic configurations. This involves setting up a reverse proxy for secure access, enabling SSL/TLS encryption, and exploring more advanced configuration options within Collabora Online.
Reverse Proxy Setup (Nginx/Apache)
Running Collabora Online directly exposed to the internet or even just your local network on port 9980 is not recommended for several reasons:
- Security: Exposes the Collabora service directly, increasing the attack surface.
- SSL/TLS Encryption: Collabora Online can handle SSL itself, but managing certificates directly within the container is cumbersome and less flexible. Centralizing SSL termination at the reverse proxy is standard practice.
- Port Conflicts: Only one application can listen on standard ports 80 (HTTP) and 443 (HTTPS). A reverse proxy allows multiple web services (Nextcloud, Collabora, websites, etc.) to coexist behind a single public IP address and standard ports.
- Load Balancing: Reverse proxies are the foundation for distributing traffic across multiple Collabora instances for scalability (covered in Advanced).
- URL Rewriting/Path Handling: Allows cleaner URLs and maps external paths to internal services.
A reverse proxy acts as an intermediary server. It receives requests from clients (like web browsers or the Nextcloud server), forwards those requests to the appropriate backend service (Collabora Online on port 9980), and relays the backend's response back to the client.
We will cover configurations for two popular web servers often used as reverse proxies: Nginx and Apache.
Configuring Nginx for Collabora
Nginx is a high-performance web server frequently used as a reverse proxy. Configuration typically involves creating a server
block in your Nginx configuration files (often within /etc/nginx/sites-available/
).
Key Nginx Directives:
server_name
: Defines the domain name this block applies to (e.g.,collabora.example.com
).listen
: Specifies the port to listen on (80 for HTTP, 443 for HTTPS).ssl_certificate
,ssl_certificate_key
: Paths to your SSL certificate and private key files (for HTTPS).location /
: Defines how to handle requests for the root path and potentially subpaths.proxy_pass
: The core directive that forwards requests to the backend Collabora service (e.g.,http://127.0.0.1:9980
).proxy_set_header
: Modifies or adds HTTP headers sent to the backend. Essential for passing information like the original host, client IP, and protocol.- WebSocket Support: Collabora relies heavily on WebSockets for real-time communication. Nginx needs specific directives to correctly proxy WebSocket connections:
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_read_timeout 3600s;
(or longer, to prevent premature disconnection)
Example Nginx Configuration Snippet (HTTPS):
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name collabora.example.com; # Your Collabora domain
# SSL configuration
ssl_certificate /etc/letsencrypt/live/collabora.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/collabora.example.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf; # Recommended SSL parameters
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # Diffie-Hellman parameters
# static files
location ^~ /loleaflet {
proxy_pass http://127.0.0.1:9980; # Collabora backend
proxy_set_header Host $http_host; # Use $http_host NOT $host with proxy_pass
}
# WOPI discovery URL
location ^~ /hosting/discovery {
proxy_pass http://127.0.0.1:9980;
proxy_set_header Host $http_host;
}
# Main websocket channel (loolwsd)
# Note: Ensure your Nginx version is >= 1.4 for WebSocket proxying
location ^~ /lool {
proxy_pass http://127.0.0.1:9980;
proxy_set_header Host $http_host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 3600s; # Set higher timeout for long editing sessions
}
# Admin Console websocket channel (loolwsd)
location ^~ /lool/adminws {
proxy_pass http://127.0.0.1:9980;
proxy_set_header Host $http_host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 3600s;
}
# Optional: Add security headers
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Content-Type-Options nosniff;
add_header X-Frame-Options SAMEORIGIN;
add_header X-XSS-Protection "1; mode=block";
add_header Referrer-Policy "no-referrer"; # Adjust if needed
}
# Optional: Redirect HTTP to HTTPS
server {
listen 80;
listen [::]:80;
server_name collabora.example.com;
location / {
return 301 https://$host$request_uri;
}
}
Remember to replace collabora.example.com
and the proxy_pass
target (127.0.0.1:9980
) if your setup differs.
Configuring Apache for Collabora
Apache httpd can also function as a reverse proxy using modules like mod_proxy
, mod_proxy_http
, and crucially, mod_proxy_wstunnel
for WebSocket support. Configuration is typically done within a VirtualHost
block.
Key Apache Modules:
mod_proxy
: Core proxy functionality.mod_proxy_http
: Proxying HTTP requests.mod_proxy_wstunnel
: Proxying WebSocket connections (essential!).mod_ssl
: For handling HTTPS.mod_headers
: For manipulating HTTP headers.mod_rewrite
: Often used for conditional proxying or URL manipulation.
Example Apache Configuration Snippet (HTTPS):
<VirtualHost *:443>
ServerName collabora.example.com
# SSL Configuration
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/collabora.example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/collabora.example.com/privkey.pem
# Include recommended SSL settings if available, e.g., from Let's Encrypt/Certbot
# Include /etc/letsencrypt/options-ssl-apache.conf
# Proxy Basic Settings
ProxyPreserveHost On
ProxyRequests Off # Crucial for security: Off means Reverse Proxy mode
# AllowEncodedSlashes NoDecode needed for WOPI URLs
AllowEncodedSlashes NoDecode
# Proxy WebSocket setup for /lool endpoint
ProxyPass /lool ws://127.0.0.1:9980/lool retry=0
ProxyPassReverse /lool ws://127.0.0.1:9980/lool retry=0
# Proxy WebSocket setup for /lool/adminws endpoint (Admin Console)
ProxyPass /lool/adminws ws://127.0.0.1:9980/lool/adminws retry=0
ProxyPassReverse /lool/adminws ws://127.0.0.1:9980/lool/adminws retry=0
# Proxy all other requests for Collabora static files and discovery
ProxyPass / http://127.0.0.1:9980/ retry=0
ProxyPassReverse / http://127.0.0.1:9980/ retry=0
# Set timeouts to handle long connections
ProxyTimeout 3600
# Optional: Add security headers
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
Header always set X-Content-Type-Options "nosniff"
Header always set X-Frame-Options "SAMEORIGIN"
Header always set Referrer-Policy "no-referrer"
Header always set X-XSS-Protection "1; mode=block"
</VirtualHost>
# Optional: Redirect HTTP to HTTPS
<VirtualHost *:80>
ServerName collabora.example.com
Redirect permanent / https://collabora.example.com/
</VirtualHost>
Remember to enable the necessary Apache modules (a2enmod proxy proxy_http proxy_wstunnel ssl headers rewrite
) and adjust domain names and the backend URL.
SSL/TLS Termination (Let's Encrypt)
Securing the connection between the user's browser and your Collabora instance is paramount. HTTPS encrypts the traffic, preventing eavesdropping. Terminating SSL at the reverse proxy means the proxy handles the encryption/decryption, and the connection between the proxy and the Collabora container can be plain HTTP (if they are on the same secure host or network).
Let's Encrypt is a free, automated, and open Certificate Authority (CA) that provides SSL/TLS certificates. The easiest way to obtain and manage Let's Encrypt certificates is using the Certbot client.
Using Certbot:
- Install Certbot: Follow the official Certbot instructions for your OS and web server (Nginx/Apache): https://certbot.eff.org/
- Obtain Certificate: Certbot can often automatically obtain the certificate and configure your web server.
- For Nginx:
sudo certbot --nginx -d collabora.example.com
- For Apache:
sudo certbot --apache -d collabora.example.com
- Alternatively, obtain only the certificate:
sudo certbot certonly --webroot -w /var/www/html -d collabora.example.com
(adjust webroot path) orsudo certbot certonly --standalone -d collabora.example.com
(requires temporarily stopping your web server).
- For Nginx:
- Auto-Renewal: Certbot typically sets up automatic renewal via a systemd timer or cron job. Verify this with
sudo systemctl list-timers
orsudo crontab -l
.
Once you have the certificate files (usually in /etc/letsencrypt/live/yourdomain.com/
), you reference them in your Nginx/Apache SSL configuration directives as shown in the examples above.
Workshop Secure Access with Reverse Proxy and SSL
This workshop guides you through setting up Nginx as a reverse proxy for your Collabora Online container, securing it with a Let's Encrypt SSL certificate.
Goal: Make Collabora Online accessible via HTTPS on a dedicated subdomain (e.g., https://collabora.example.com
), with Nginx handling SSL termination.
Prerequisites:
- Collabora Online CODE running in Docker, listening on
127.0.0.1:9980
. - A registered domain name (e.g.,
example.com
). - DNS configured: An
A
record for a subdomain (e.g.,collabora.example.com
) pointing to your server's public IP address. - Nginx installed on your server.
- Certbot installed on your server.
- Ports 80 and 443 open on your server's firewall.
- Sudo/root privileges.
Steps:
-
Stop and Remove Existing CODE Container (If Necessary): If your previous CODE container was bound publicly or had SSL enabled internally, it's best to reconfigure it for proxying. Ensure the
domain=
variable used previously still correctly reflects your Nextcloud domain. We need to add options to disable internal SSL handling and tell it SSL is terminated externally. -
Restart CODE Container for Proxying: Restart the container, ensuring it listens only on
127.0.0.1
and adding thessl.enable=false
andssl.termination=true
parameters via theextra_params
environment variable. Replacenextcloud\.example\.com
with your actual Nextcloud domain (dots escaped).sudo docker run -t -d -p 127.0.0.1:9980:9980 \ -e "domain=nextcloud\.example\.com" \ -e "extra_params=--o:ssl.enable=false --o:ssl.termination=true" \ --restart always \ --cap-add MKNOD \ --name code \ collabora/code:latest
-e "extra_params=--o:ssl.enable=false --o:ssl.termination=true"
: These crucial parameters tellloolwsd
not to handle SSL itself but to expect the reverse proxy to do it.
-
Obtain SSL Certificate with Certbot: Use Certbot to get a certificate for your Collabora subdomain. Using the Nginx plugin is often easiest if Nginx is already installed. Replace
Follow the prompts. Certbot will ask about email registration and agreeing to terms. It should detect your domain, obtain the certificate, and offer to configure Nginx automatically (usually creating or modifying the SSL parts of the server block). Choose the option to redirect HTTP to HTTPS if prompted.collabora.example.com
with your chosen subdomain. -
Configure Nginx Reverse Proxy: Certbot might have created a basic configuration. You need to ensure it includes the necessary
proxy_pass
and WebSocket settings for Collabora. Edit the Nginx configuration file for your site (often/etc/nginx/sites-available/collabora.example.com
or/etc/nginx/conf.d/collabora.conf
, depending on your setup and Certbot's actions).Make sure your
server
block for port 443 looks similar to the Nginx example provided earlier, specifically including:- Correct
server_name
. - Correct
ssl_certificate
andssl_certificate_key
paths (Certbot usually sets these). - The
location
blocks for/loleaflet
,/hosting/discovery
,/lool
, and/lool/adminws
with the correctproxy_pass http://127.0.0.1:9980;
directive and WebSocket headers for the/lool
locations.
Example Snippet to Ensure is Present/Correct within the
server { listen 443 ssl ... }
block:# static files location ^~ /loleaflet { proxy_pass http://127.0.0.1:9980; proxy_set_header Host $http_host; } # WOPI discovery URL location ^~ /hosting/discovery { proxy_pass http://127.0.0.1:9980; proxy_set_header Host $http_host; } # Main websocket channel (loolwsd) location ^~ /lool { proxy_pass http://127.0.0.1:9980; proxy_set_header Host $http_host; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_read_timeout 3600s; # Important for stability proxy_buffering off; # Useful for WebSockets } # Admin Console websocket channel (loolwsd) location ^~ /lool/adminws { proxy_pass http://127.0.0.1:9980; proxy_set_header Host $http_host; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_read_timeout 3600s; proxy_buffering off; }
- Correct
-
Test Nginx Configuration and Reload: Always test your Nginx configuration before applying it:
If it reports "syntax is ok" and "test is successful", reload Nginx to apply the changes: -
Update Nextcloud Configuration:
- Go back to your Nextcloud instance -> Administration settings -> Nextcloud Office.
- Change the "URL (and port) of Collabora Online server" to your new HTTPS URL:
https://collabora.example.com
(no port number needed as it's standard HTTPS port 443). - Click "Save". Nextcloud should confirm that the server is reachable via the new secure URL.
-
Test Access and Editing:
- Try accessing
https://collabora.example.com/hosting/discovery
in your browser. You should see the XML file. - Try accessing
https://collabora.example.com/loleaflet/dist/admin/admin.html
. You should see the admin login page (though you likely don't have credentials configured yet). - Go to Nextcloud -> Files and try opening or creating an office document. It should load successfully via the secure reverse proxy connection. Check your browser's address bar and security indicators to confirm HTTPS is active.
- Try accessing
Outcome: You have successfully configured Nginx as a reverse proxy for Collabora Online, secured the connection with Let's Encrypt SSL/TLS, and updated Nextcloud to use the secure endpoint. Your Collabora setup is now significantly more secure and accessible.
Advanced Configuration Options
While environment variables cover basic settings, Collabora Online's behavior is primarily controlled by an XML configuration file, typically loolwsd.xml
. When using Docker, you can override settings using environment variables (like extra_params
we used) or by mounting a custom loolwsd.xml
file into the container. For more extensive customization, using a custom file is often cleaner.
loolwsd.xml
Overview
The default loolwsd.xml
file resides within the container, usually at /etc/loolwsd/loolwsd.xml
. It contains numerous sections controlling various aspects of the service.
Key Sections:
<server_name>
: The hostname the server identifies as. Should match the public URL.<storage desc="Backend storage">
: Contains information about allowed WOPI hosts (<host>
). This is where thedomain
environment variable typically injects its value. You can manually list allowed host regex patterns here.<storage desc="Backend storage"> <filesystem allow="false"/> <!-- Usually false, rely on WOPI --> <wopi desc="Allow/deny wopi storage. Mutually exclusive with webdav." allow="true"> <!-- List of regex patterns for allowed WOPI hosts (e.g., Nextcloud domain) --> <host allow="true">nextcloud\.example\.com</host> <host allow="true">192\.168\.1\. S+$</host> <!-- Example: Allow local subnet --> <!-- <host allow="false">.*</host> --> <!-- Optional: Explicitly deny others --> </wopi> <!-- ... other storage options like webdav ... --> </storage>
<net desc="Network settings">
: Controls listening interfaces, allowed connection addresses, and SSL settings (if handled internally).<listen>
: Typicallyall
or specific IPs.<connection_idle_timeout_secs>
: How long idle connections are kept.<allowed_connect_hosts>
: Which IPs can connect directly toloolwsd
(important if not using a loopback proxy pass).
<ssl desc="SSL settings">
: Configures SSL if handled byloolwsd
. Theenable
andtermination
attributes are key here. When using a reverse proxy for SSL, these should befalse
andtrue
, respectively.<ssl desc="SSL settings"> <enable type="bool" default="true">false</enable> <!-- Set to false when using reverse proxy for SSL --> <termination type="bool" default="true">true</termination> <!-- Set to true when using reverse proxy for SSL --> <!-- cert_file_path, key_file_path, ca_file_path are ignored if enable=false --> </ssl>
<logging>
: Configures log levels (trace
,debug
,info
,warning
,error
,critical
) and output locations.<logging> <level type="string" default="warning">info</level> <!-- e.g., change to info or debug --> <file enable="true"> <property name="path" desc="Log file path.">[REMOVED]/loolwsd.log</property> <!-- Other log file properties --> </file> <console enable="false" /> <!-- Logs go to file/syslog, not usually console in container --> </logging>
<per_document>
: Controls resource limits per document instance (loolkit
).<max_concurrency>
: Max threads per document.<idle_timeout_secs>
: How long an inactive document stays loaded.<inactive_timeout_secs>
: How long an unused document (no viewers) stays loaded.
<per_view>
: Controls limits per active view/connection.<admin_console>
: Configuration for the admin console (/loleaflet/dist/admin/admin.html
), including authentication.<admin_console desc="Admin console settings"> <enable type="bool" default="true">true</enable> <username desc="Admin username" type="string" default="admin">your_admin_user</username> <password desc="Admin password" type="string" default="admin">your_secure_password</password> <!-- ... other settings ... --> </admin_console>
<branding>
: Allows basic customization like changing logos and welcome messages (requires preparing image files).
Modifying loolwsd.xml
with Docker
To use a custom configuration file:
- Extract the Default: Copy the default file from a running container:
- Edit: Modify
my_loolwsd.xml
using your text editor. - Mount: Stop the container and restart it, mounting your custom file read-only:
(Note: Using
sudo docker stop code sudo docker rm code # Start command modified to mount the file sudo docker run -t -d -p 127.0.0.1:9980:9980 \ -v $(pwd)/my_loolwsd.xml:/etc/loolwsd/loolwsd.xml:ro \ # -e options are less critical now as settings are in the file, but domain can still be useful -e "domain=nextcloud\.example\.com" \ # No need for extra_params if SSL settings are correct in the XML --restart always \ --cap-add MKNOD \ --name code \ collabora/code:latest
-v $(pwd)/my_loolwsd.xml...
assumesmy_loolwsd.xml
is in your current directory. Use the full path if needed). The:ro
makes the mount read-only inside the container, which is good practice for configuration files.
Changes in the mounted loolwsd.xml
require a container restart (docker restart code
) to take effect.
Workshop Customizing Basic Settings
This workshop demonstrates how to modify the loolwsd.xml
configuration file to change the logging level and set admin console credentials.
Goal: Increase log verbosity for debugging and secure the admin console with a custom username and password.
Prerequisites:
- A running Collabora Online CODE container managed via Docker (ideally behind the reverse proxy set up previously).
- Sudo/root privileges.
- Access to the server's command line.
Steps:
-
Extract Default Configuration: If you don't already have it, copy the default
loolwsd.xml
from your running container: -
Edit
my_loolwsd.xml
: Open the copied filemy_loolwsd.xml
in a text editor (e.g.,nano my_loolwsd.xml
).-
Change Log Level: Locate the
<logging>
section. Find the<level>
tag. Change its content fromwarning
(or whatever the default is) toinfo
ordebug
.info
provides more general operational details, whiledebug
is very verbose. Let's useinfo
for now. -
Set Admin Credentials: Locate the
<admin_console>
section. Find the<username>
and<password>
tags. Change their content to your desired secure credentials. Choose strong, unique values.<admin_console desc="Admin console settings"> <enable type="bool" default="true">true</enable> <username desc="Admin username" type="string" default="admin">mycooladmin</username> <password desc="Admin password" type="string" default="admin">MySuperSecretP@ssw0rd!</password> <!-- ... rest of admin_console section ... --> </admin_console>
-
Verify SSL Settings (Crucial): While editing, double-check the
<ssl>
section. Ensure<enable>
isfalse
and<termination>
istrue
, as required for our reverse proxy setup. -
Verify Allowed Hosts (Crucial): Check the
<storage><wopi><host>
entries. Ensure the regex pattern correctly matches your Nextcloud domain(s). Using thedomain
environment variable often handles this, but if you rely solely on the XML, it must be correct here.
Save the changes and exit the editor.
-
-
Stop and Remove the Old Container:
-
Start New Container with Mounted Config: Use the
docker run
command, adding the-v
option to mount your modifiedmy_loolwsd.xml
. Make sure the path tomy_loolwsd.xml
is correct (using$(pwd)
works if it's in the current directory).# Assuming my_loolwsd.xml is in the current directory sudo docker run -t -d -p 127.0.0.1:9980:9980 \ -v $(pwd)/my_loolwsd.xml:/etc/loolwsd/loolwsd.xml:ro \ # You might still include -e "domain=..." as a fallback or for clarity -e "domain=nextcloud\.example\.com" \ # No need for extra_params for SSL if set in XML --restart always \ --cap-add MKNOD \ --name code \ collabora/code:latest
-
Verify Changes:
- Check Logs: Wait a minute for the container to start fully, then check the logs:
You should now see more detailed logs (INFO level) compared to the default
warning
level. Look for lines explicitly marked[ loolwsd ] INFO ...
. - Test Admin Console: Open your browser and navigate to the admin console URL via your reverse proxy:
https://collabora.example.com/loleaflet/dist/admin/admin.html
. You should now be prompted for a username and password. Enter the credentials you set inmy_loolwsd.xml
(mycooladmin
andMySuperSecretP@ssw0rd!
in our example). You should gain access to the admin dashboard. - Test Document Editing: Ensure document editing in Nextcloud still works correctly. This confirms that the core functionality wasn't broken by the configuration changes.
- Check Logs: Wait a minute for the container to start fully, then check the logs:
You should now see more detailed logs (INFO level) compared to the default
Outcome: You have successfully customized Collabora Online's behavior using the loolwsd.xml
file, specifically changing the log level and securing the admin console. You now have a method for applying more fine-grained configuration adjustments.
3. Advanced Level
This section delves into scaling your Collabora Online deployment for more users, ensuring high availability, implementing monitoring, and tackling common troubleshooting scenarios. These topics are crucial for running a reliable service for larger groups or organizations.
Scaling Collabora Online
The single CODE container setup, while simple, has limitations. As the number of concurrent documents and users grows, a single instance will become a bottleneck, primarily limited by CPU and RAM. Scaling involves distributing the load across multiple Collabora Online instances.
Understanding Limitations
- Vertical Scaling: Increasing the CPU cores and RAM allocated to the single CODE server/container. This is the simplest approach but has physical/virtual limits and becomes expensive.
- Horizontal Scaling: Adding more identical CODE instances (running on the same or different physical/virtual machines) and distributing incoming connections among them using a load balancer. This is generally more flexible and cost-effective for significant growth.
Collabora Online itself is largely stateless regarding user sessions (session information is managed, but document data resides in the WOPI host like Nextcloud). This makes it well-suited for horizontal scaling.
Horizontal Scaling Concepts
The core idea is:
- Deploy Multiple Instances: Set up two or more identical CODE containers/servers. They should have the same configuration (
loolwsd.xml
or equivalent environment variables), particularly the allowed WOPI hosts (domain=...
) and SSL settings (expecting termination at the proxy/balancer). Each instance will listen on its own internal IP/port (e.g.,192.168.1.10:9980
,192.168.1.11:9980
, or on the same machine127.0.0.1:9980
,127.0.0.1:9981
). - Introduce a Load Balancer: Place a load balancer in front of the CODE instances. This load balancer becomes the single entry point that your frontend (Nextcloud) and reverse proxy (if separate) point to. Its job is to distribute incoming connections across the available CODE instances.
- Configure Integration: Update your Nextcloud/ownCloud settings and your main reverse proxy (if the load balancer isn't also handling external SSL/proxying) to point to the load balancer's address instead of a single CODE instance.
Load Balancing Strategies
Load balancers use different algorithms to decide which backend server gets the next request:
- Round Robin: Distributes connections sequentially to each server in the pool (Server1, Server2, Server3, Server1, ...). Simple but doesn't account for server load.
- Least Connections: Sends the next connection to the server currently handling the fewest active connections. Generally better for long-lived connections like Collabora's WebSockets, as it balances based on actual load.
- IP Hash: Assigns a client to a specific server based on their IP address. This ensures a user consistently hits the same backend, which can sometimes be helpful but might lead to uneven load distribution. Less ideal for Collabora unless specific session persistence issues arise (which are uncommon).
- Weighted Variations: Allows assigning weights to servers (e.g., send twice as much traffic to a more powerful server).
For Collabora, Least Connections is often the preferred strategy.
Setting up Multiple CODE Instances
Using Docker, you can easily launch multiple instances on the same host by mapping them to different host ports:
- Instance 1 (already running):
docker run ... -p 127.0.0.1:9980:9980 ... --name code1 ...
- Instance 2:
docker run ... -p 127.0.0.1:9981:9980 ... --name code2 ...
(Note the host port9981
) - Instance 3:
docker run ... -p 127.0.0.1:9982:9980 ... --name code3 ...
If running on different hosts, each would typically listen on 127.0.0.1:9980
(or 0.0.0.0:9980
if the load balancer is on a separate machine) within its own environment, and the load balancer would use the distinct host IPs (e.g., 192.168.1.10:9980
, 192.168.1.11:9980
).
Using a Dedicated Load Balancer (HAProxy/Nginx)
Both Nginx and dedicated load balancers like HAProxy can perform this role.
-
Nginx as Load Balancer: Nginx can load balance using an
upstream
block.In this setup, Nginx acts as both the SSL termination point/reverse proxy and the load balancer. Requests to# Define the pool of backend Collabora servers upstream collabora_backends { # least_conn; # Use Least Connections algorithm ip_hash; # Use IP Hash for session persistence if needed server 127.0.0.1:9980; # Instance 1 server 127.0.0.1:9981; # Instance 2 # Add more servers as needed } server { listen 443 ssl http2; server_name collabora.example.com; # Public facing domain # SSL configuration... (as before) # Proxy requests to the upstream group location / { proxy_pass http://collabora_backends; # Pass to the upstream group # WebSocket headers NEEDED here too! proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_read_timeout 3600s; proxy_buffering off; # Recommended for WebSockets } }
collabora.example.com
are distributed to the servers defined in thecollabora_backends
upstream block. -
HAProxy: A popular, high-performance, dedicated load balancer. Configuration (usually in
/etc/haproxy/haproxy.cfg
) might look like:HAProxy handles SSL and load balancing, forwarding traffic to the backend CODE instances. Note the use of health checks (frontend collabora_frontend bind *:443 ssl crt /etc/letsencrypt/live/collabora.example.com/combined.pem # Path to combined cert+key mode http option httplog # Redirect HTTP to HTTPS if needed # redirect scheme https if !{ ssl_fc } default_backend collabora_backend backend collabora_backend mode http balance leastconn # Use Least Connections # Use cookie for persistence if needed, but often not required for Collabora # cookie SERVERID insert indirect nocache option forwardfor # Pass client IP # Health checks to ensure servers are up option httpchk GET /lool/healthz HTTP/1.1\r\nHost:\ collabora.example.com http-check expect status 200 server code1 127.0.0.1:9980 check # Instance 1 server code2 127.0.0.1:9981 check # Instance 2 # Add more servers # Define timeouts timeout connect 5s timeout server 3600s # Long timeout for editing timeout client 3600s
check
andoption httpchk
) to automatically remove unresponsive instances from the pool.
Workshop Setting up a Load-Balanced Collabora Cluster
This workshop guides you through setting up two CODE instances on the same host and using Nginx to load balance traffic between them.
Goal: Create a small, horizontally scaled Collabora cluster load balanced by Nginx.
Prerequisites:
- A working single CODE instance behind an Nginx reverse proxy with SSL (as per the Intermediate workshop).
- Nginx installed and configured for the single instance.
- Docker installed.
- Sudo/root privileges.
- Enough server resources (CPU/RAM) to comfortably run two CODE instances plus Nginx and the OS. (~4+ cores, 4-6GB+ RAM free for Collabora).
Steps:
-
Prepare Configuration (If Using XML): If you are using a custom
my_loolwsd.xml
, ensure it's suitable for both instances (especially allowed hosts and SSL settings:enable=false
,termination=true
). No instance-specific changes should be needed in the XML itself. -
Stop Existing Single Instance: Stop the current
code
container. We'll rename it for clarity. -
Launch First CODE Instance (code1): Launch the first instance, naming it
code1
and ensuring it listens on127.0.0.1:9980
. Use either environment variables or your mounted XML file for configuration.Using environment variables:
Using mounted XML: -
Launch Second CODE Instance (code2): Launch the second instance similarly, but name it
code2
and map it to a different host port, e.g.,127.0.0.1:9981
.Using environment variables:
Using mounted XML: -
Verify Both Instances Running:
You should see bothcode1
(mapping127.0.0.1:9980->9980/tcp
) andcode2
(mapping127.0.0.1:9981->9980/tcp
) listed and running. -
Configure Nginx for Load Balancing: Edit your Nginx site configuration file for
collabora.example.com
.- Add
upstream
block: Before theserver
block, define the upstream group: -
Modify
proxy_pass
: Inside theserver { ... }
block, find alllocation
blocks that currently haveproxy_pass http://127.0.0.1:9980;
. Change the target tohttp://collabora_backends;
. This includes locations/
,/loleaflet
,/hosting/discovery
,/lool
,/lool/adminws
.Example change for
/lool
:Apply this change to alllocation ^~ /lool { # proxy_pass http://127.0.0.1:9980; # OLD line proxy_pass http://collabora_backends; # NEW line # Keep WebSocket and other headers! proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; # ... other headers if you have them ... proxy_read_timeout 3600s; proxy_buffering off; }
proxy_pass
directives pointing to the old single instance.
- Add
-
Test Nginx Configuration and Reload:
-
Test Load Balancing and Failover:
- Basic Functionality: Open Nextcloud and edit a document. It should work seamlessly. You don't directly see which backend is used, but Nginx is now distributing the requests.
- Monitor Connections (Optional): Access the admin console
https://collabora.example.com/loleaflet/dist/admin/admin.html
(if you secured it, log in). Navigate to the "Analytics" or "Monitoring" section. Open a few documents. You might see connections being distributed across both instances listed (if the admin console provides such detail, or check server stats). - Simulate Failure: Stop one of the containers:
- Test Again: Immediately try opening a new document or continue editing an existing one in Nextcloud. It should still work (perhaps after a slight delay for Nginx to detect the stopped backend if it doesn't have active health checks configured in the free version). Nginx should redirect traffic to the remaining active instance (
code1
). - Restore: Start the stopped container again:
- Test Again: Functionality should remain normal. Nginx will reintegrate
code2
into the load balancing pool.
Outcome: You have successfully set up a basic horizontally scaled Collabora Online cluster with two backend instances and configured Nginx to load balance traffic between them using the least_conn
method. You've also demonstrated basic fault tolerance – the service remains available even if one backend instance fails.
High Availability Considerations
Load balancing provides scalability and some resilience, but true High Availability (HA) requires eliminating single points of failure throughout the stack.
- Load Balancer Redundancy: If your Nginx/HAProxy load balancer itself fails, the entire service goes down. For HA, you need redundant load balancers. Common techniques include:
- Keepalived + VRRP: Two identical load balancers share a Virtual IP address. Keepalived monitors the health of the primary; if it fails, the secondary takes over the Virtual IP.
- DNS Failover: Using DNS services that monitor health and automatically update DNS records to point to a secondary load balancer IP (often slower failover).
- Cloud Provider Load Balancers: Cloud platforms (AWS ELB, GCP Load Balancer, Azure Load Balancer) offer managed HA load balancing services.
- Collabora Instance Redundancy: Already addressed by having multiple instances in the load balancer pool. Ensure instances are spread across different physical hosts or availability zones if possible.
- Frontend (Nextcloud/ownCloud) Redundancy: Your file host also needs to be highly available (clustered web servers, redundant database, distributed storage like NFS/GlusterFS/Ceph). This is outside the scope of Collabora setup but critical for overall service HA.
- Network Redundancy: Redundant network switches, routers, and internet connections.
- Monitoring and Alerting: Continuous monitoring of all components (load balancers, CODE instances, frontend servers, network) is crucial to detect failures quickly. Alerting systems (e.g., Prometheus + Alertmanager, Nagios, Zabbix) should notify administrators of issues.
Implementing full HA is complex and depends heavily on the specific infrastructure and requirements.
Workshop Implementing Basic Monitoring
This workshop focuses on setting up simple monitoring for your load-balanced Collabora setup using built-in tools and a basic external health check script.
Goal: Monitor the status of individual CODE instances and the overall service availability.
Prerequisites:
- Load-balanced Collabora setup (as per the previous workshop).
- Access to the server hosting Nginx and the CODE containers.
- Admin console access for Collabora (
https://collabora.example.com/loleaflet/dist/admin/admin.html
) configured and accessible. curl
command-line tool installed.
Steps:
-
Using the Admin Console:
- Navigate to
https://collabora.example.com/loleaflet/dist/admin/admin.html
and log in. - Explore the available tabs/sections. Look for:
- Active Documents: A list of currently open documents.
- Active Users: Number of connected users.
- Server Stats: Information about memory usage, CPU load, and potentially metrics per backend instance if the load balancer passes identifying information (less common with basic Nginx setup).
- This provides a real-time snapshot but isn't persistent or automated alerting. Regularly checking this dashboard manually can help spot issues.
- Navigate to
-
Basic External Health Check Script: We can create a simple script that checks the
/lool/healthz
endpoint of each backend instance directly, bypassing the load balancer for individual checks, and also checks the main public URL.- Create the Script: Create a file named
check_collabora.sh
: -
Add Script Content: Paste the following script, adjusting URLs and ports:
#!/bin/bash # --- Configuration --- INSTANCE1_URL="http://127.0.0.1:9980/lool/healthz" INSTANCE2_URL="http://127.0.0.1:9981/lool/healthz" PUBLIC_URL="https://collabora.example.com/lool/healthz" # Check via LB/Proxy LOG_FILE="/var/log/collabora_health.log" # --- End Configuration --- TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S') STATUS_OK="ok" OVERALL_STATUS="OK" echo "[$TIMESTAMP] Starting health check..." >> $LOG_FILE # Check Instance 1 echo -n "Checking Instance 1 ($INSTANCE1_URL)... " >> $LOG_FILE RESPONSE1=$(curl -s -m 5 $INSTANCE1_URL) # -s silent, -m timeout 5s if [ "$RESPONSE1" == "$STATUS_OK" ]; then echo "OK" >> $LOG_FILE else echo "FAILED (Response: '$RESPONSE1')" >> $LOG_FILE OVERALL_STATUS="FAILED" fi # Check Instance 2 echo -n "Checking Instance 2 ($INSTANCE2_URL)... " >> $LOG_FILE RESPONSE2=$(curl -s -m 5 $INSTANCE2_URL) if [ "$RESPONSE2" == "$STATUS_OK" ]; then echo "OK" >> $LOG_FILE else echo "FAILED (Response: '$RESPONSE2')" >> $LOG_FILE OVERALL_STATUS="FAILED" fi # Check Public URL (via Load Balancer/Proxy) echo -n "Checking Public URL ($PUBLIC_URL)... " >> $LOG_FILE # Use -k if using self-signed cert for internal checks, but public should be valid RESPONSE_PUBLIC=$(curl -s -m 10 $PUBLIC_URL) if [ "$RESPONSE_PUBLIC" == "$STATUS_OK" ]; then echo "OK" >> $LOG_FILE else echo "FAILED (Response: '$RESPONSE_PUBLIC')" >> $LOG_FILE OVERALL_STATUS="FAILED" fi echo "[$TIMESTAMP] Overall Status: $OVERALL_STATUS" >> $LOG_FILE echo "--------------------------------------" >> $LOG_FILE # Optional: Add alerting logic here if status is FAILED # e.g., send email, trigger webhook, etc. if [ "$OVERALL_STATUS" == "FAILED" ]; then echo "ALERT: Collabora health check failed!" # mail -s "Collabora Health Alert" admin@example.com < $LOG_FILE fi exit 0
-
Make Executable:
-
Initial Test Run: Execute the script manually:
Check the output and the contents of/var/log/collabora_health.log
(you might needsudo tail -n 10 /var/log/collabora_health.log
). It should report "OK" for all checks if everything is running.
- Create the Script: Create a file named
-
Schedule Regular Checks (Cron Job): Automate the script to run periodically using cron.
- Edit Crontab: (Choose an editor if prompted).
- Add Cron Job: Add a line to run the script every 5 minutes. Adjust the path
/path/to/check_collabora.sh
to the actual location of your script. - Save and exit the editor. Cron will now execute your health check script every 5 minutes.
-
Simulate Failure and Check Logs:
- Stop one instance:
sudo docker stop code2
- Wait for the next cron job execution (up to 5 minutes).
- Check the log file:
sudo tail /var/log/collabora_health.log
- You should now see entries where Instance 2 reports "FAILED", and the Overall Status is "FAILED". If you added alerting, that should also trigger. The Public URL should still report "OK" as
code1
is handling the load. - Start the instance again:
sudo docker start code2
- After the next check, the logs should return to showing "OK" for all components.
- Stop one instance:
Outcome: You have implemented basic monitoring using the built-in admin console for real-time checks and an automated script that checks the health of individual instances and the public endpoint, logging the results. This provides early warnings of potential issues. For production, integrate this with a more robust monitoring system like Prometheus/Grafana or Zabbix.
Troubleshooting Common Issues
Even with careful setup, issues can arise. Here’s a breakdown of common problems and how to diagnose them.
Connection Problems ("Unable to connect", "Service Unavailable")
- Symptom: Nextcloud shows an error trying to load Collabora; accessing the Collabora URL directly fails.
- Diagnosis:
- Check CODE Container(s): Are they running? (
sudo docker ps
). Check logs (sudo docker logs code1
,sudo docker logs code2
) for startup errors or crashes. - Check Reverse Proxy/Load Balancer: Is Nginx/HAProxy running? (
sudo systemctl status nginx
). Check its error logs (/var/log/nginx/error.log
or equivalent). Look for errors related to connecting to the upstream (Collabora backend). - Firewall: Is port 443 (and 80 for redirects) open on the server firewall? Is the reverse proxy allowed to connect to the backend ports (9980, 9981) on
127.0.0.1
or the relevant internal IPs? - Network Path: Can the Nextcloud server resolve and reach the Collabora URL? From the Nextcloud server, try:
curl -v https://collabora.example.com/hosting/discovery
. Check for DNS issues or network blocks. - Nginx/Apache Config: Double-check the
proxy_pass
directives and upstream server definitions. Ensure ports and IPs are correct. Reload the service after changes (sudo systemctl reload nginx
).
- Check CODE Container(s): Are they running? (
"Unauthorized WOPI Host" Error
- Symptom: Collabora loads partially or shows an error specifically mentioning unauthorized host or domain.
- Diagnosis:
- Check CODE Logs: Look in
sudo docker logs code1
(andcode2
) for lines likeWRN WOPI::CheckFileInfo Failed. Error: Unauthorized WOPI host...
or similar permission errors. The log should mention the domain that tried to connect. - Verify
domain
Setting: Ensure thedomain=
environment variable used when starting the CODE containers (or the<host>
entries inloolwsd.xml
) contains a correct regular expression matching the domain name as Nextcloud knows it. If Nextcloud is accessed viahttps://cloud.mydomain.internal
, then thedomain=
variable needs to includecloud\.mydomain\.internal
. Remember to escape dots (.
) and use|
to separate multiple domains if needed (e.g.,domain=nextcloud\.example\.com|cloud\.mydomain\.internal
). - Restart CODE Containers: If you changed the
domain
environment variable or theloolwsd.xml
file, you must restart the CODE containers (sudo docker restart code1 code2
).
- Check CODE Logs: Look in
Performance Bottlenecks (Slow Loading, Unresponsive Editing)
- Symptom: Documents take a long time to load; typing lags; Collabora feels sluggish.
- Diagnosis:
- Server Resources: Check CPU, RAM, and Disk I/O usage on the server(s) hosting the CODE containers while the issue is occurring. Use tools like
htop
,vmstat
,iotop
. Are CPU cores maxed out? Is the system swapping heavily (low RAM)? - Container Limits: Are the Docker containers themselves resource-limited (e.g., via docker-compose
deploy
limits or cgroup settings)? - Network Latency: Check network latency between the user -> Nextcloud -> Collabora -> Nextcloud. High latency can impact responsiveness. Use
ping
andtraceroute
. - Document Complexity: Is the issue specific to very large or complex documents? Test with a simple, blank document.
- Scale Up/Out: If resources are the bottleneck, you may need to vertically scale (more RAM/CPU) or horizontally scale (add more CODE instances to the load balancer pool).
- Check
loolwsd.xml
Limits: Review<per_document>
settings likemax_concurrency
inloolwsd.xml
. Unlikely to be the issue unless heavily customized.
- Server Resources: Check CPU, RAM, and Disk I/O usage on the server(s) hosting the CODE containers while the issue is occurring. Use tools like
SSL/TLS Errors
- Symptom: Browser shows certificate warnings; connection fails with SSL errors.
- Diagnosis:
- Certificate Validity: Check the expiry date and chain of the SSL certificate served by your reverse proxy (Nginx/HAProxy). Use browser developer tools or online SSL checkers (e.g., SSL Labs). Has the certificate expired? Is the intermediate chain missing?
- Mixed Content: Ensure Nextcloud and Collabora are both accessed via HTTPS. Check browser developer console for "mixed content" warnings.
- Reverse Proxy SSL Config: Review the Nginx/Apache/HAProxy SSL configuration (
ssl_certificate
,ssl_certificate_key
, protocols, ciphers). Ensure it's correct and using strong, modern settings. - CODE Internal SSL: Verify that internal SSL is disabled in CODE (
ssl.enable=false
,ssl.termination=true
) if the reverse proxy handles termination. Checkloolwsd.xml
orextra_params
in thedocker run
command.
Log Analysis Techniques
- Collabora Logs (
docker logs codeX
): Set log level toinfo
ordebug
inloolwsd.xml
for more detail during troubleshooting. Look forERR
(Error) orWRN
(Warning) messages. Correlate timestamps with user actions. Search for specific document IDs or WOPI URLs. - Reverse Proxy Logs (
/var/log/nginx/access.log
,/var/log/nginx/error.log
): Checkaccess.log
for requests to Collabora URLs (status codes 200 OK, 4xx errors, 5xx errors). Checkerror.log
for connection issues to backends, SSL problems, or configuration errors. - Nextcloud Logs (
data/nextcloud.log
inside Nextcloud data directory): Look for errors related to the "Nextcloud Office" app or WOPI client functionality around the time of the issue. Set Nextcloud's log level higher if needed (Admin -> Logging). - Browser Developer Tools (F12): Check the "Console" tab for JavaScript errors or failed resource loading. Check the "Network" tab to see requests to Collabora, their status codes, and timings. Look for failed WebSocket connections.
Workshop Debugging an Integration Problem
This workshop simulates a common issue – Nextcloud failing to connect to Collabora – and walks through the debugging process.
Goal: Diagnose and fix a simulated "Unable to connect" error between Nextcloud and Collabora.
Prerequisites:
- Working load-balanced Collabora setup behind Nginx.
- Access to Nextcloud admin, server command line (for Docker, Nginx logs).
- Ability to stop/start services/containers.
Scenario: Users report that clicking on documents in Nextcloud results in an error message like "Failed to connect to Collabora Online server" or similar, instead of loading the editor.
Debugging Steps:
-
Reproduce and Gather Info:
- Try opening a document yourself in Nextcloud. Note the exact error message displayed.
- Note the timestamp when the error occurred.
-
Check Nextcloud Admin:
- Go to Nextcloud -> Administration settings -> Nextcloud Office.
- Verify the Collabora URL (
https://collabora.example.com
) is correct. - Click "Save". Does it show "Collabora Online server is reachable." or an error? If it shows an error here, the problem lies in the basic connectivity or Collabora/proxy service status.
-
Check Service Status:
- CODE Containers:
sudo docker ps
. Arecode1
andcode2
running? - Nginx:
sudo systemctl status nginx
. Is it active (running)?
- CODE Containers:
-
Simulate the Problem (Choose ONE):
- Option A: Stop Nginx:
sudo systemctl stop nginx
- Option B: Stop CODE Containers:
sudo docker stop code1 code2
- Option C: Introduce Firewall Block (If possible/applicable): Block traffic to
127.0.0.1:9980
and127.0.0.1:9981
from Nginx (less easy to simulate quickly). - Option D: Misconfigure Nginx
proxy_pass
: Edit the Nginx config, changeproxy_pass http://collabora_backends;
to something incorrect likeproxy_pass http://localhost:12345;
, then runsudo nginx -t && sudo systemctl reload nginx
.
- Option A: Stop Nginx:
-
Diagnose (Following the Scenario Above):
-
Check Nginx Logs:
sudo tail -n 50 /var/log/nginx/error.log
- If you stopped Nginx (A), this log won't update, but attempts to connect will fail immediately.
- If you stopped CODE (B) or misconfigured proxy_pass (D), you'll likely see errors like
[error] connect() failed (111: Connection refused) while connecting to upstream
or(111: Connection refused) while connecting to upstream, client: ..., server: collabora.example.com, request: "GET /lool/... ", upstream: "http://127.0.0.1:9980/lool/..."
. This clearly points to Nginx being unable to reach the defined backend(s). - If a firewall blocked (C), similar "Connection refused" or potentially "Connection timed out" errors might appear.
-
Check CODE Logs:
sudo docker logs code1
andsudo docker logs code2
- If CODE containers were stopped (B), these logs won't show new entries related to the connection attempt.
- If Nginx couldn't reach them (C, D), the CODE logs would show no sign of the incoming connection attempt from Nginx.
-
Check Connectivity from Nginx Host:
- Try curling the backends directly from the Nginx server:
- If CODE is stopped (B) or firewalled (C), these will fail ("Connection refused" or timeout).
- If only Nginx is misconfigured (D), these should still return "ok" (proving CODE itself is fine).
-
-
Identify the Cause: Based on the log messages and connectivity tests:
- Nginx errors "Connection refused" +
curl
to backend fails => CODE containers are stopped/unreachable. - Nginx errors "Connection refused" +
curl
to backend succeeds => Nginx configuration (proxy_pass
,upstream
) is likely wrong. - No Nginx errors, but connection fails => Nginx might be stopped, or a firewall before Nginx is blocking, or DNS is wrong for
collabora.example.com
. - Nextcloud admin check fails => Confirms basic connectivity issue.
- Nginx errors "Connection refused" +
-
Fix the Simulated Problem:
- If Nginx stopped (A):
sudo systemctl start nginx
- If CODE stopped (B):
sudo docker start code1 code2
- If Firewall (C): Remove the blocking rule.
- If Nginx config bad (D): Correct the
proxy_pass
directive, runsudo nginx -t && sudo systemctl reload nginx
.
- If Nginx stopped (A):
-
Verify Fix:
- Retry opening a document in Nextcloud.
- Re-check the connection in Nextcloud Admin -> Nextcloud Office. It should now succeed.
- Check Nginx
access.log
anderror.log
– errors should stop, and successful requests (200 OK) should appear.
Outcome: You have walked through a methodical troubleshooting process for a common integration failure, using logs and direct connectivity checks to pinpoint the cause (whether it's the reverse proxy, the backend service, or the connection between them) and verify the fix. This approach can be adapted to diagnose various connectivity and configuration issues.
Conclusion
Congratulations on completing this guide to self-hosting Collabora Online! You have journeyed from understanding the fundamental concepts and performing a basic Docker installation to implementing a secure, load-balanced, and monitored deployment suitable for more demanding environments.
Recap of Key Learnings:
- Core Concepts: You learned about Collabora Online's architecture (CODE,
loolwsd
,loolforkit
), its role as a WOPI host, and the importance of integrating it with a frontend like Nextcloud. - Basic Setup: You successfully deployed CODE using Docker and performed an initial integration test.
- Secure Access: You mastered setting up a reverse proxy (Nginx/Apache) to handle SSL/TLS termination using Let's Encrypt, significantly enhancing security and accessibility.
- Configuration: You explored the
loolwsd.xml
file and learned how to customize settings like logging and admin access. - Scaling & HA: You implemented horizontal scaling using multiple CODE instances and a load balancer (Nginx) and understood the broader considerations for High Availability.
- Monitoring & Troubleshooting: You set up basic monitoring and practiced a systematic approach to diagnosing common integration problems using logs and diagnostic tools.
By self-hosting Collabora Online, you gain full control over your collaborative document editing environment, ensuring data privacy and sovereignty. While it requires ongoing effort for maintenance and updates, the benefits of a tailored, private office suite backend are substantial.
Next Steps and Further Exploration:
- Deeper
loolwsd.xml
Customization: Explore advanced options for branding, font management, language settings, and fine-tuning resource limits. - Advanced Monitoring: Integrate your Collabora setup with robust monitoring solutions like Prometheus, Grafana, Zabbix, or the ELK stack for comprehensive dashboards and alerting.
- Alternative Integrations: Experiment with integrating Collabora Online with other WOPI-compatible frontends (ownCloud, Seafile, Moodle, etc.).
- Security Hardening: Implement stricter firewall rules, intrusion detection systems, and regular security audits. Explore advanced Nginx/Apache security configurations.
- Backup Strategy: While Collabora itself is largely stateless, ensure you have robust backup strategies for your configuration files, SSL certificates, and critically, the data stored in your frontend (Nextcloud/ownCloud).
- Performance Tuning: Analyze performance under heavy load using profiling tools and optimize server/network configurations.
Remember that the open-source community around Collabora Online and related projects is a valuable resource. Consult official documentation, forums, and community channels when you encounter challenges or want to learn more.
Self-hosting is a rewarding journey that empowers you with control and knowledge. Keep learning, stay updated with security patches, and enjoy the benefits of your private, collaborative office suite!