How to properly configure nextcloud to set-up a subdomain

Nextcloud version : 23.0.4
Operating system and version : Debian GNU/Linux 10 (buster)
Apache or nginx version : Apache/2.4.38 (Debian)
PHP version : 8.0

Hello everyone,

I’m trying to access my nextcloud instance via a subdomain.
For now accessing using mydomain.com/nextcloud but cloud.mydomain.com redirects to the Apache2 Debian Default Page.

I’ve followed a few threads on this forum (mainly this one) to try and get it working, it helped me get further but I’m still missing a piece of the puzzle it seems.

I’ve tried many things for this project but also for other things on my server and so I know that my Virtual Hosts files are really messy and there must be something not right in there. I don’t know much about how to set them up properly and so I can’t find my mistake but I would really like a little bit of help to better understand what is going on whith them.

First I have 5 of them, which might not be ideal (?). A default one, one for my webpage (mydomain.com/index.html) and one for nextcloud, then they all have an ssl version except for the NextCloud one.

The first default file (default.conf) :

<VirtualHost *:80>
	ServerName cloud.mydomain.com
	ServerAlias www.mydomain.com

	ServerAdmin webmaster@localhost
	DocumentRoot /var/www/html

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

	RewriteEngine on
	RewriteCond %{SERVER_NAME} =www.mydomain.com [OR]
	RewriteCond %{SERVER_NAME} =cloud.mydomain.com
	RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>

SSL version (default-le-ssl.conf) :
<IfModule mod_ssl.c>

	<VirtualHost *:443>
		ServerName cloud.mydomain.com
		ServerAlias www.mydomain.com

		ServerAdmin webmaster@localhost
		DocumentRoot /var/www/html

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

		SSLCertificateFile /etc/letsencrypt/live/cloud.mydomain.com-0001/fullchain.pem
		SSLCertificateKeyFile /etc/letsencrypt/live/cloud.mydomain.com-0001/privkey.pem
		Include /etc/letsencrypt/options-ssl-apache.conf
	</VirtualHost>
</IfModule>

For my website (on www.mydomain.com/index.html) (001-mydomain.conf) :
<VirtualHost *:80>
	Redirect permanent / https://mydomain.com
</VirtualHost>

SSL version (001-mydomain-ssl.conf) :
<VirtualHost *:443>

	ServerAdmin webmaster@localhost
	Servername mydomain.com
	ServerAlias www.mydomain.com
		DocumentRoot /var/www/html/mydomain
		<Directory "/var/www/html/mydomain/">
			Options -Indexes
			Options +FollowSymlinks
			<Limit PUT DELETE OPTIONS CONNECT TRACK>
				Order deny,allow
				Deny from all
			</Limit>
			<Files .htaccess>
				Order allow,deny
				Deny from all
			</Files>
			RewriteEngine On
			RewriteCond %{REQUEST_FILENAME} !-d
			RewriteCond %{REQUEST_FILENAME} !-f
			RewriteCond %{REQUEST_FILENAME}.php -f
			RewriteRule ^(.*)$ $1.php
        </Directory>

	<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
	SSLProxyengine on
	SSLProtocol -ALL -TLSv1 -TLSv1.1 +TLSv1.2
	SSLHonorCipherOrder On
	SSLCompression off
	SSLSessionTickets off

	ErrorDocument 400 /error/error_400.html

	SSLCertificateFile /etc/letsencrypt/live/mydomain.com/fullchain.pem
	SSLCertificateKeyFile /etc/letsencrypt/live/mydomain.com/privkey.pem
	Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>

Then, the one for nextcloud :
Alias /nextcloud "/var/www/nextcloud/"

#ServerName cloud.mydomain.com
#DocumentRoot /var/www/nextcloud

#ErrorLog /var/log/apache2/cloud.mydomain.com-error.log
#CustomLog /var/log/apache2/cloud.mydomain.com-access.log common

<Directory /var/www/nextcloud/>
  Options +FollowSymlinks
  AllowOverride All

  #Require all granted
  #AllowOverride All
  #Options FollowSymLinks MultiViews

  <IfModule mod_dav.c>
    Dav off
  </IfModule>

  <IfModule mod_headers.c>
    Header set Referrer-Policy no-referrer
    Header always set Strict-Transport-Security "max-age=15768000; includeSubDomains; preload"
  </IfModule>

  SetEnv HOME /var/www/nextcloud
  SetEnv HTTP_HOME /var/www/nextcloud

</Directory>

