Is there a guide how to setup Collabora/Code docker if the reverse proxy is on a different machine?

I’m pretty experienced at setting up Collabora code via Docker/Docker compose, but I can’t seem to take a working configuration where collabora and an nginx reverse proxy is running on the same machine and tweak the configuration so that an nginx reverse proxy is running a different machine. I’m trying to setup an ssl terminating reverse proxy with http communication to collabora

Here is my docker-compose.yml file I’m tweaking (there are a number of different commented sections which I turn on and off for testing): I’ve substituted for my actual domain name.

---
version: '3.3'

networks:
  net:
   driver: bridge

services:

  collabora:
    restart: always
    image: collabora/code:latest
    container_name: collabora
    networks:
      - net
    ports:
#      - 127.0.0.1:9980:9980
      - 9980:9980
    cap_add:
      - MKNOD
    environment:
      - TZ=America/Chicago
      - username=admin
      - password=dockercol
      - domain=nextcloud\.<domain>\.com
#      - cert_domain=office.<domain>.com
      - DONT_GEN_SSL_CERT="True"
      - server_name=office.<domain>.com
      - extra_params=--o:ssl.enable=false --o:ssl.termination=true
#      - extra_params=--o:ssl.enable=false --o:ssl.termination=false
#      - extra_params="--o:ssl.enable=true"
#      - extra_params="--o:ssl.enable=false"
 #   volumes:
 #    - /etc/letsencrypt/office.<domain>.com/privkey.pem:/etc/loolwsd/key.pem
 #     - /etc/letsencrypt/office.<domain>.com/cert.pem:/etc/loolwsd/cert.pem
#      - /etc/ssl/certs/ca-certificates.crt:/etc/loolwsd/ca-chain.cert.pem
#      - /etc/letsencrypt/office.<domain>.com/chain.pem:/etc/loolwsd/ca-chain.cert.pem

In terms of the compose file, perhaps someone could help me as I’m using this page as a reference. https://www.collaboraoffice.com/code/docker/

The domain parameter specifies the WOPI host. I believe the WOPI host (what that heck does WOPI stand for anyway??) is the nextcloud installation. I suppose if you running multiple nextcloud installations you would add a second host with a | separator.
The cert_domain is needed is needed if you are enabling TLS/SSL inside the container and want the collabora container to generate a “self signed certificate” with a specific domain name. Because I’m terminating SSl at the reverse proxy, I don’t think I need this option.
The server_name parameter I believe is the host-name of the reverse proxy. I believe the server_name needs to be changed depending on the location of the reverse proxy.

In terms of the nginx reverse proxy configuration – this is the configuration if the reverse proxy is on the same machine (this is a working configuration). This was directly adapted from the official collabora proxy instructions: https://www.collaboraoffice.com/code/nginx-reverse-proxy/

map $http_x_forwarded_proto $the_scheme {
     default $http_x_forwarded_proto;
     "" $scheme;
}

map $http_x_forwarded_host $the_host {
    default $http_x_forwarded_host;
    "" $host;
}

map $http_upgrade $proxy_connection {
  default upgrade;
  "" close;
}

