Files
docs/Servers/Containerization/Docker/Compose/Collabora CODE Server.md
Nicole Rappe 3a24e17889
All checks were successful
GitOps Automatic Deployment / GitOps Automatic Deployment (push) Successful in 7s
Add Servers/Containerization/Docker/Compose/Collabora CODE Server.md
2025-11-18 17:56:07 -07:00

4.0 KiB

Purpose:

The Collabora CODE Server is used by Nextcloud Office to open and edit documents and spreadsheets collaboratively. When Nextcloud is not deployed in a Nextcloud AIO way, and is instead installed not as a container, you (may) run into stability issues with Collabora CODE Server just randomly breaking and not allowing users to edit documents. If this happens, you can follow this document to stand-up a dedicated Collabora CODE Server on the same host as your Nextcloud server.

!!! info "Assumptions"

- It is assumed that you are running an ACME Certificate Bot on your Nextcloud server to generate certificates for Nextcloud.  
- It is also assumed that you are running Ubuntu Server 24.04.3 LTS. *This document does not outline the process for setting up an ACME Certificate Bot*. 
- It is lastly assumed that (until changes are made to allow such) this will only work for internal access.  Unless you port-forward port `9980` Collabora will not function for public internet-facing access.

Install Docker and Configure Portainer

The first thing you need to do is install Docker then Portainer. You can do this by following the Portainer Deployment documentation.

Portainer Stack

name: app
services:
  code:
    image: collabora/code
    container_name: collabora
    restart: always
    networks:
      - collabora-net
    environment:
      - domain=${NEXTCLOUD_COLLABORA_URL}
      - aliasgroup1=${NEXTCLOUD_COLLABORA_URL}
      - username=${CODESERVER_ADMIN_USER} # Used to login @ https://cloud.bunny-lab.io:9980/browser/dist/admin/admin.html
      - password=${CODESERVER_ADMIN_PASSWORD} # Used to login @ https://cloud.bunny-lab.io:9980/browser/dist/admin/admin.html
      # CODE speaks HTTP internally, TLS is terminated at nginx
      - extra_params=--o:ssl.enable=false --o:ssl.termination=true
    # no direct port mapping; only reachable via proxy

  collabora-proxy:
    image: nginx:alpine
    container_name: collabora-proxy
    restart: always
    depends_on:
      - code
    networks:
      - collabora-net
    ports:
      # Host port 9980 -> container port 443 (HTTPS)
      - "9980:443"
    volumes:
      # Our nginx vhost config (this exists outside of the container anywhere you want to put it, by default "/opt/collabora/nginx.conf")
      - /opt/collabora/nginx.conf:/etc/nginx/conf.d/default.conf:ro

      # Mount the entire letsencrypt tree so symlinks keep working
      - /etc/letsencrypt:/etc/letsencrypt:ro

networks:
  collabora-net:
    driver: bridge
NEXTCLOUD_COLLABORA_URL=cloud\\.bunny-lab\\.io
CODESERVER_ADMIN_USER=admin
CODESERVER_ADMIN_PASSWORD=ChangeThisPassword

NGINX Reverse Proxy Configuration

If the container does not run on the same host as Traefik, you will need to manually add configuration to Traefik's dynamic config file, outlined below.

map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

server {
    listen 443 ssl;
    server_name cloud.akafs.org;

    ssl_certificate     /etc/letsencrypt/live/cloud.akafs.org/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/cloud.akafs.org/privkey.pem;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;

    # Main proxy to CODE
    location / {
        proxy_pass http://collabora:9980;

        # Required for WebSockets
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;

        # Standard headers
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto https;

        proxy_read_timeout 36000;
        proxy_connect_timeout 36000;
        proxy_send_timeout 36000;

        proxy_buffering off;
        proxy_request_buffering off;
    }
}