Setup Dynamic Virtual Host (Apache2 on Ubuntu) - apache

I want to set up a single virtual host that can dynamically handle all requests based on the hostname used to access it. If %{HTTP_HOST} could be used in a DocumentRoot, this is probably exactly what I want:
<VirtualHost *:80>
ServerAdmin me#example.com
DocumentRoot /var/www/live/%{HTTP_HOST}/public
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory /var/www/live/%{HTTP_HOST}/public>
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all
</Directory>
# Possible values include: debug, info, notice, warn, error, crit, alert, emerg.
LogLevel warn
ErrorLog /var/www/live/%{HTTP_HOST}/logs/error.log
CustomLog /var/www/live/%{HTTP_HOST}/logs/access.log combined
</VirtualHost>
...unfortunately, %{HTTP_HOST} is not allowed in the DocumentRoot (Warning: DocumentRoot [/var/www/live/%{HTTP_HOST}/public] does not exist). How else can I achieve my goal?
Update: I thought of pointing a catch-all vhost to a single directory and having a .htaccess use mod_rewrite to dynamically select the path but (honestly) I'm exhausted. I'll try at it again in the morning, but in the meantime, if anyone has good ideas, I'd love to hear them! Thank you!

Maybe you can try the following solution from this article: Apache: Dynamic Virtual Hosts
A few months back I looked for a solution to overcome the problem of
creating individual Virtual Hosts in Apache every time I wanted to
configure a new site on a development machine (something that is a big
issue in work where we have a lot of websites). Apache is able to
support this functionality relatively easy using a module and a few
lines in the configuration file. I set this up on Fedora 14, so
results may be slightly different for other OS's (different paths,
configuration file setup, etc)
Open up the main Apache conf (/etc/httpd/conf/httpd.conf), and ensure
the module mod_vhost_alias is enabled. There should be a line in the
configuration like
LoadModule vhost_alias_module modules/mod_vhost_alias.so
Next, add the
following lines to the bottom of this file. You'll need to edit the
file with sudo privileges.
NameVirtualHost *:80
UseCanonicalName Off
<VirtualHost *:80>
VirtualDocumentRoot /var/www/html/domains/%0
</VirtualHost>
This sets up a catch all for any domain coming in over port 80 (the
default port for http traffic, if your using https you will need to
use 443 - alternatively you could remove the port restriction). The
important line here is the VirtualDocumentRoot. The tells Apache where
your files will reside on disk. The %0 part takes the whole domain
name and inserts it into the path. To illustrate this if we went to a
domain testing.com.dev the VirtualDocumentRoot would be:
/var/www/html/domains/testing.com.dev
This type of configuration might
be suitable for most situations, however I didn't want to have the
.dev part of the domain in my folders on disk. I was able to achieve
this by setting the VirtualDocumentRoot to:
VirtualDocumentRoot /var/www/html/domains/%-2+
The above example of testing.com.dev would now point to:
/var/www/html/domains/testing.com
Remember to add the domain to your
hosts file (/etc/hosts)
For a full list of options see the mod_vhost_alias documentation.
Additional documentation can be found here.

The official methods for achieving dynamic virtual hosts are explained in the Apache documentation:
http://httpd.apache.org/docs/2.0/vhosts/mass.html

Related

Apache showing empty "index of /", after dist upgrade

I'm working on a Debian 7 server which I did a dist upgrade on so it is Debian 8 now.
The only thing I am having trouble with is the apache2 which got updated from 2.2 to 2.4. the problem that is that now it shows me an empty "Index of /" although there are a lot of files in the specified folders.
vHost Conf:
<VirtualHost *:80>
ServerAdmin some#email
ServerName some.server
ServerAlias some.server
DocumentRoot "/data/apt/public_html"
<Directory "/data/apt/public_html">
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
Require all granted
</Directory>
</VirtualHost>
How can I get it working again?
mixing 2.2 and 2.4 access directives is not recommended. Look at http://httpd.apache.org/docs/current/upgrading.html. You will see that they never mix Order allow,deny with Require all granted. So remove your Order line.
Mixing old and new directives
Mixing old directives like Order, Allow or Deny with new ones like
Require is technically possible but discouraged. mod_access_compat was
created to support configurations containing only old directives to
facilitate the 2.4 upgrade. Please check the examples below to get a
better idea about issues that might arise.
Also, you do not specify a DocumentIndex file so Apache does not know which file it should return a client when he asks for http://some.server/.
Let's assume the default page is index.html, add this in your VirtualHost:
DocumentIndex index.html
Note 1: ServerAlias has the same value as ServerName, and is therefore not required.
Note 2: you should setup access and error log files for this VirtualHost. It might not be useful if you have only 1 VirtualHost, but you will thank me if you have a large site (with multiple VH later).