Redirect 301 /.well-known/carddav /nextcloud/remote.php/dav
Redirect 301 /.well-known/caldav /nextcloud/remote.php/dav
Redirect 301 /.well-known/webfinger "/nextcloud/index.php/.well-known/webfinger"
Redirect 301 /.well-known/nodeinfo "/nextcloud/index.php/.well-known/nodeinfo"

And finally the config.php file (nextcloud/config/config.php) :
<?php
$CONFIG = array (
  'instanceid' => 'NNNNNNNNNNNNNNNNNNNNNN',
  'passwordsalt' => 'NNNNNNNNNNNNNNNNNNNNNN',
  'secret' => 'NNNNNNNNNNNNNNNNNNNNNN',
  'trusted_domains' => 
  array (
    0 => 'mydomain.com',
    1 => 'cloud.mydomain.com',
  ),
  'default_phone_region' => 'FR',
  'datadirectory' => '/var/www/nextcloud/data',
  'dbtype' => 'mysql',
  'version' => '23.0.4.1',
  'overwrite.cli.url' => 'https://mydomain.com/nextcloud',
  'htaccess.RewriteBase' => '/nextcloud',
  'dbname' => 'nextcloud',
  'dbhost' => 'localhost',
  'dbport' => '',
  'dbtableprefix' => 'oc_',
  'mysql.utf8mb4' => true,
  'dbuser' => 'nextcloud',
  'dbpassword' => 'NNNNNNNNNNNNNNNNNNNNNN',
  'installed' => true,
  'memcache.local' => 'OC\\Memcache\\APCu',
  'mail_smtpmode' => 'smtp',
  'mail_sendmailmode' => 'smtp',
  'mail_smtpauthtype' => 'LOGIN',
  'mail_smtpauth' => 1,
  'has_rebuilt_cache' => true,
  'mail_smtpport' => '587',
  'mail_smtpname' => 'myemail@email.com',
  'mail_smtppassword' => 'NNNNNNNNNNNNNNNNNNNNNN',
  'mail_smtpsecure' => 'tls',
  'mail_smtphost' => 'smtp-relay.sendinblue.com',
  'maintenance' => false,
  'theme' => '',
  'loglevel' => 2,
);

The DNS record part seem to be ok since I get the debian default page.

I apologize for the lengthy post but I am really not sure where the problem can come from.
Thank you to anyone who takes the time to read that and provide some pointer on finding my mistake.

Have a nice day everyone.

you must change overal servername to domain.org

and have serveralias point to cloud.domain.org

in default-le-ssl.conf you point to servername cloud but document root is /var/www/html

here is a example for hosting only cloud.example.org nextcloud.conf

<VirtualHost *:80>
   Redirect permanent / https://cloud.example.org/
   ServerName example.org
   DocumentRoot /var/www/nextcloud
       ServerAlias cloud.example.org
</VirtualHost>

<IfModule mod_ssl.c>
   <VirtualHost *:443>
   	DocumentRoot /var/www/nextcloud
   	ServerName example.org
               ServerAlias cloud.example.org

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

   	<FilesMatch "\.(cgi|shtml|phtml|php)$">
   			SSLOptions +StdEnvVars
   	</FilesMatch>

   	<Directory /usr/lib/cgi-bin>
   			SSLOptions +StdEnvVars
   	</Directory>

   	<Directory /var/www/nextcloud>
   			Options +FollowSymlinks
   			AllowOverride All
                               SetEnv HOME /var/www/nextcloud
                               SetEnv HTTP_HOME /var/www/nextcloud

   		<IfModule mod_dav.c>
   		  Dav off
   		</IfModule>
   	</Directory>

               <IfModule mod_headers.c>
                         Header always set Strict-Transport-Security "max-age=15768000; includeSubDomains"
               </IfModule>
           Include /etc/letsencrypt/options-ssl-apache.conf
           SSLCertificateFile /etc/letsencrypt/live/cloud.example.org/fullchain.pem
           SSLCertificateKeyFile /etc/letsencrypt/live/cloud.example.org/privkey.pem
</VirtualHost>
</IfModule>

another sub-domain blog.conf

<VirtualHost *:80>
   ServerName blog.example.org
   ServerAlias blog.example.org
   DocumentRoot /var/www/html/blog
</VirtualHost>

<Directory /var/www/html/blog/>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
</Directory>

<IfModule mod_ssl.c>

	<VirtualHost *:443>
		ServerAdmin admin@example.org
		DocumentRoot /var/www/html/blog
		ServerName blog.example.org
		ServerAlias blog.example.org

		SSLEngine on
                SSLCertificateFile      /etc/letsencrypt/live/www.example.org/fullchain.pem
                SSLCertificateKeyFile   /etc/letsencrypt/live/www.example.org/privkey.pem
                Include /etc/letsencrypt/options-ssl-apache.conf
	</VirtualHost>
