HOWTO - What to do for having Nextcloud / OnlyOffice on the same host?

Hello to the Community,

I will write here some tips you should know for having OnlyOffice working on the same host as your Nextcloud instance if you’re using APACHE2 as a WebServer.

I didn’t find a tutorial about this case, they’re all speaking about Ngnix

So what do you need first :

Apache2
A working Nextcloud Instance with SSL
Docker
Some RAM in your computer

I’m on a Debian/Ubuntu server.
First of all lets enable the Apache modules you will need with some commands :

a2enmod proxy
a2enmod proxy_wstunnel
a2enmod proxy_http
a2enmod headers

Then a little bit of pre-work about your installation :
Let says your nextcloud instance is on that URL : mycloud.mydomain.com
We want to create another subdomain like this : myoffice.mydomain.com
So first you have to go to your DNS configuration of your Domain provider to add this host, do the same that you did for your nextcloud instance.
On the system we will modify a file for letting the system know that myoffice.mydomain.com is itself :
Modify this file with nano/vi/vim whatever you know best :
nano /etc/hosts
and add/modify the first line to have something like this :

127.0.0.1 localhost mycloud.mydomain.com myoffice.mydomain.com

save and exit

Now a big task to do, create an Apache2 Virtual host for myoffice.mydomain.com,
create with nano/vi/vim whatever this file :

nano /etc/apache2/sites-avialable/myoffice.conf

And Modify the file depending of your domain :

<VirtualHost *:80>
ServerName myoffice.mydomain.com
RewriteEngine on
RewriteCond %{SERVER_NAME} =myoffice.mydomain.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]

Now we will enable this virtual host :

a2ensite myoffice.conf
service apache2 reload

Now you have to create the same host for the SSL version, so you have to create Cert as you want with LetsEncrypt or Verisign etc… (follow some tutos if you want to use LetsEncrypt if you’re a newbie)

When you have your certs, lets create or modify the SSL version of myoffice.conf. As i use LetsEncrypt it created and enabled automaticly this myoffice-le-ssl.conf

Servername myoffice.mydomain.com

SSLEngine on
SSLCertificateFile “/etc/letsencrypt/live/myoffice.mydomain.com/fullchain.pem” #Change with the right path
SSLCertificateKeyFile “/etc/letsencrypt/live/myoffice.mydomain.com/privkey.pem” #Change with the right path

SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH
SSLProtocol All -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
SSLCompression off
SSLHonorCipherOrder on

Header always set Strict-Transport-Security “max-age=15768000; includeSubDomains”

SetEnvIf Host “^(.*)$” THE_HOST=$1
RequestHeader setifempty X-Forwarded-Proto https
RequestHeader setifempty X-Forwarded-Host %{THE_HOST}e
ProxyAddHeaders Off

ProxyPassMatch (.*)(/websocket)$ “ws://127.0.0.1/$1$2”
ProxyPass / “http://127.0.0.1/
ProxyPassReverse / “http://127.0.0.1

Save and reload apache2, don’t forget to enable this site if it isn’t the case :

a2ensite myoffice-le-ssl.conf
service apache2 reload

Now lets get the docker image :

docker pull onlyoffice/documentserver

Wait a moment, now we have to create some folders to map with the docker instance of DocumentServer for ease of use, and to update without pain the docker image.

mkdir /app

(it’s my exemple, you can create this folder where you want but don’t forget to follow my tuto with this modification)

Now lets start the Docker image :

docker run -i -t -d -p 80:80 --restart always -v /app/onlyoffice/DocumentServer/logs:/var/log/onlyoffice -v /app/onlyoffice/DocumentServer/data:/var/www/onlyoffice/Data -v /app/onlyoffice/DocumentServer/lib:/var/lib/onlyoffice -v /app/onlyoffice/DocumentServer/db:/var/lib/postgresql onlyoffice/documentserver

If you have errors because port 80 is already use, then modify the myoffice-le-ssl.conf, the last line should look like this :

ProxyPassMatch (.*)(/websocket)$ “ws://127.0.0.1:81/$1$2”
ProxyPass / “http://127.0.0.1:81/
ProxyPassReverse / “http://127.0.0.1:81

And so the docker command line will be :

docker run -i -t -d -p 81:80 --restart always -v /app/onlyoffice/DocumentServer/logs:/var/log/onlyoffice -v /app/onlyoffice/DocumentServer/data:/var/www onlyoffice/Data -v /app/onlyoffice/DocumentServer/lib:/var/lib/onlyoffice -v /app/onlyoffice/DocumentServer/db:/var/lib/postgresql onlyoffice/documentserver