Override single setting in default Apache <VirtualHost> block

In debian's default apache2 configuration, /etc/apache2/sites-enabled/000-default contains a lot of settings for the default VirtualHost:
<VirtualHost *:80>
# Many good settings here, among them:
CustomLog ${APACHE_LOG_DIR}/access.log combined
ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
</VirtualHost>
In another configuration file, I'd like to override a single one of them, the CustomLog setting, so that logs go somewhere else. I don't want to copy or mess with all the other settings, e.g. ScriptAlias. But I still want it to apply to <VirtualHost *:80>.
Is that possible?
What I tried
I tried putting this in
/etc/apache2/sites-enabled/001-mylog:
<VirtualHost *:80>
CustomLog ${APACHE_LOG_DIR}/my.log combined
</VirtualHost>
That has no effect, presumably because apache only looks at the first <VirtualHost> section, and /etc/apache2/sites-enabled/000-default gets loaded before /etc/apache2/sites-enabled/001-mylog.
Instead I tried putting the same snippet in /etc/apache2/conf.d/mylog, that gets loaded before /etc/apache2/sites-enabled/000-default because /etc/apache2/apache2.conf has an Include conf.d/ before Include sites-enabled/. That does override the CustomLog value as I wanted. But now the ScriptAlias from /etc/apache2/sites-enabled/000-default doesn't take effect.
I'd like to avoid duplicating everything from /etc/apache2/sites-enabled/000-default effectively creating a fork of the default debian apache configuration file.
Documentation
Apache HTTP Server - core documentation has this rather vague:
When a request is received, the server first maps it to the best matching
based on the local IP address and port combination only.
Non-wildcards have a higher precedence. If no match based on IP and port occurs
at all, the "main" server configuration is used.
If multiple virtual hosts contain the best matching IP address and port, the
server selects from these virtual hosts the best match based on the requested
hostname. If no matching name-based virtual host is found, then the first
listed virtual host that matched the IP address will be used. As a consequence,
the first listed virtual host for a given IP address and port combination is
default virtual host for that IP and port combination.
<VirtualHost> doesn't behave like <Directory>
Very confusingly, it looks to me as if for <VirtualHost> directives, only a single matching instance is considered. But for e.g. <Directory> directives, they are added/combined, so that:
<Directory "/some/dir">
Options Indexes MultiViews FollowSymLinks
</Directory>
<Directory "/some/dir">
AllowOverride None
Order deny,allow
Allow from all
</Directory>
is equivalent to:
<Directory "/some/dir">
Options Indexes MultiViews FollowSymLinks
AllowOverride None
Order deny,allow
Allow from all
</Directory>
But that this mechanism doesn't work for <VirtualHost> :-(
Edit: This is not the same as Sharing configuration between several VHosts, because debian's default VirtualHost doesn't use any of those solutions. But perhaps others can find inspiration in that answer.
I get the same puzzle for the multiple vhosts'(virtual hosts') definition. Do they override(redefine), overlap? Or there are other veiled details inside?
I find some links for this puzzle as following:
https://www.thegeekstuff.com/2011/07/apache-virtual-host/
https://httpd.apache.org/docs/2.4/vhosts/examples.html
With cautions to these examples inside, I could say the vhosts' definitions are not the same (even they look like the same). The difference mainly lays on the SeverName inside definition. Apache httpd server distinguishes the different vhost definitions based on ServerName inside(each vhost definition), not the IP Address or Port Number as listed in the <VirtualHost> header.
This puzzle keeps coming and going since there lacks explicit explanation for this topic(in the web). I hope this post can help to relieve this mindboggler in a way.

