Category Archives: Tutorial

Integrating Collabora with Nextcloud on Nginx

In one of the previous articles I described how to install nextcloud. If you want extend functionality to online editing XOffice (Open & M$) documents you need to install Collabora service.

Install additional fonts

Install (on Debian) additional MS fonts. New fonts will be available on /usr/share/fonts directory.

apt-get install ttf-mscorefonts-installer

Docker compose

You should add appropriate section on the end of docker compose file. My custom Collabora service is based on collabora/code and btstream/collabora-fonts. The main feature is the possibility of adding custom font from external directory. Just mount the volume.

version: '2'

volumes:
  nextcloud:
  db:

services:
  db:
    image: mariadb:10.3.14
    restart: always
    volumes:
      - ./data/db:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=$ENV_MYSQL_ROOT_PASSWORD
      - MYSQL_PASSWORD=$ENV_MYSQL_PASSWORD
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud

  app:
    image: nextcloud:15.0.8-apache
    ports:
      - 50020:80
    links:
      - db
    volumes:
      - $ENV_APP_HTML:/var/www/html
      - $ENV_APP_DATA:/var/www/html/data
      - $ENV_APP_CONFIG:/var/www/html/config
      - $ENV_APP_APPS:/var/www/html/apps
    restart: always

  collabora:
    image: mrcnpdlk/collabora-custom-fonts:1.0
    restart: unless-stopped
    environment:
       - domain=mydomain.com
       - username=admin
       - password=some_password
    volumes:
       - /usr/share/fonts:/usr/share/fonts/Custom
    ports:
      - 127.0.0.1:9980:9980

After starting of services wait one or two minutes – collabora image starts long time.

Nginx configuration

Collabora is started on localhost without SSL, because of that I am using Nginx to add SSL. Add config to site-enabled directory.

server {
    listen 9081 ssl http2;
    listen [::]:9081 ssl http2;
    ssl_certificate     path_to_cert;
    ssl_certificate_key path_to_key;
    server_name my_server_name;
    access_log /var/log/nginx/access.log;
    error_log  /var/log/nginx/error.log;
    large_client_header_buffers 4 8k;

    location ^~ /loleaflet {
        proxy_pass https://localhost:9980;
        proxy_set_header Host $http_host;
    }

    # WOPI discovery URL
    location ^~ /hosting/discovery {
        proxy_pass https://localhost:9980;
        proxy_set_header Host $http_host;
    }

    # Capabilities
    location ^~ /hosting/capabilities {
        proxy_pass https://localhost:9980;
        proxy_set_header Host $http_host;
    }

    # main websocket
    location ~ ^/lool/(.*)/ws$ {
        proxy_pass https://localhost:9980;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_set_header Host $http_host;
        proxy_read_timeout 36000s;
    }

    # download, presentation and image upload
    location ~ ^/lool {
        proxy_pass https://localhost:9980;
        proxy_set_header Host $http_host;
    }

    # Admin Console websocket
    location ^~ /lool/adminws {
        proxy_pass https://localhost:9980;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_set_header Host $http_host;
        proxy_read_timeout 36000s;
    }
}

Now, the collabora service is listening on 9081 port of my server with some public IP, for example 1.1.1.1 on domain mydomain.com.

If everything is correct, you will be able to login into admin page: https://mydomain.com:9081/loleaflet/dist/admin/admin.html

Nextcloud configuration

Next step is very easy. Just install Collabora Online app on the Nextcloud and configure it. Set url service: https://mydomain.com:9081 and disable checking SSL if you have self-signed certificate .

Nextcloud behind Nginx reverse proxy

Create Nextcloud in Docker

Prepare directory tree

mkdir nextcloud
cd nextcloud
touch docker-compose.yml
touch .env

docker-compose.yml

Compose is a tool for defining and running multi-container Docker applications. With Compose, you use a YAML file to configure your application’s services. 

We gonna expose Nextcloud on 50020 host port and define external volumes.

version: '2'

volumes:
  nextcloud:
  db:

services:
  db:
    image: mariadb
    restart: always
    volumes:
      - ./data/db:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=$ENV_MYSQL_ROOT_PASSWORD
      - MYSQL_PASSWORD=$ENV_MYSQL_PASSWORD
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud

  app:
    image: nextcloud
    ports:
      - 50020:80
    links:
      - db
    volumes:
      - $ENV_APP_HTML:/var/www/html
      - $ENV_APP_DATA:/var/www/html/data
      - $ENV_APP_CONFIG:/var/www/html/config
      - $ENV_APP_APPS:/var/www/html/apps
    restart: always

.env file

Compose supports declaring default environment variables in an environment file named .env placed in the folder where the docker-compose command is executed (current working directory).

ENV_MYSQL_ROOT_PASSWORD=root_sql_pass
ENV_MYSQL_PASSWORD=nextcloud_sql_pass
ENV_APP_HTML=./data/app/html
ENV_APP_DATA=./data/app/data
ENV_APP_CONFIG=./data/app/config
ENV_APP_APPS=./data/app/apps

Start compose

To start our stack just call below commands:

docker-compose up -d
Creating network "nextcloud_default" with the default driver
Creating nextcloud_db_1 ... done
Creating nextcloud_app_1 ... done

docker-compose ps   
     Name                    Command               State           Ports        
--------------------------------------------------------------------------------
nextcloud_app_1   /entrypoint.sh apache2-for ...   Up      0.0.0.0:50020->80/tcp
nextcloud_db_1    docker-entrypoint.sh mysqld      Up      3306/tcp   

Everything is correct. MySQL service is encapsulated into the stack, only Nextcloud has access to it. On the other hand Nextcloud HTTP port 80 is exposed on 50020 host port. Let’s try go to http://HOST_IP:50020, you will be able to see Nextcloud wizard page. Set config and save.

It is not the end our case, because we want have access to our drive not via PORT but using the subfolder: http://DOMAIN_NAME/nc. To do this, we must use nginx reverse proxy.

Nginx configuration

Add insertion to your domain DOMAIN_NAME sites-enabled configuration file

# NextCloud
location ^~ /nc/ {
  rewrite ^/nc(.*) $1 break;
  # set your HOST_IP and Nextcloud PORT
  proxy_pass http://HOST_IP:50020/; 
  proxy_http_version 1.1;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $remote_addr;
  proxy_read_timeout 1d;
  proxy_set_header HTTP_X-Forwarded-For $proxy_add_x_forwarded_for;
}

Check config and restart service

nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

systemctl restart nginx.service
systemctl status nginx.service 

Try open http://DOMAIN_NAME/nc in your browser. Unfortunately, the login page does not look like we would expect. CSS/JS files has 404 Not found error because requested paths are malformed.

To fix this edit Nextcloud configuration file (availabled in compose volume) and overwrite lines as in the example below.

nano data/app/config/config.php
#  'overwrite.cli.url' => 'http://192.168.1.12:50020',

# www.example.com is our DOMAIN_NAME
# https is our external protocol, if you don't use ssl set http
# nc is subfolder defined in nginx config

  'overwrite.cli.url' => 'https://www.example.com/nc',
  'overwritehost' => 'www.example.com',
  'overwritewebroot' => '/nc',
  'overwriteprotocol' => 'https',