#    <FilesMatch ".+\.ph(ar|p|tml)$">
#        SetHandler "proxy:unix:/run/php/php5.6-fpm.sock|fcgi://localhost/"
#    </FilesMatch>

</IfModule>

all other to this domain default.conf

<VirtualHost _default_:80>
    ServerName example.org
    ServerAlias www.example.org
    DocumentRoot /var/www/html

    ErrorDocument 400 /ErrorPages/HTTP400.php
    ErrorDocument 401 /ErrorPages/HTTP401.php
    ErrorDocument 403 /ErrorPages/HTTP403.php
    ErrorDocument 404 /ErrorPages/HTTP404.php
    ErrorDocument 500 /ErrorPages/HTTP500.php
    ErrorDocument 501 /ErrorPages/HTTP501.php
    ErrorDocument 502 /ErrorPages/HTTP502.php
    ErrorDocument 503 /ErrorPages/HTTP503.php
#    ErrorDocument 520 /ErrorPages/HTTP520.php
#    ErrorDocument 521 /ErrorPages/HTTP521.php
#    ErrorDocument 530 /ErrorPages/HTTP530.php
</VirtualHost>

<IfModule mod_ssl.c>

	<VirtualHost *:443>
		ServerAdmin admin@example.org

		DocumentRoot /var/www/html
		ServerName www.example.org
		ServerAlias www.example.org
		ErrorLog ${APACHE_LOG_DIR}/error.log
		CustomLog ${APACHE_LOG_DIR}/access.log combined

		<FilesMatch "\.(cgi|shtml|phtml|php|html)$">
				SSLOptions +StdEnvVars
                                # Below for php-fpm
#                                SetHandler "proxy:unix:/var/run/php/php7.4-fpm.sock|fcgi://localhost"
		</FilesMatch>

		<Directory /usr/lib/cgi-bin>
				SSLOptions +StdEnvVars
	        </Directory>

                #   SSL Engine Switch:
                #   Enable/Disable SSL for this virtual host.
                SSLEngine on
		SSLCertificateFile	/etc/letsencrypt/live/www.example.org/fullchain.pem
		SSLCertificateKeyFile   /etc/letsencrypt/live/www.example.org/privkey.pem
                Include /etc/letsencrypt/options-ssl-apache.conf
	</VirtualHost>
</IfModule>

Editing yours

The first default file (default.conf) :

<VirtualHost *:80>
	ServerName mydomain.com
	ServerAlias www.mydomain.com

	ServerAdmin webmaster@localhost
	DocumentRoot /var/www/html/mydomain

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

	RewriteEngine on
	RewriteCond %{SERVER_NAME} =www.mydomain.com [OR]
	RewriteCond %{SERVER_NAME} =cloud.mydomain.com  # Cannot say about this one.
	RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
        Redirect permanent / https://mydomain.com # disable file 001-mydomain.conf
</VirtualHost>

SSL version (default-le-ssl.conf) :

<IfModule mod_ssl.c>

	<VirtualHost *:443>
		ServerName mydomain.com
		ServerAlias www.mydomain.com

		ServerAdmin webmaster@localhost
		DocumentRoot /var/www/html/mydomain

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

		SSLCertificateFile /etc/letsencrypt/live/cloud.mydomain.com-0001/fullchain.pem
		SSLCertificateKeyFile /etc/letsencrypt/live/cloud.mydomain.com-0001/privkey.pem
		Include /etc/letsencrypt/options-ssl-apache.conf
	</VirtualHost>
</IfModule>

above 2 can be one file just add <IfModule mod_ssl.c> before the virtualhost *:443 and close </IfModule> at the end like the examples above

For my website (on www.mydomain.com/index.html) (001-mydomain.conf) :

<VirtualHost *:80>
	Redirect permanent / https://mydomain.com # Place this line in default
</VirtualHost>

disable this one

SSL version (001-mydomain-ssl.conf) : Wonder what your server is serving