Apache: <Directory> directive with no path specified

I have a local server environment running on my OS X machine using MAMP, and I am currently setting up a few virtual hosts. I found that, in order for one of my virtual hosts to recognize my site's .htaccess file, I needed to add a <Directory> directive within the <VirtualHost> directive.
Here is an example of what I am using to configure one of my virtual hosts:
<VirtualHost *>
DocumentRoot "/path/to/mysite"
ServerName mysite.local
<Directory "/path/to/mysite">
AllowOverride All
Order Allow,Deny
Allow from all
</Directory>
</VirtualHost>
Now, I would like to avoid redundancy by removing the path from that <Directory> directive. I tried doing so and it seems to work, although I am not familiar with Apache enough to know the potential consequences of doing this. Furthermore, I could not find an explanation of this case in the Apache Documentation.
This is what I would like to do:
<VirtualHost *>
DocumentRoot "/path/to/mysite"
ServerName mysite.local
<Directory>
AllowOverride All
Order Allow,Deny
Allow from all
</Directory>
</VirtualHost>
Therefore, my question is this: what happens when I omit the path from the <Directory> directive (in this case)?
Directory is a directive targeting a file system directory, and should always have a path (waildcards allowed).
Using some instructions targetd to no directory may be discarded silently, or maybe with an error (you could test it), but is would certainly be useless.
Why would you write some configuration instructions targeted to no directory at all?
But there's maybe more things in your question.
Ususally a Virtualhost should contains at least one Directory instruction, the DocumentRoot directory, and usually we also add one targeting the root of the filesystem, this way:
<Directory />
(instructions to deny access and avoid .htaccess reads)
</Directory>
<Directory /my/document/root/>
(instructions to allow access and still avoid .htaccess reads or to allow them if you are lazy and feel over confident that .htaccess are useful in any way and you do not need speed)
</Directory>
And you could add more, especially to avoid usage of .htaccess files as such file stored in /path/to/somewhere is the same thing as a <Directory /path/to/somewhere> section, but slower.
Now you do not like to repeat yourself in your VH configuration, so you coud maybe use .htaccess files or global level instructions for things that are usually set there. And you could also use another magical keyword, which is Location.
You can use a lot of Apache instruction in a <Location /foo> directive. Locations works on url, not on filesystem paths.
So <Location /> is your documentRoot, and <Location /foo> is maybe the subdirectory 'foo' under you DocumentRoot. This could help you write things in your VH without reusing the documentroot prefix everywhere. But be careful, urls are not file-system paths. Any protection applied on the url level may be weaker or stronger compared to a protection applied on a directory level. It depends on your alias, the way you use urls, etc.
Update:
If you use the new Apache 2.4 version you can now use mod_macro or even easier, built-in variables support:
Define docroot "/path/to/mysite"
DocumentRoot ${docroot}
<Directory ${docroot}>
(...)

Apache accepts all websites that point to server