Now you should go to your Admin Nextcloud Instance,
Download the Onlyoffice App,
Go to your admin panel of Nextcloud → OnlyOffice page and configure it like this :
Document Editing Service address → https://myoffice.mydomain.com
DO NOT CLIC ON Advanced Settings, it’s useless for this setup and won’t work
Feel free to tick or untick the other boxes, and save.

Normaly it’s working

7 Likes

nice of you !

I concur for most of the procedure, having build a debian/apache/mysql/mdamd/lvm2/openssl/letsencrypt/http2/brotli/fail2ban/redis server.

The only thing is i am using a real server without docker.

Some tuning can be made on your ssl conf:
more secure SSLProtocol:
SSLProtocol All -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
Header always set Strict-Transport-Security "max-age=15768000; includeSubDomains"

modern cyphersuite excluding old unsecured browser
SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH

If your apache version is >= 2.4 then you can add some checking that your server certificate has not been revoked.

SSLUseStapling          on
SSLStaplingResponderTimeout 5
SSLStaplingReturnResponderErrors off
SSLStaplingCache        shmcb:/var/run/ocsp(128000)

Yes, i know, i am kind of paranoiac


if you have the prerequist add http2 for Apache >= 2.4 Hypertext Transfer Protocol/2 — Wikipédia

prerequist = openssl libssl1.0.2 libssl-dev apache2 apache2-bin apache2-data libnghttp2-14 with Apache >= 2.4

add this line below <VirtualHost *:443>
Protocols h2, h2c http/1.1
then
a2enmod http2
service apache2 restart


When all done, you can check your https security level by using the SSL Server Test (Powered by Qualys SSL Labs) tools

A%20

AND … HTTP/2 Test - Verify HTTP/2 Support | KeyCDN Tools for http2/ALPN test:

1 Like

I moded my post with some of your advices,

I added the better sypher suite and module Headers for HSTS.

I didn’t add Checking if cert isn’t revoked because it needs a certain version of apache, nor the http/2 protocol because the first benchmark aren’t better for Nextcloud performances.

Thank you a lot

Hello NEmskiller,
I tried your TUTO. I think i’m nearly there. I’ve a problem with the proxy part. If I try to start Apache2 again, I get an error on the proxypass URL:

sep 16 21:14:40 t53n-nextcloud apachectl[5957]: AH00526: Syntax error on line 31
sep 16 21:14:40 t53n-nextcloud apachectl[5957]: ProxyPass Unable to parse URL: \
sep 16 21:14:40 t53n-nextcloud apachectl[5957]: Action 'start' failed.  

Line 31 of my office-ssl.conf contains:
ProxyPassMatch (.*)(/websocket)$ “ws://127.0.0.1/$1$2”

OnlyOffice is running, I have the 127.0.0.1/welcome screen.

Ok, This isn’t a problem anymore. I forgot the http:// bit in the lines below line 31.
I can start Apache2 now and OnlyOffice is still running.