<VirtualHost *:443>

	ServerAdmin webmaster@localhost
	Servername mydomain.com
	ServerAlias www.mydomain.com
		DocumentRoot /var/www/html/mydomain
		<Directory "/var/www/html/mydomain/">
			Options -Indexes
			Options +FollowSymlinks
			<Limit PUT DELETE OPTIONS CONNECT TRACK>
				Order deny,allow
				Deny from all
			</Limit>
			<Files .htaccess>
				Order allow,deny
				Deny from all
			</Files>
			RewriteEngine On
			RewriteCond %{REQUEST_FILENAME} !-d
			RewriteCond %{REQUEST_FILENAME} !-f
			RewriteCond %{REQUEST_FILENAME}.php -f
			RewriteRule ^(.*)$ $1.php
        </Directory>

	<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
	SSLProxyengine on
	SSLProtocol -ALL -TLSv1 -TLSv1.1 +TLSv1.2
	SSLHonorCipherOrder On
	SSLCompression off
	SSLSessionTickets off

	ErrorDocument 400 /error/error_400.html

	SSLCertificateFile /etc/letsencrypt/live/mydomain.com/fullchain.pem
	SSLCertificateKeyFile /etc/letsencrypt/live/mydomain.com/privkey.pem
	Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>

This looks like your website but you have 2 defaults setup that listen to www…mydomain.com:443

SSL version (001-mydomain-ssl.conf) :
SSL version (default-le-ssl.conf) : # Disable this one # > a2dissite def[TAB]-[TAB]

Then, the one for nextcloud :

<VirtualHost *:80>
   Redirect permanent / https://cloud.mydomain.com/
   ServerName mydomain.com
   DocumentRoot /var/www/nextcloud
       ServerAlias cloud.mydomain.com
</VirtualHost>

<IfModule mod_ssl.c>
<VirtualHost *:443>

ServerName mydomain.com
ServerAlias cloud.mydomain.com
DocumentRoot /var/www/nextcloud

#ErrorLog /var/log/apache2/cloud.mydomain.com-error.log
#CustomLog /var/log/apache2/cloud.mydomain.com-access.log common

<Directory /var/www/nextcloud/>
  Options +FollowSymlinks
  AllowOverride All

  #Require all granted
  #AllowOverride All
  #Options FollowSymLinks MultiViews

  <IfModule mod_dav.c>
    Dav off
  </IfModule>

  <IfModule mod_headers.c>
    Header set Referrer-Policy no-referrer
    Header always set Strict-Transport-Security "max-age=15768000; includeSubDomains; preload"
  </IfModule>

  SetEnv HOME /var/www/nextcloud
  SetEnv HTTP_HOME /var/www/nextcloud

</Directory>
SSLEngine on
SSLProxyengine on
SSLProtocol -ALL -TLSv1 -TLSv1.1 +TLSv1.2
SSLHonorCipherOrder On
SSLCompression off
SSLSessionTickets off

        SSLCertificateFile /etc/letsencrypt/live/cloud.mydomain.com-0001/fullchain.pem
		SSLCertificateKeyFile /etc/letsencrypt/live/cloud.mydomain.com-0001/privkey.pem
		Include /etc/letsencrypt/options-ssl-apache.conf

</VirtualHost>
Redirect 301 /.well-known/carddav /nextcloud/remote.php/dav
Redirect 301 /.well-known/caldav /nextcloud/remote.php/dav
Redirect 301 /.well-known/webfinger "/nextcloud/index.php/.well-known/webfinger"
Redirect 301 /.well-known/nodeinfo "/nextcloud/index.php/.well-known/nodeinfo"
</IfModule>

When done check with

apachectl -t

if all is OK

apachectl graceful

to restart apache

1 Like

Hello Vincent_Stans

First of all thank you very much for taking the time to provide such a precise answer.

You commented :

My server is serving a whole bunch of things. The “main” website is like a portfolio of projects, with a few pages and a contact form (hence the php stuff).
I also have a few streamlit applets running.
I have a bitwarden instance running (but not working at the moment, this is my next stop).
And finnaly there is a ownCloud and NextCloud instance running. Now that my NextCloud set-up is ready I will move on from ownCloud.

It might not be the best way to do things but I am experimenting and trying to learn and I am certain that many of these lines are not needed anymore.


Back to the virtual host config. With your help I condensed all my files and I have only 3 left which is a lot cleaner so thanks a lot for that alone.

I followed corrected my config files with your versions and even if I still can’t say that I fully understand what is happening, everything is working perfectly now, so thank you again.

After making all the modification, I had an Internal server error when using cloud.mydomain.com. So thanks to this other thread, there was only two changes to make in the nextcloud/config/config.php file :

  'overwrite.cli.url' => 'https://mydomain.com/nextcloud',
  'htaccess.RewriteBase' => '/nextcloud',

Became :

  'overwrite.cli.url' => 'https://cloud.mydomain.com/',
  'htaccess.RewriteBase' => '/',

