Table of Contents
This tutorial explains how to set up an Apache reverse proxy to access different applications running on your own server using different subdomains.
Preprequisites
- Root access (via SSH) to a Linux Server (VPS, Dedicated Server, Home Serve)
- A domain name (free or bought)
1. Get a domain name
You can either get a free domain name from providers such as ClouDNS, or buy one, e.g. from hosting companies such as Hostinger.
2. Add CNAME DNS entries for each subdomain
Add a CNAME entry for each subdomain required. Assuming that you want to run a regular Apache website, a WordPress blog, and a Nextcloud server on the same machine, we want to point the host “blog” and “cloud” to our domain name as follows:
Also make sure to select a low TTL (time to live) time which allows you to quickly change the CNAME entries of you need to. You can then set a higher TTL once you have got everything set up.
3. Setup the Apache reverse proxy
You can now add your subdomain names in the 000-default.conf file to route your subdomains to different directories or applications running on your server.
First, you simply want to add a virtual host block for the regular domain:
<VirtualHost *:80>
ServerName yourdomain.com
ServerAdmin webmaster@yourdomain.com
DocumentRoot /var/www/html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
If you are running Nextcloud as a regular installation and you want to route the domain cloud.yourdomain.com to it, you need to add the following virtual host block:
<VirtualHost *:80>
ServerName cloud.yourdomain.com
ServerAdmin webmaster@yourdomain.com
DocumentRoot /var/www/html/nextcloud
<Directory /var/www/html/nextcloud/>
Options +FollowSymlinks
AllowOverride All
<IfModule mod_dav.c>
Dav off
</IfModule>
SetEnv HOME /var/www/html/nextcloud
SetEnv HTTP_HOME /var/www/html/nextcloud
RewriteEngine On
RewriteRule ^/\.well-known/carddav http://%{SERVER_NAME}/remote.php/dav/ [R=301,L]
RewriteRule ^/\.well-known/caldav http://%{SERVER_NAME}/remote.php/dav/ [R=301,L]
RewriteRule ^/\.well-known/host-meta http://%{SERVER_NAME}/public.php?service=host-meta [QSA,L]
RewriteRule ^/\.well-known/host-meta\.json http://%{SERVER_NAME}/public.php?service=host-meta-json [QSA,L]
RewriteRule ^/\.well-known/webfinger https://%{SERVER_NAME}/public.php?service=webfinger [QSA,L]
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
Furthermore, you need to edit the config file to allow connections to Nextcloud on the new domain:
<?php
$CONFIG = array (
...
'trusted_domains' =>
array (
0 => 'https://cloud.yourdomain.com',
),
);
If you are running Nextcloud as a snap instance however, the required block is slightly different. Note that in this case we use the ProxyPass and ProxyPassReverse directives to route access on the subdomain to the snap instance:
<VirtualHost *:80>
ServerName cloud.yourdomain.com
ServerAdmin webmaster@yourdomain.com
ProxyPreserveHost On
ProxyRequests Off
RewriteEngine On
RewriteRule ^/\.well-known/carddav http://%{SERVER_NAME}/remote.php/dav/ [R=301,L]
RewriteRule ^/\.well-known/caldav http://%{SERVER_NAME}/remote.php/dav/ [R=301,L]
RewriteRule ^/\.well-known/host-meta http://%{SERVER_NAME}/public.php?service=host-meta [QSA,L]
RewriteRule ^/\.well-known/host-meta\.json http://%{SERVER_NAME}/public.php?service=host-meta-json [QSA,L]
RewriteRule ^/\.well-known/webfinger http://%{SERVER_NAME}/public.php?service=webfinger [QSA,L]
ProxyPass / http://localhost:81/
ProxyPassReverse / http://localhost:81/
</VirtualHost>
Additionally, you must change the default port on which the nextcloud snap is running, e.g. to port 81 as we need must use port 80 to accept un-encrypted connections to our server.
sudo snap set nextcloud ports.http=81
Again, you need to add this domain to your trusted domains
<?php
$CONFIG = array (
...
'trusted_domains' =>
array (
0 => 'https://cloud.yourdomain.com',
),
);
Finally, if you want to link to another applications, e.g. a wiki running under port 8080 this would be the required virtual host block:
<VirtualHost *:80>
ServerName wiki.yourdomain.com
ServerAdmin webmaster@yourdomain.com
ProxyPreserveHost On
ProxyRequests Off
ProxyPass / http://localhost:8080/
ProxyPassReverse / http://localhost:8080/
</VirtualHost>
As a next step, I would highly recommend you to secure your traffic using an SSL certificate! Check out this follow up guide on how to set up a Free Wildcard SSL Certificate for Nextcloud and WordPress.
Thank you very much, it is the only description I found of explicitly for configuring specifically nextcloud snap virtual host for apache. Nonetheless after editing the 000-default.conf file with the virtual host for the regular domain and the one for nextcloud snap, apache2 won’t restart: running systemctl restart apache2, I get an error message:
“Job for apache2.service failed because the control process exited with error code.
See “systemctl status apache2.service” and “journalctl -xe” for details.”
I don’t nknow what to do now. I checked again all the 000-default.conf file but without finding any mistake. If you’d had an idea, it would be much appreciated. Thanks in advance!
Hi Roman,
It took me three weeks, from never had set-up a server to have a Lychee and Next cloud running in parallel. Both with an SSL certificate.
I would not have been able to do that if it had not been for countless hours I spent both on your channel and on this website,
Thank you!
I will make sure to check out your merchandise, or patreon if you have one.
Danke, Merci!
This makes me so happy, thank you so much for your kind feedback 🙂
Hello Roman,
Thanks a lot for the effort you made with your channel and with your youtube channel. It has been a very good source for me. Still I have got an issue with my install and I can not find the solution. Maybe you can help.
Ubuntu: 20.01 LTS
Nexcloud install with snap
Followed commands:
$ sudo snap install nextcloud
$ sudo nextcloud.manual-install admin ###password###
$ sudo snap set nextcloud ports.http=81
$ sudo nextcloud.occ config:system:set trusted_domains 0 –value=https://cloud.mydomain.com
$ sudo snap connect nextcloud:removable-media
$ sudo nano /var/snap/nextcloud/current/nextcloud/config/config.php
–> I changed the data directory to the one that I use
$ sudo nano /etc/apache2/sites-available/000-default.conf
–> Here I pasted your code sniplet. Here I display my complete 000-default.conf (because I think the problem probably here). Ps: I am also running a jellyfin service @ jellyfin.mydomain.nl (that on works). On my host server I made 2 CNAME entries: 1= cloud@mydomain.nl and 2=jellyfin@mydomain.nl
ServerName mydomain.nl
ServerAdmin webmaster@mydomain.nl
DocumentRoot /var/www/html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
ServerName jellyfin.mydomain.nl
# Uncomment for HTTP to HTTPS redirect
# Redirect permanent / https://DOMAIN_NAME
ErrorLog /var/log/apache2/DOMAIN_NAME-error.log
CustomLog /var/log/apache2/DOMAIN_NAME-access.log combined
# If you are not using a SSL certificate, replace the ‘redirect’
# line above with all lines below starting with ‘Proxy’
ServerName jellyfin.mydomain.nl
# This folder exists just for certbot(You may have to create it, chown and chm>
DocumentRoot /var/www/html/jellyfin/public_html
ProxyPreserveHost On
# Letsencrypt’s certbot will place a file in this folder when updating/verifyi>
# This line will tell apache to not to use the proxy for this folder.
ProxyPass /.well_known/ !
ProxyPass “/socket” “ws://127.0.0.1:8096/socket”
ProxyPassReverse “/socket” “ws://127.0.0.1:8096/socket”
ProxyPass “/” “http://127.0.0.1:8096/”
ProxyPassReverse “/” “http://127.0.0.1:8096/”
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/mydomain.nl/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/mydomain.nl/privkey.pem
Protocols h2 http/1.1
# Enable only strong encryption ciphers and prefer versions with Forward Secre>
SSLCipherSuite HIGH:RC4-SHA:AES128-SHA:!aNULL:!MD5
SSLHonorCipherOrder on
# Disable insecure SSL and TLS versions
SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
ErrorLog /var/log/apache2/jellyfin.mydomain.nl-error.log
CustomLog /var/log/apache2/jellyfin.mydomain.nl-access.log combined
# nextcloud
ServerName cloud.mydomain.nl
ServerAdmin webmaster@mydomain.nl
ProxyPreserveHost On
ProxyRequests Off
RewriteEngine On
RewriteRule ^/\.well-known/carddav http://%{SERVER_NAME}/remote.php/dav/ [>
RewriteRule ^/\.well-known/caldav http://%{SERVER_NAME}/remote.php/dav/ [R>
RewriteRule ^/\.well-known/host-meta http://%{SERVER_NAME}/public.php?serv>
RewriteRule ^/\.well-known/host-meta\.json http://%{SERVER_NAME}/public.ph>
RewriteRule ^/\.well-known/webfinger http://%{SERVER_NAME}/public.php?serv>
ProxyPass / http://localhost:81/
ProxyPassReverse / http://localhost:81/
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
======================
I really hope you can help me becaus it drives me crazy!
Thanks a lot!
hope you found a solution since then! I’m also kind of getting crazy right now 🙂 In my case, the server refused to start because of an error. I could debug with “sudo apachectl configtest” which allowed me to find out that apache modules were missing in my installation. Furthermore, I think it is goot to leave the original virtual host block in 000-default.conf. Maybe it helps to sort out cases where no domain name is given in the header of the request to the server (?)
Hello!
First of all: great job with these tutorials! Thank you!
I’m installing my own server at home and I’m learning a lot of stuff; your videos and tutorials are awesome.
May you explain a little why do you need the “RewriteRule” statements with Nextcloud??
Thank you again!
Glad you like them!
The first two rewrite rules are required if you want to access your calendar or contacts using a different client (mail, android sync). The others are needed to avoid getting some error messages in Nextcloud but frankly I forgot what exactly they are needed for. Not that you don’t need them, Nextcloud works just fine without any rewrite rules but not all features will work correctly.