The symptoms:

  • When I go to the URL https://office.mysite.nl. I get an error and the URL changes to: https://(null)/welcome
  • When I go to https://office.mysite.nl/healthcheck It returns ‘True’ in the browser and the browser URL stays intact.
  • The log on my Nextcloud instance when I try to save OnlyOffice settings: “file_get_contents(https://office.url.com/healthcheck): failed to open stream: Connection refused at /var/www/html/nextcloud/apps/onlyoffice/lib/documentservice.php#381”

Any ideas on this? Could it be a permission issue?

This is my conf file:

<IfModule mod_ssl.c>
<VirtualHost *:4433>
	ServerAdmin ****@protonmail.com
    Servername office.url.com

	DocumentRoot /var/www/onlyoffice
<IfModule mod_headers.c>
  Header always set Strict-Transport-Security "max-age=15552000; includeSubDomains"
</IfModule>
	ErrorLog ${APACHE_LOG_DIR}/error.log
	CustomLog ${APACHE_LOG_DIR}/access.log combined

	SSLEngine on
	SSLCertificateFile	/etc/ssl/certs/office.crt
	SSLCertificateKeyFile /etc/ssl/private/office.key

		SetEnvIf Host “^(.*)$” THE_HOST=$1
		RequestHeader setifempty X-Forwarded-Proto https
		RequestHeader setifempty X-Forwarded-Host %{THE_HOST}e
		ProxyAddHeaders Off

	SSLProxyEngine on
    ProxyPassMatch (.*)(/websocket)$ "ws://127.0.0.1/$1$2"
	ProxyPass / "http://127.0.0.1/"
	ProxyPassReverse / "http://127.0.0.1"

	<FilesMatch "\.(cgi|shtml|phtml|php)$">
			SSLOptions +StdEnvVars
	</FilesMatch>
	<Directory /usr/lib/cgi-bin>
			SSLOptions +StdEnvVars
	</Directory>

</VirtualHost>

Thank you very much for this awesome guide.
It worked for me without any issues. :+1:

However there is a small typo in the scipts above. In the starting command for the docker container there is a / missing between /app/onlyoffice/DocumentServer/data:/var/www and onlyoffice/Data

the correct command should be like

docker run -i -t -d -p 80:80 --restart always \
-v /app/onlyoffice/DocumentServer/logs:/var/log/onlyoffice \
-v /app/onlyoffice/DocumentServer/data:/var/www/onlyoffice/Data \
-v /app/onlyoffice/DocumentServer/lib:/var/lib/onlyoffice \
-v /app/onlyoffice/DocumentServer/db:/var/lib/postgresql onlyoffice/documentserver
1 Like

Hello !

Following exactly your instructions, I get a “ProxyPass Unable to parse URL” error on the following line :

ProxyPassMatch (.*)(/websocket)$ “ws://127.0.0.1:81/$1$2”

This doesn’t seem to be the same issue T53N encountered, since your instructions contain the http:// bit in the lines below.

I’m not getting anything on apache error log.

Could you give me a hand?

Edit : nevermind, seems to be working now after copying the same values from onlyoffice config page.

Strange.

Now I get some other errors, but the reverse proxy is working.

I Had the same problem for a few days and it drove me insane…
Anyway…

You have to comment out

#Header always set Strict-Transport-Security “max-age=15552000; includeSubDomains”

And

    #SetEnvIf Host “^(.*)$” THE_HOST=$1
	#RequestHeader setifempty X-Forwarded-Proto https
	#RequestHeader setifempty X-Forwarded-Host %{THE_HOST}e

Try that… And if you get an “Unknow Error” Please tell me to post the settings I had to add to fix it … There are many thing I changed in my apache config file that I do not remember them all… I have to get home to get them or I could SSH to my server but my break is almost over and I have to get back to work

Good luck

Thanks for your great tutorial. Since I don’t really know what I’m doing I had no idea where to start and your howto seems to be the only one matching my configuration, that I could find.

I did run into a few issues with it however. I’ll try to list them and my solutions here and hopefully they’ll help others following this HOWTO.

First of all I wasted a lot of time due to copy/paste issues until I realized, that the " characters where not getting copied/formated properly in editor vim. Nano does not seem to have the same issues. And all lines with the "s in them ran into errors. After manually inserting all the "s things worked.

The second issue I had is that your docker command did not work for me either. Thank fully the command that @darioce kindly provied worked.

You likely ran into the same issue I did with the "s not being copied properly and therefore breaking all the lines with them.

I would question whether disabling HSTS is a reasonable fix for an issue.

Try this:
Nextcloud and onlyoffice working in a debian server with lets`encrypt. Working!

Im running your exact Setup from the first post. After i found all the "s and replaced them the office server was available and i was able to add the server in the Settings of Nextcloud. Now my only problem remains that when i open a document to edit i get the following error message “ONLYOFFICE cannot be reached. Please contact admin” There is no additional information in the Logging section. Do you have an idea on how to debug this? Or maybe even on how to fix it?

Info:
PHP: 2.7
Nextcloud and Onlyoffice on the same server.
Onlyoffice 16.04

Maybe you have problems with ports or the hostname of onlyoffice.
Contact me by MP if we can have a session together to troubleshoot this.

2 Likes

Hello

I would assume it is some problem with the host name but i am unsure what exactly the problem is.
I am available for a session if you have time. I’m in the TimeZone GMT +1 so i dont know how much difference there is between us! If you have time, i would be available today for the next 8 Hours.

Best
Linard

PS: I’m unable to send you a PM because i have no idea how to start a conversation. I searched everywhere ^^ sorry

I’m currently working through this as well. I have a slightly modified setup.

I got the docker image of the OnlyOffice server up and running, I can access it by ip, but I’m trying to set up the domain to redirect to it. I also have a subdomain properly set-up with DNS and SSL using certbot. I’m just struggling to get the right configuration working in apache2.

Currently when I visit my domain, I’m presented with a 400 Bad Request from ngnix (which means the proxy redirect worked on apache’s behalf). It says “The plain HTTP request was sent to HTTPS port”

Here’s my virtualhost config:

<VirtualHost *:80>
	ServerName office.chillstice.com
	ServerAlias www.office.chillstice.com
	DocumentRoot /var/www/office/public_html

	RewriteEngine On
	RewriteCond %{HTTPS} !=on
	RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L] 
</VirtualHost>

<VirtualHost *:443>
	# The ServerName directive sets the request scheme, hostname and port that
	# the server uses to identify itself. This is used when creating
	# redirection URLs. In the context of virtual hosts, the ServerName
	# specifies what hostname must appear in the request's Host: header to
	# match this virtual host. For the default virtual host (this file) this
	# value is not decisive as it is used as a last resort host regardless.
	# However, you must set it for any further virtual host explicitly.
	#ServerName www.example.com

	ServerAdmin chris@chillstice.com
	ServerName office.chillstice.com
    ServerAlias www.office.chillstice.com
	DocumentRoot /var/www/office/public_html

    <Directory "/var/www/office/public_html">
        	Options Indexes FollowSymLinks
            AllowOverride All
			Require all granted
    </Directory>

	#RewriteEngine on
	#RewriteCond %{SERVER_NAME} =office.chillstice.com
	#RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]

    <IfModule mod_headers.c>
      Header always set Strict-Transport-Security "max-age=15552000; includeSubDomains"
    </IfModule>

	SSLEngine on
	SSLCertificateFile /etc/letsencrypt/live/office.chillstice.com/fullchain.pem
	SSLCertificateKeyFile /etc/letsencrypt/live/office.chillstice.com/privkey.pem
	Include /etc/letsencrypt/options-ssl-apache.conf

	SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH
	SSLProtocol All -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
	SSLCompression off
	SSLHonorCipherOrder on

	ProxyPassMatch (.*)(/websocket)$ "ws://127.0.0.1:8443/$1$2"
	ProxyPass / "http://127.0.0.1:8443"
	ProxyPassReverse / "http://127.0.0.1:8443"

	# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
	# error, crit, alert, emerg.
	# It is also possible to configure the loglevel for particular
	# modules, e.g.
	#LogLevel info ssl:warn

	ErrorLog ${APACHE_LOG_DIR}/error.log
	CustomLog ${APACHE_LOG_DIR}/access.log combined

	# For most configuration files from conf-available/, which are
	# enabled or disabled at a global level, it is possible to
	# include a line for only one particular virtual host. For example the
	# following line enables the CGI configuration for this host only
	# after it has been globally disabled with "a2disconf".
	#Include conf-available/serve-cgi-bin.conf
</VirtualHost>

# vim: syntax=apache ts=4 sw=4 sts=4 sr noet

@Chillstice
Ok I think I probably can help – but let me ask a couple of more questions

Is Your setup is like the following:

Internet—(Https) ----> Apache Reverse Proxy (SSL terminates here)------(HTTP)—>Docker Image

As I understand – you’d like to SSL to terminate at the proxy.

You’d also like any connection on port 80 to be automatically forwarded to port 443.

You also have LE certs for your domain.

Are these assumptions correct?

I have a feeling you’re totally right. I’m not exactly sure where the ssl connection terminates, but the error message indicates to me that the ssl encapsulation is terminated in Apache instead of getting forwarded - or however it’s supposed to work - through to the docker image and the ngnix server.

I do want SSL applied to as much of the chain as I can.
I do want http traffic on port 80 to be redirected to https traffic on 443 (side note I picked port 8443 for OnlyOffice)
And yes, I used LE with the standalone flag to generate the certs. I’m using the Apache config to dictate the chain and key. So I don’t have a *-le-ssl.conf

As far as I can tell, everything is configured correctly, but ngnix in the docker is complaining because of how the proxy is handling ssl traffic.

Ok just a few things in terms of SSL termination in relation to the reverse proxy.

#1. You need to make sure your apache (collabora issues aside) can accept HTTPS connections. Usually I test this with making an index.html within the document root and ensure I can use a computer outside the LAN (like a phone for example) to see if I can grab the page at https://<your_domain>.com.

#2. Assuming you’ve got your Apache configuration setup to accept https requests, SSL terminates at the proxy if you use ProxyPass and ProxyPassReverse lines that start with http:. If they start with https then the SSL connection is not terminating at the proxy. It appears through what you posted above your terminating the SSL at the proxy.

#3. How are you starting your docker collabora? What options are your passing it? Is ssl enabled or is it not? What are your docker options?

I̶ ̶g̶o̶t̶ ̶i̶t̶ ̶w̶o̶r̶k̶i̶n̶g̶.̶ I want to say something like ‘of course it was something this simple’ but there was more to it than that.

I had a typo in the config - you’re right - I really meant to forward the proxy to https://… instead of http. But it still wasn’t working at that point. I was getting some 502 errors.

[proxy_http:error] [pid 23637] [client 192.168.1.1:29042] AH01097: pass request body failed to 127.0.0.1:8443 (127.0.0.1) from 192.168.1.1 ()

I had to add the following lines to my config before the ProxyPass lines:

SSLProxyEngine on
SSLProxyVerify none
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off

EDIT: okay, weird. I got office.chillstice.com to forward to OnlyOffice with SSL and it reports that it’s working, but when trying to connect it to Nextcloud through the app, I get this error:

Error when trying to connect (Error occurred in the document service: Error while downloading the document file to be converted.)
onlyoffice	GetConvertedUri on check error: Error occurred in the document service: Error while downloading the document file to be converted.

Is it bad that there’s just a self-signed cert for https://127.0.0.1:8443 and only the domain redirect has a valid cert?

curl https://127.0.0.1:8443/healthcheck
curl: (60) SSL certificate problem: self signed certificate
More details here: https://curl.haxx.se/docs/sslcerts.html

curl https://office.chillstice.com/healthcheck
true

EDIT:
Now I think my issue is rooted from how I’m running the docker container. Here’s my starting code right now:

sudo docker run -i -t -d -p 8443:443 --restart=always -v /app/onlyoffice/DocumentServer/logs:/var/log/onlyoffice -v /app/onlyoffice/DocumentServer/data:/var/www/onlyoffice/Data -v /app/onlyoffice/DocumentServer/lib:/var/lib/onlyoffice -v /app/onlyoffice/DocumentServer/db:/var/lib/postgresql onlyoffice/documentserver

I was experimenting with the following lines and couldn’t get a proper result:

--add-host=cloud.chillstice.com:my.public.ip
-e SSL_CERTIFICATE_PATH=/etc/letsencrypt/live/office.chillstice.com/fullchain.pem
-e SSL_KEY_PATH=/etc/letsencrypt/live/office.chillstice.com/fullchain.pem

Also for whatever reason when I try to run the container with a name, it refuses to start:

--name onlyoffice

I think the ngnix server is running without ssl, but I need it to run with ssl because the rest of the chain has it enabled. How can I resolve this?

Ok a few things. If you are trying to run https all the way to proxy, then you are not terminating SSL at the reverse proxy, but rather at the docker instance. Make sure within your Apache Virtual Host file you are Proxying and Reverse proxying to either https or wss locations.

Docker instance – you have a lot of variables within the startup command for your docker instance. That’s OK its just I’m not familiar with some of them.

I initiate my docker instance with the following: run --sysctl net.ipv6.conf.all.disable_ipv6=1 --sysctl net.ipv6.conf.default.disable_ipv6=1 -t -d -p 9980:9980 -e ‘domain=nextcloud\.example\.com’ --name=“jax” -e “username=admin” -e “password= docker col” -e “extra_params=–o:ssl.enable=true” --restart always --cap-add MKNOD collabora/code:latest

I’m starting collabora and you’re starting onlyoffice so I’m not sure exactly the parameters you need. You might want to check – however some things to ponder.

ssl.enable=true for me means that the docker instance is going to terminate the SSL connection. It also means collabora is going to generate some fake dummy SSL certs. You’ll get an encrypted connection between reverse proxy but you won’t verify authenticity of the certs:
SSLProxyVerify none
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off
These statements mean don’t verify the public cert issued by the docker container — (usually you don’t want to do this however for at least collabora – this is what they say). Because dummy certs are being generated you don’t need to copy your own certs into the container. DO NOT add your own keys (BTW – You SSL_KEY_PATH is wrong – its should be privkey.pem and not fullchain.pem) – You don’t need those lines anyway. Your add host line is also wrong. Its going to be the domain name of the host where you are running Nextcloud. I don’t think you need to append your public IP to the statement. In most cases you want your nextcloud domain name to actually resolve to a LAN ip address and not public ip address. You might need to add a DNS override to your router to accomplish this or add an entry into the /etc/hosts file on the docker machine so it knows what local IP is associated with the machine running nextcloud.