Then running sudo -u www-data php occ maintenance:update:htaccess in /var/www/nextcloud to take the changes into account and everything was working.

(I wanted to upload a beautiful picture of the A+ rating I now get on scan.nextcloud.com but it seems I cannot upload it for some reason)

In conclusion the issue is resolved, thank you very much for the help :slight_smile:


Edit : a minor correction also need to be made in the cloud.mydomain.com.conf file :
Redirect 301 /.well-known/carddav /nextcloud/remote.php/dav
Redirect 301 /.well-known/caldav /nextcloud/remote.php/dav
Redirect 301 /.well-known/webfinger "/nextcloud/index.php/.well-known/webfinger"
Redirect 301 /.well-known/nodeinfo "/nextcloud/index.php/.well-known/nodeinfo"

For those 4 lines, nextcloud need to be removed from the path.

I would left it out enteierly unless the server has to be reached by both names. The ServerName can be just a subdomain, otherwise you couldn’t use multiple servers / ip address for a specific domain name. Also there is no no law that says an A record must exist for your main domain. :wink: I do not have an A record for my main domain and everything is working perfectly fine. Anyways…

@Mammastringbean

  1. You’re gonna need multiple VirtualHosts if you want to host multiple sites without beeing one a subfolder of another

  2. You don’t have to use ServerAlias directives unless you explicitly want to point multiple names to the same site / application, meaning if the website only has to be reachable via www subdomain or only via main domain, you don’t need the other one in there. Also Apache doesn’t care if you are using subdomains or not. It determines by the ServerName / ServerAlias directives in the respective Virual Host section and the DocumentRoot directive to which directory the request has to be directed…

So if you want to use Nextcloud and a website on the same server, you can set it up like this:

yourdomain.tld -> Website
www.yourdomain.tld -> Website
cloud.yourdomain.tld -> Nextcloud

Folder structure:

/var/www/html/website
/var/www/html/nextcloud

VirtualHost example for the website, using the main domain and the www subdomain:

<VirtualHost *:80>
	ServerName yourdomain.tld
    ServerAlias www.yourdomain.tld
	ServerAdmin webmaster@localhost
	DocumentRoot /var/www/html/website

    more config options
</VirtualHost> 

VirtualHost example for the website, using only the www subdomain:

<VirtualHost *:80>
	ServerName www.yourdomain.tld
	ServerAdmin webmaster@localhost
	DocumentRoot /var/www/html/website

    more config options
</VirtualHost> 

VirtualHost example for the website, using only the main domain:

<VirtualHost *:80>
	ServerName yourdomain.tld
	ServerAdmin webmaster@localhost
	DocumentRoot /var/www/html/website

    more config options
</VirtualHost> 

VirtaulHost example for Nextcloud using the cloud subdomain.

<VirtualHost *:80>
    ServerName cloud.yourdomain.tld
	ServerAdmin webmaster@localhost
	DocumentRoot /var/www/html/nextcloud

    more config options
</VirtualHost> 

Both DocumentRoots have to be either at enterly diffrent locations or on the same foder level beside each other. One must not be a sufolder of another if you are using VirtualHosts configs.

1 Like

Thank you for your answer @bb77.

I forgot to mention my file structure in the original post but it is simply :

/var/www/html/mydomain
/var/www/nextcloud

I’ve seen next cloud in or out of the html folder and I do not know if that makes any difference honestly, but thing seems to work now.

I tried your version and used only ServerName instead of setting ServerName to mydomain.com and having a ServerAlias and it also work but I don’t see a difference, is there any real difference or is it just a more “pro” way of doing things ?

Thank you again

This should be fine as long as you use seperate VirtualHosts for each site and the DocumentRoot directive is pointing to the correct folders.

No It doesn’t make any diffrence, as long as you don’t put one site in a subfolder of the other.

Same answer here. It’s fine as long as everything points to the correct location. But it doesn’t make much sense to use multiple names for a service like Nextcloud. And you can only use your main domain for one site. You cannot use yourdomain.com for your webpage and for Nextcloud at same time, if you don’t want to use one in a subfolder of the other.

I would create one VirtualHost with domain.com and www.domain.com for the webpage and another VirtaulHost with cloud.domain.com for Nextcloud.

1 Like

Thank you for the explanation, things are a little clearer for me now, and you gave me pointers on where I can improve and what I can learn next because apache servers are still a bit blurry for me.

Everything is working so I won’t make any major changes but I will try to at least understand the best practices and adapt my configurations files accordingly.

1 Like