I only have two websites pointed to my server IP, Asite.com and Bsite.com. I tried adding a website, so I pointed Csite.com to my server IP (but I haven't registered a virtualhost for site3.com yet). How come when I access Csite.com apache recognizes it as Asite.com even if I haven't registered a virtualhost for Csite.com?
httpd.conf
Listen 8080
NameVirtualHost *:8080
Asite.com
<VirtualHost *:8080>
ServerAdmin webmaster#localhost
ServerName asite.com
ServerAlias asite.com *.asite.com
DocumentRoot /var/www/asite.com/public
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory /var/www/asite.com/>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
allow from all
</Directory>
ErrorLog /var/log/httpd/error_log
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn
</VirtualHost>
^The same goes for Bsite.com
The first virtualhost is also the default:
"The asterisks match all addresses, so the main server serves no requests. Due to the fact that www.example1.com is first in the configuration file, it has the highest priority and can be seen as the default or primary server. That means that if a request is received that does not match one of the specified ServerName directives, it will be served by this first VirtualHost."
See 'Running several name-based web sites on a single IP address.' http://httpd.apache.org/docs/2.0/vhosts/examples.html
It uses the first-listed one, when it has no ServerName match.
You'll find you can also use the raw IP address to access Asite.com.
If you feel uncomfortable with that, you could create a different virtual host as the first one listed for <VirtualHost *:8080>, and configure so it just Redirects somewhere else. Or gives a 404 message, etc.
This is happening because you pointed the csite.com to your local host and the first virtual host is recognized as local host so if you switch around siteA and siteB so it would be virtual host for sure b first and type in your browser "localhost" or sitec.com it will show siteb.com
Don't worry; this isn't a problem. It is supposed to happen.
You didn't actually point sitec.com to localhost but I if you created it in your hosts file our pointed it to your domain it will take you to the first specified file!

Magento not accessible since tried to move to multi website setup. Apache issue?

I wish I had never seen this article:
http://www.magentocommerce.com/knowledge-base/entry/tutorial-multi-site-multi-domain-setup
I have Apache 2.2 installed on my XP machine and until a while ago I had a Magento site that I could test the development of a custom module on. I decided that I wanted to have multiple websites and multiple stores so that I could test that my modules configuration variables set at the different scopes (global, website, and store) were working as expected.
So I followed the instructions in the above Magento article. I created a website and gave it a name of “paulsplace.com”. I created a couple of Stores under that website. I then went to System/Configuration/General/Web and, with the scope set to paulsplace.com, I set the unsecured and secured URLs to http://paulsplace.com/ and https://paulsplace.com/ and hit Save Config - what a mistake!!
I got a 404 error. And now I can’t get to my magento front end or back end.
I tried a couple of things:
I added these lines to my hosts lookup file:
127.0.0.1 paulsplace.com
127.0.0.1 www.paulsplace.com
I then uncommented this line in my httpd,conf file:
Include conf/extra/httpd-hosts.conf
and added the following to the conf/extra/httpd-hosts.conf file:
<VirtualHost *:80>
ServerAdmin me#myemail.com
DocumentRoot "C:/Applications/Apache Software Foundation/Apache2.2/htdocs"
ServerName paulsplace.com
ErrorLog "logs/paulsplace.com-error.log"
CustomLog "logs/paulsplace.com-access.log" common
</VirtualHost>
and restarted Apache.
If I browse to “http://www.paulsplace.com” I now get a page that just says “It works!”. Same for “http://paulsplace.com” and “http://www.paulsplace.com/magento/index.php”.
I tried a few more things - I added this line to httpd.conf:
AccessFileName htaccess
(I did this because Windows Explorer didn’t let me create a file starting with a dot; I could do it from the command prompt, but I believe what I have done should be ok).
I changed AllowOverride to All from None:
<Directory />
Options FollowSymLinks
AllowOverride All
Order deny,allow
Deny from all
</Directory>
<Directory "C:/Applications/Apache Software Foundation/Apache2.2/htdocs">
AllowOverride All
</Directory>
and in C:\Applications\Apache Software Foundation\Apache2.2\htdocs\htaccess (a file that I created), I entered:
SetEnvIf Host www\.paulsplace\.com MAGE_RUN_CODE=pws1
SetEnvIf Host www\.paulsplace\.com MAGE_RUN_TYPE=website
SetEnvIf Host ^paulsplace\.com MAGE_RUN_CODE=pws1
SetEnvIf Host ^paulsplace\.com MAGE_RUN_TYPE=website
(pws was the value I used for the “Code” when creating my store).
Please tell me how I can put this right. I feel like I’m taking one step forward and three backward at the moment.
Any help really would be greatly appreciated.
<VirtualHost *:80>
ServerAdmin me#myemail.com
DocumentRoot "Change this to point at your magento install"
ServerName paulsplace.com
ErrorLog "logs/paulsplace.com-error.log"
CustomLog "logs/paulsplace.com-access.log" common
SetEnv MAGE_RUN_TYPE website
SetEnv MAGE_RUN_CODE pws1
</VirtualHost>
If changing anything in System Configuration borks your system, you can always clear out the bad values in the database directly, and clear your Magento cache. Do a
select * from core_config_data where value LIKE '%paulsplace.com%'
This will give you the two rows that were added when you clicked save. Remove the rows. Next, clear out all the files in
var/cache/*
to clear your cache. Then restore your Apache config to what it was before you started monkeying around. This should restore your site back to its previous state, and you can continue to experiment with things.