server {
        listen [::]:443 ssl http2;
	listen      443 ssl http2;

        server_name office.<domain>.com;

        #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
        #                  '$status $body_bytes_sent "$http_referer" '
        #                  '"$http_user_agent" "$http_x_forwarded_for"';

        access_log /var/log/nginx/office.<domain>.com.access.log main buffer=32k;
        error_log /var/log/nginx/office.<domain>.com.error.log;

        include snippets/office.<domain>.com.cert.conf;
        include snippets/ssl-params.conf;

	keepalive_timeout 65;

	# Allow large attachments
	client_max_body_size 128M;

	index index.html index.htm index.php /index.php;

	location / {
		root /var/www/office.<domain>.com/html;
	}

       # static files
       location ^~ /loleaflet {
           proxy_pass http://localhost:9980;
           proxy_set_header Host $http_host;
       }

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

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

       # main websocket
       location ~ ^/lool/(.*)/ws$ {
           proxy_pass http://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 http://localhost:9980;
           proxy_set_header Host $http_host;
       }

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

So that’s a working configuration.
For the non-working reverse proxy on a different machine I’m running the same docker-collabora instance however with my compose file I set the server_name parameter to the reverse proxy (I named my reverse proxy test.<domain>.com and have LE certs for the test domain)

Here is my nginx config (almost as exactly above but with slight modifications);

map $http_x_forwarded_proto $the_scheme {
     default $http_x_forwarded_proto;
     "" $scheme;
}

map $http_x_forwarded_host $the_host {
    default $http_x_forwarded_host;
    "" $host;
}

map $http_upgrade $proxy_connection {
  default upgrade;
  "" close;
}

server {
        listen [::]:443 ssl http2;
	listen      443 ssl http2;

        server_name test.<domain>.com;

        #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
        #                  '$status $body_bytes_sent "$http_referer" '
        #                  '"$http_user_agent" "$http_x_forwarded_for"';

        access_log /var/log/nginx/test.<domain>.com.access.log main buffer=32k;
        error_log /var/log/nginx/test.<domain>.com.error.log;

        include snippets/test.<domain>.com.cert.conf;
        include snippets/ssl-params.conf;

	keepalive_timeout 65;

	# Allow large attachments
	client_max_body_size 128M;

           # static files
           location ^~ /loleaflet {
               proxy_pass http://office.<domain>.com:9980;
               proxy_set_header Host $http_host;
           }

           # WOPI discovery URL
           location ^~ /hosting/discovery {
               proxy_pass http://office.<domain>.com:9980;
               proxy_set_header Host $http_host;
           }

           # Capabilities
           location ^~ /hosting/capabilities {
               proxy_pass http://office.<domain>.com:9980;
               proxy_set_header Host $http_host;
           }

           # main websocket
           location ~ ^/lool/(.*)/ws$ {
               proxy_pass http://office.<domain>.com: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 http://office.<domain>.com:9980;
               proxy_set_header Host $http_host;
           }

           # Admin Console websocket
           location ^~ /lool/adminws {
               proxy_pass http://office.<domain>.com:9980;
               proxy_set_header Upgrade $http_upgrade;
               proxy_set_header Connection "Upgrade";
               proxy_set_header Host $http_host;
               proxy_read_timeout 36000s;
           }

}

I’ve ensured the firewall allows all connections for port 9980:

# ufw status
Status: active

To                         Action      From
--                         ------      ----
Apache Full                ALLOW       Anywhere
OpenSSH                    ALLOW       Anywhere
9980                       ALLOW       Anywhere
Anywhere on docker0        ALLOW       Anywhere
Anywhere                   ALLOW       172.17.0.0/24
Anywhere                   ALLOW       172.18.0.0/24
Anywhere                   ALLOW       172.19.0.0/24
Anywhere                   ALLOW       172.20.0.0/24
Apache Full (v6)           ALLOW       Anywhere (v6)
OpenSSH (v6)               ALLOW       Anywhere (v6)
9980 (v6)                  ALLOW       Anywhere (v6)
Anywhere (v6) on docker0   ALLOW       Anywhere (v6)

Unfortunately this configuration is definitely not working. I’m wondering if anyone had any ideas??

When I say not working let me clarify – there is a problem with the websocket connection.
I can reach the collabora administrator console through the reverse proxy and I can also with a tweak reach the docker instance where I’m getting an OK in the browser.

Here is an example from the nextcloud log:

{"reqId":"JSWPDYuZrMlvFolfSuPX","level":3,"time":"April 22, 2020 22:33:00","remoteAddr":"10.0.1.184","user":"ncadmin","app":"richdocuments","method":"GET","url":"/index.phpdocuments/index?fileId=25&requesttoken=lVriqZxmIC6nzqUuPFrk46Mk5PKmBKk86rOzkWMqFgI%3D%3A%2Bi207OYyYXjjg4pkVjCx1MxIsJfRYspXp%2FyY41F5d1M%3D","message":{"Exception":"GuzzleHttp\\Exception\\ConnectException","Message":"cURL error 35: error:1407742E:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version (see http://curl.haxx.se/libcurl/c/libcurl-errors.html)","Code":0,"Trace":[{"file":"/usr/local/www/nextcloud/3rdparty/guzzlehttp/guzzle/src/Handler/CurlFactory.php","line":149,"function":"createRejection","class":"GuzzleHttp\\Handler\\CurlFactory","type":"::","args":[{"sink":{"__class__":"GuzzleHttp\\Psr7\\Stream"},"headers":[],"response":null,"request":{"__class__":"GuzzleHttp\\Psr7\\Request"},"options":{"verify":false,"timeout":5,"synchronous":true,"handler":{"__class__":"GuzzleHttp\\HandlerStack"},"allow_redirects":{"max":5,"protocols":["http","https"],"strict":false,"referer":false,"track_redirects":false},"http_errors":true,"decode_content":true,"cookies":false},"errno":35,"onHeadersException":null,"__class__":"GuzzleHttp\\Handler\\EasyHandle"},{"errno":35,"error":"error:1407742E:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version","url":"https://test.<domain>.com/hosting/discovery"

Clearly there seems to be an SSL error – however why???

The answer isn’t sticking out to me, but make sure that:

  • Both NC and Collabora are able to resolve each other’s names
  • Both are pointing to the reverse proxy even when talking to each other
  • The reverse proxy is presenting a valid certificate for both

Here is another example I wrote myself that you can cross-reference.

https://help.nextcloud.com/t/howto-ubuntu-docker-nextcloud-talk-collabora/76430

Both nextcloud.domain.com and office.domain.com should resolve to the reverse proxy. Is that the case? If so then this looks like nginx is sending the Collabora connection to itself rather than the other machine.

@KarlF12

I’m going to answer your questions in turn

  1. Both NC and Collabora are able to resolve each other’s names. I believe so. Here is how I test this – Nextcloud is running in a freebsd jail, Collabora within docker on an Ubuntu VM. From Nextcloud (nextcloud..com) I can ping (office..com). If I docker exec into collabora container, I can ping nextcloud..com from inside the container. (I have a dhcp host override on the pfsense router which points to the internal LAN address for these domain names).
  2. Both are pointing at the reverse proxy even when talking to each other – Hmm.
  3. The reverse proxy is presenting a valid cert for both

Ok I know the certs are valid – Let’s encrypt. I’ve verified this by running webservers and having browsers connect to directories and such

Let’s revisit point #2. How exactly is this done?
Nextcloud side – From within the Settings->Collabora Online, I have entered the https://test.<domain>.com (test.<domain>.com) which is the name of my reverse proxy. So I’m guessing that nextcloud is “talking” to collabora through the reverse proxy

Collabora talking to nextcloud through reverse proxy-- Not sure how this is done – I guessing you put the WOPI host as the reverse proxy??? So maybe change:
domain=nextcloud\.<domain>\.com to domain=test\.<domain>\.com

To address your concern the reverse proxy is test.<domain>.com and the collabora machine is office.<domain>.com

       # main websocket
       location ~ ^/lool/(.*)/ws$ {
           proxy_pass http://office.<domain>.com:9980;
           proxy_set_header Upgrade $http_upgrade;
           proxy_set_header Connection "Upgrade";
           proxy_set_header Host $http_host;
           proxy_read_timeout 36000s;
       }

This is the nginx reverse proxy config located on test.<domain>.com. Is this a problem?

And what the heck is up with this error message since its suggesting an SSL problem.
ndex?fileId=68119&requesttoken=EzBXng9ezEtm1wcYYzS5mGUpDIrB0GzkB7RPI0mE%2BQ4%3D%3AfEcB23UKjR0imihSCV7srwpFWO%2B2tg%2BPSvtkUXvXmF8%3D","message":{"Exception":"GuzzleHttp\\Exception\\ConnectException","Message":"cURL error 35: error:1407742E:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version (see http://curl.haxx.se/libcurl/c/libcurl-errors.html)","Code":0,"Trace"

A portion of something has to be working since if I issue command from a browser on the network (This statement along would show that this connection is going through the reverse proxy and then being proxied to collabora):

#wget https://test.<domain>.com/hosting/discovery
<wopi-discovery>
    <net-zone name="external-http">
        <app name="image/svg+xml">
            <action ext="svg" name="view" urlsrc="https://test.<domain>.com/loleaflet/adadb63/loleaflet.html?"/>
        </app>
        <app name="application/vnd.ms-powerpoint">
            <action ext="pot" name="edit" urlsrc="https://test.<domain>.com/loleaflet/adadb63/loleaflet.html?"/>
        </app>
...

Did I understand correctly that the reverse proxy and Collabora are on different systems? And you have office.domain.com pointing to the reverse proxy? But that is also the reverse proxy’s target for the port 9980 connection, meaning it will pass that to 9980 on itself, not to the other system where Collabora is.

The reverse proxy is known as test.<domain>.com and collabora is known as office<domain>.com. They are on different systems. Office.domain.com pointing to reverse proxy. There is also a nextcloud.domain.com on another system.

I don’t understand what you are saying by office.domain.com pointing to the reverse proxy. What setting would that be? The server_name setting?

The reverse proxy at the present time points to office.domain.com but not nextcloud although I could add that.

If office.domain.com resolves to the IP of your reverse proxy, then isn’t your nginx proxy pass directive telling it to forward the connection to itself instead of Collabora?

proxy_pass http://office.<domain>.com:9980;

Try using you Collabora server’s IP here.

office.<domain>.com resolves to the collabora server.
test.<domain>.com resolves to the RV proxy
nextcloud.<domain>.com resolves to the nextcloud server.

[root@archZFSProxy vdomains]# nslookup office.domain.com
Server:		10.0.1.1
Address:	10.0.1.1#53

Name:	office.domain.com
Address: 10.0.1.162

[root@archZFSProxy vdomains]# nslookup test.domain.com
Server:		10.0.1.1
Address:	10.0.1.1#53

Name:	test.domain.com
Address: 10.0.1.86

[root@archZFSProxy vdomains]# nslookup nextcloud.domain.com
Server:		10.0.1.1
Address:	10.0.1.1#53

Name:	nextcloud.domain.com
Address: 10.0.1.158

I do have two nextcloud instance and one collabora on one server
ie. 192.168.x.100

I have nginx on another machine. ie. 192.168.x.10
listening on 443 to send of both subdomains to ie. 192.168.x.100

The incoming router is port forwarding port 443 to the IP of nginx ie. 192.168.x.10

the Nextcloud with OnlyOffice is working (but slow as ever before)
therefore I prefer collabora. But the collabora doesn’t fire any document. Everything loads but for the document which according to the debugger in my browser probably is somethink like:

wss://collabora.domain.com/lool/https%3A%2F%2Fnextcloud.domain.com%2Findex.php%2Fapps%2Frichdocuments%2Fwopi%2Ffiles%2F1740_oc8xxxxxxxx%3Faccess_token%3xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%26access_token_ttl%3D0/ws?WOPISrc=https%3A%2F%2Fnextcloud.domain.com%2Findex.php%2Fapps%2Frichdocuments%2Fwopi%2Ffiles%2F1740_oc8xxxxxxxx&compat=/ws

the type is “websocket”

it returns this message: Error during WebSocket handshake: Unexpected response code: 500

I am still digging but maybe you can dig along

Okay, then how are connections to office.domain.com being directed to the reverse proxy? You see what I’m getting at? The DNS record for anything that is supposed to go through the reverse proxy must point to the reverse proxy’s IP address, and then can’t be used as the proxy pass target because that would then point to itself.

So office.domain.com should point to your reverse proxy, and the reverse proxy should pass it back to the Collabora server by IP. Same for Nextcloud if it uses the same reverse proxy.

@KarlF12

Hmm I get what you’re saying — but that strategy you are telling me doesn’t work if you have SSL certs involved on the backend (which is my ultimate goal since you cant proxy pass by IP address with verification since SSL certs require a domain name and not an IP address.

Although I didn’t mention it in the original post (perhaps I should have), I tried adding the IP address to my proxy-pass statements and the results were similar.

Perhaps you could help me understand things since clearly I’m kind of confused.
I definitely need the connection to nextcloud to eventually go through the reverse proxy. However once inside the nextcloud app, is it essential that the nextcloud<–>collabora connection go through the reverse proxy?

If you want to validate and authenticate certificates between the reverse proxy and the backend server, then you’ll have to have another FQDN for it that only the reverse proxy uses, with another valid certificate that probably isn’t going to auto-renew. You can certainly work that out, but consider whether that’s making things unnecessarily complicated.

I wouldn’t say it’s absolutely essential. It does make life much easier and is shown to work. Remember, anything not using the reverse proxy will have to be using a different name to reach the server, and that creates a mess in a variety of ways.

In my guide, I went so far as to use the Docker extra_hosts directive to add the reverse proxy to both Nextcloud and Collabora’s hosts files to make sure they both went through the proxy (which in my case all three were on the same machine). I had problems with Collabora much like you’re describing before I took that step.

As I described in my comment; if you’d check in a browser console network tab you’d see that on opening a document from nextcloud using collabora, the document itself is passed in a websocket type connection.
Transferring 0 bytes.

Ok I’m trying a new configuration, but unfortunately its the same result.
In this configuration I basically placed the nextcloud and collabora directives in the nginx virtual domain file. Everything at this point is run through the reverse proxy.

Please note I also tried substituting IP addresses rather than using domain names for collabora, and same error.

Here is my nginx file

upstream collabora {
    server office.domain.com:9980;
}

upstream nextcloud {
    server nextcloud.domain.com;
}

server {
        listen [::]:443 ssl http2;
	    listen      443 ssl http2;

        server_name test.domain.com;

        #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
        #                  '$status $body_bytes_sent "$http_referer" '
        #                  '"$http_user_agent" "$http_x_forwarded_for"';

        access_log /var/log/nginx/test.domain.com.access.log main buffer=32k;
        error_log /var/log/nginx/test.domain.com.error.log;

        include snippets/test.domain.com.cert.conf;
        include snippets/ssl-params.conf;

	keepalive_timeout 65;

	# Allow large attachments
	client_max_body_size 128M;

	index index.html index.htm index.php /index.php;

    #nextcloud block
    location / {
      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_set_header X-Forwarded-Host $server_name;
      proxy_set_header X-Forwarded-Ssl on;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";
      proxy_http_version 1.1;
      proxy_pass https://nextcloud;
    }

    # static files
    location ^~ /loleaflet {
        proxy_pass http://collabora;
        proxy_set_header Host $http_host;
    }

    # WOPI discovery URL
    location ^~ /hosting/discovery {
        proxy_pass http://collabora;
        proxy_set_header Host $http_host;
    }

    # Capabilities
    location ^~ /hosting/capabilities {
        proxy_pass http://collabora;
        proxy_set_header Host $http_host;
    }

    # main websocket
    location ~ ^/lool/(.*)/ws$ {
        proxy_pass http://collabora;
        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 http://collabora;
        proxy_set_header Host $http_host;
    }

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

}

Nextcloud is reachable but unfortunately here is the error log on the nextcloud server (it’s basically the same from the prior setup. It’s still bitching about:
Message":"cURL error 35: error:1407742E:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version

{"reqId":"Yshguay9ipDeXcsPyu2j","level":3,"time":"April 23, 2020 17:18:29","remoteAddr":"10.0.1.184","user":"ncadmin","app":"richdocuments","method":"GET","url":"/index.phpdocuments/index?fileId=25&requesttoken=YzQmFkwTra8yztdSMpAlN6fInO5rLMN%2B1eVOGwO5mmk%3D%3ATHZXXx1g%2B%2BB8%2FLpmY9l%2FQ8yp3YIRToE6lIk0d1eNzFs%3D","message":{"Exception":"GuzzleHttp\\Exception\\ConnectException","Message":"cURL error 35: error:1407742E:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version (see http://curl.haxx.se/libcurl/c/libcurl-errors.html)","Code":0,"Trace":[{"file":"/usr/local/www/nextcloud/3rdparty/guzzlehttp/guzzle/src/Handler/CurlFactory.php","line":149,"function":"createRejection","class":"GuzzleHttp\\Handler\\CurlFactory","type":"::","args":[{"sink":{"__class__":"GuzzleHttp\\Psr7\\Stream"},"headers":[],"response":null,"request":{"__class__":"GuzzleHttp\\Psr7\\Request"},"options":{"verify":false,"timeout":5,"synchronous":true,"handler":{"__class__":"GuzzleHttp\\HandlerStack"},"allow_redirects":{"max":5,"protocols":["http","https"],"strict":false,"referer":false,"track_redirects":false},"http_errors":true,"decode_content":true,"cookies":false},"errno":35,"onHeadersException":null,"__class__":"GuzzleHttp\\Handler\\EasyHandle"},{"errno":35,"error":"error:1407742E:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version","url":"https://test.domain.com/hosting/discovery","content_type":null,"http_code":0,"header_size":0,"request_size":0,"filetime":-1,"ssl_verify_result":1,"redirect_count":0,"total_time":0.01004,"namelookup_time":0.001077,"connect_time":0.001302,"pretransfer_time":0,"size_upload":0,"size_download":0,"speed_download":0,"speed_upload":0,"download_content_length":-1,"upload_content_length":-1,"starttransfer_time":0,"redirect_time":0,"redirect_url":"","primary_ip":"10.0.1.86","certinfo":[],"primary_port":443,"local_ip":"10.0.1.158","local_port":32367}]},{"file":"/usr/local/www/nextcloud/3rdparty/guzzlehttp/guzzle/src/Handler/CurlFactory.php","line":102,"function":"finishError","class":"GuzzleHttp\\Handler\\CurlFactory","type":"::","args":[{"__class__":"GuzzleHttp\\Handler\\CurlHandler"},{"sink":{"__class__":"GuzzleHttp\\Psr7\\Stream"},"headers":[],"response":null,"request":{"__class__":"GuzzleHttp\\Psr7\\Request"},"options":{"verify":false,"timeout":5,"synchronous":true,"handler":{"__class__":"GuzzleHttp\\HandlerStack"},"allow_redirects":{"max":5,"protocols":["http","https"],"strict":false,"referer":false,"track_redirects":false},"http_errors":true,"decode_content":true,"cookies":false},"errno":35,"onHeadersException":null,"__class__":"GuzzleHttp\\Handler\\EasyHandle"},{"__class__":"GuzzleHttp\\Handler\\CurlFactory"}]},{"file":"/usr/local/www/nextcloud/3rdparty/guzzlehttp/guzzle/src/Handler/CurlHandler.php","line":43,"function":"finish","class":"GuzzleHttp\\Handler\\CurlFactory","type":"::","args":[{"__class__":"GuzzleHttp\\Handler\\CurlHandler"},{"sink":{"__class__":"GuzzleHttp\\Psr7\\Stream"},"headers":[],"response":null,"request":{"__class__":"GuzzleHttp\\Psr7\\Request"},"options":{"verify":false,"timeout":5,"synchronous":true,"handler":{"__class__":"GuzzleHttp\\HandlerStack"},"allow_redirects":{"max":5,"protocols":["http","https"],"strict":false,"referer":false,"track_redirects":false},"http_errors":true,"decode_content":true,"cookies":false},"errno":35,"onHeadersException":null,"__class__":"GuzzleHttp\\Handler\\EasyHandle"},{"__class__":"GuzzleHttp\\Handler\\CurlFactory"}]},{"file":"/usr/local/www/nextcloud/3rdparty/guzzlehttp/guzzle/src/Handler/Proxy.php","line":28,"function":"__invoke","class":"GuzzleHttp\\Handler\\CurlHandler","type":"->","args":["*** sensitive parameter replaced ***","*** sensitive parameter replaced ***"]},{"file":"/usr/local/www/nextcloud/3rdparty/guzzlehttp/guzzle/src/Handler/Proxy.php","line":51,"function":"GuzzleHttp\\Handler\\{closure}","class":"GuzzleHttp\\Handler\\Proxy","type":"::","args":["*** sensitive parameters replaced ***"]},{"file":"/usr/local/www/nextcloud/3rdparty/guzzlehttp/guzzle/src/PrepareBodyMiddleware.php","line":37,"function":"GuzzleHttp\\Handler\\{closure}","class":"GuzzleHttp\\Handler\\Proxy","type":"::","args":["*** sensitive parameters replaced ***"]},{"file":"/usr/local/www/nextcloud/3rdparty/guzzlehttp/guzzle/src/Middleware.php","line":30,"function":"__invoke","class":"GuzzleHttp\\PrepareBodyMiddleware","type":"->","args":["*** sensitive parameter replaced ***","*** sensitive parameter replaced ***"]},{"file":"/usr/local/www/nextcloud/3rdparty/guzzlehttp/guzzle/src/RedirectMiddleware.php","line":70,"function":"GuzzleHttp\\{closure}","class":"GuzzleHttp\\Middleware","type":"::","args":["*** sensitive parameters replaced ***"]},{"file":"/usr/local/www/nextcloud/3rdparty/guzzlehttp/guzzle/src/Middleware.php","line":60,"function":"__invoke","class":"GuzzleHttp\\RedirectMiddleware","type":"->","args":["*** sensitive parameter replaced ***","*** sensitive parameter replaced ***"]},{"file":"/usr/local/www/nextcloud/3rdparty/guzzlehttp/guzzle/src/HandlerStack.php","line":67,"function":"GuzzleHttp\\{closure}","class":"GuzzleHttp\\Middleware","type":"::","args":["*** sensitive parameters replaced ***"]},{"file":"/usr/local/www/nextcloud/3rdparty/guzzlehttp/guzzle/src/Client.php","line":277,"function":"__invoke","class":"GuzzleHttp\\HandlerStack","type":"->","args":["*** sensitive parameter replaced ***","*** sensitive parameter replaced ***"]},{"file":"/usr/local/www/nextcloud/3rdparty/guzzlehttp/guzzle/src/Client.php","line":125,"function":"transfer","class":"GuzzleHttp\\Client","type":"->","args":["*** sensitive parameter replaced ***","*** sensitive parameter replaced ***"]},{"file":"/usr/local/www/nextcloud/3rdparty/guzzlehttp/guzzle/src/Client.php","line":131,"function":"requestAsync","class":"GuzzleHttp\\Client","type":"->","args":["get",{"__class__":"GuzzleHttp\\Psr7\\Uri"},{"verify":false,"timeout":5,"synchronous":true,"handler":{"__class__":"GuzzleHttp\\HandlerStack"},"allow_redirects":{"max":5,"protocols":["http","https"],"strict":false,"referer":false,"track_redirects":false},"http_errors":true,"decode_content":true,"cookies":false,"_conditional":{"User-Agent":"GuzzleHttp/6.3.3 curl/7.68.0 PHP/7.2.28"}}]},{"file":"/usr/local/www/nextcloud/lib/private/Http/Client/Client.php","line":149,"function":"request","class":"GuzzleHttp\\Client","type":"->","args":["get","https://test.domain.com/hosting/discovery",{"proxy":null,"verify":false,"timeout":5,"headers":{"User-Agent":"Nextcloud Server Crawler"},"synchronous":true}]},{"file":"/usr/local/www/nextcloud/apps/richdocuments/lib/WOPI/DiscoveryManager.php","line":106,"function":"get","class":"OC\\Http\\Client\\Client","type":"->","args":["https://test.domain.com/hosting/discovery",{"timeout":5,"verify":false}]},{"file":"/usr/local/www/nextcloud/apps/richdocuments/lib/WOPI/DiscoveryManager.php","line":78,"function":"fetchFromRemote","class":"OCA\\Richdocuments\\WOPI\\DiscoveryManager","type":"->","args":[]},{"file":"/usr/local/www/nextcloud/apps/richdocuments/lib/WOPI/Parser.php","line":41,"function":"get","class":"OCA\\Richdocuments\\WOPI\\DiscoveryManager","type":"->","args":[]},{"file":"/usr/local/www/nextcloud/apps/richdocuments/lib/TokenManager.php","line":210,"function":"getUrlSrc","class":"OCA\\Richdocuments\\WOPI\\Parser","type":"->","args":["application/vnd.oasis.opendocument.text"]},{"file":"/usr/local/www/nextcloud/apps/richdocuments/lib/Controller/DocumentController.php","line":238,"function":"getToken","class":"OCA\\Richdocuments\\TokenManager","type":"->","args":["*** sensitive parameters replaced ***"]},{"file":"/usr/local/www/nextcloud/lib/private/AppFramework/Http/Dispatcher.php","line":170,"function":"index","class":"OCA\\Richdocuments\\Controller\\DocumentController","type":"->","args":["*** sensitive parameter replaced ***"]},{"file":"/usr/local/www/nextcloud/lib/private/AppFramework/Http/Dispatcher.php","line":99,"function":"executeController","class":"OC\\AppFramework\\Http\\Dispatcher","type":"->","args":[{"__class__":"OCA\\Richdocuments\\Controller\\DocumentController"},"index"]},{"file":"/usr/local/www/nextcloud/lib/private/AppFramework/App.php","line":125,"function":"dispatch","class":"OC\\AppFramework\\Http\\Dispatcher","type":"->","args":[{"__class__":"OCA\\Richdocuments\\Controller\\DocumentController"},"index"]},{"file":"/usr/local/www/nextcloud/lib/private/AppFramework/Routing/RouteActionHandler.php","line":47,"function":"main","class":"OC\\AppFramework\\App","type":"::","args":["OCA\\Richdocuments\\Controller\\DocumentController","index",{"__class__":"OC\\AppFramework\\DependencyInjection\\DIContainer"},{"_route":"richdocuments.document.index"}]},{"function":"__invoke","class":"OC\\AppFramework\\Routing\\RouteActionHandler","type":"->","args":[{"_route":"richdocuments.document.index"}]},{"file":"/usr/local/www/nextcloud/lib/private/Route/Router.php","line":299,"function":"call_user_func","args":[{"__class__":"OC\\AppFramework\\Routing\\RouteActionHandler"},{"_route":"richdocuments.document.index"}]},{"file":"/usr/local/www/nextcloud/lib/base.php","line":1008,"function":"match","class":"OC\\Route\\Router","type":"->","args":["/apps/richdocuments/index"]},{"file":"/usr/local/www/nextcloud/index.php","line":38,"function":"handleRequest","class":"OC","type":"::","args":[]}],"File":"/usr/local/www/nextcloud/3rdparty/guzzlehttp/guzzle/src/Handler/CurlFactory.php","Line":185,"CustomMessage":"--"},"userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.113 Safari/537.36","version":"18.0.3.0"}
{"reqId":"77P4RgIV9wDvGdwpsVu0","level":0,"time":"April 23, 2020 17:18:44","remoteAddr":"10.0.1.184","user":"ncadmin","app":"no app in context","method":"GET","url":"/index.phpiew?fileId=67826&c=d509a425972e4e5af849d29dd2ef613d&x=500&y=500&forceIcon=0","message":"Deprecated event type for OCP\\IPreview:PreviewRequested: Symfony\\Component\\EventDispatcher\\GenericEvent","userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.113 Safari/537.36","version":"18.0.3.0"}

So two things about this. One, are you absolutely sure this name is going to resolve correctly to the IP of the Collabora server? That looks very suspect to me.

And two, you’re getting SSL errors, but here you’ve told it to proxy via HTTP instead of HTTPS. Which way are you going with this? Everything has to be consistently configured, and you also have to tell Collabora internally whether it will be disabling HTTPS. See the environment variables here:

https://www.collaboraoffice.com/code/docker/

ok here is my “misconception”
I created entries in nginx as reverse proxy for several apache vhosts running PHP apps. Nextcloud among them.
I also have a native collabora installed. For this an Apache entry was made under the vhosts with all Apache proxy settings according to this:
https://www.collaboraoffice.com/code/apache-reverse-proxy/

My idea was to do exactly the same as with the Apache vhosts running PHP apps.

  • do not change request header
  • do not change response header
  • allow whatever file size
  • pass the remote IP
    Simply said, do not temper with anything whenever possible

That did not work with Collabora.
And I did not need to.
Since Collabora is running under its own port I could actually copy the whole of the nginx rules as in https://www.collaboraoffice.com/code/nginx-reverse-proxy/ and change it to the respective IP

thanks to KarlF12… after rereading it struck me…

This works… I am bypassing the Apache hosts file using the nginx from the outside.

I kept the Apache vhost file and the entry in the local DNS though… whatever NextCloud needs from it locally, it can get it locally… probably nothing but it allows me to revert when ever I want.

My local DNS points to the local IP of my reverse proxy. I use it even on my own LAN, and this setup works great.

Yes I’m absolutely sure it will resolve.

upstream collabora {
    server office.domain.com:9980;
}

proxy_pass http://collabora;

To prove the point, here is the collabora administration window:

In terms of http vs https – yes that’s my point (I’ve been harping about this all along since it doesn’t make sense) – I’m passing via http to the upstream server - the encrypted tls communication ends at the reverse proxy.

Here is the relevant portion of my docker-compose file again:

environment:
  - TZ=America/Chicago
  - username=admin
  - password=dockercol
  - domain=nextcloud\.domain\.com
  - cert_domain=office.domain.com
  - DONT_GEN_SSL_CERT="True"
  - server_name=test.domain.com
  - extra_params=--o:ssl.enable=false --o:ssl.termination=true

Again I’m unclear totally what to set for the domain, and server_name entries. I set domain as the host of nextcloud and the server_name as the reverse proxy name…I’m not even sure if I need all of these entries. I could take the cert_domain out as no certs are being generated as I didn’t enable ssl.

And thanks for looking at this – nothing makes sense to me. Particularly if I use the exact same parameters and just run the reverse proxy on the same machine as collabora.

And what’s bother me — entries within the Nextcloud Collabora setup.

Entries that work within the field URL (and Port) of Collabora Online-server

Entries that don’t work:

The collabora admin interface works when specifying any of the above. The document server is the portion that fails.

I haven’t used cert_domain or DONT_GEN_SSL_CERT. As I understand it, domain references the Nextcloud FQDN and server_name references the Collabora CODE server. With the extra_params specified, is DONT_GEN_SSL_CERT benign? Is the discussion BUG: DONT_GEN_SSL_CERT doesnt work of any significance here?