4

I am trying to set up some automation on my local dev machine. Normally I start all my projects like this

Open Hosts file, set up a DNS entry like 127.0.0.1 example.com www.example.com Open httpd-vhosts.conf file and add an entry, something like this below

<VirtualHost *>
    DocumentRoot "/path/to/xampp/htdocs/example.com"
    ServerName example.com
    ServerAlias www.example.com
</VirtualHost>

What I am trying to achieve is to set up the environment in such a way that, I shouldn't have add this entry in my httpd-vhosts.conf every time I want to work on a new host.

Rather I would like to have one global entry in httpd-vhosts.conf that can handle all the domains and map them to their respective directories

so if I have a list of records in my hosts file like this

127.0.0.1 example.com
127.0.0.1 mysite.com
127.0.0.1 google.com
127.0.0.1 abc.com

and a folder structure like this

/htdocs/
    /example.com/
    /mysite.com/
    /google.com/
    /abc.com/

It should automatically map to those directories without the need of adding the VirtualHost record in the httpd-vhosts.conf file.

I can guess that this can be achieved by adding a wildcard entry in httpd-vhosts.conf (I don't know how) and then adding some redirect rules in .htaccess file placed in /htdocs/ to map them to their directories.

So eventually,

  1. How to set up a wildcard entry in httpd-vhosts.conf
  2. How to set up exact rewrite rules in .htaccess file in /htdocs/

This is something that I thought of, there might also be a better way to do this.

Atif
  • 10,623
  • 20
  • 63
  • 96
  • For any solution to work you MUST park/addon a domain to your server. Therefore whilst adding the domain, take 5 more seconds to point it directly into the desired directory. I must emphesise: **since you're parking it anyway, park it where it belongs.** – Unamata Sanatarai Mar 19 '13 at 12:40

3 Answers3

6

1. How to set up a wildcard entry in httpd-vhosts.conf

By placing an asterix (*) in front of the domain name, where you'd normally place www

<VirtualHost *>
    DocumentRoot "/path/to/xampp/htdocs/example.com"
    ServerName example.com

    ServerAlias *.example.com

</VirtualHost>

2. How to set up exact rewrite rules in .htaccess file in /htdocs/

RewriteEngine On
#RewriteCond %{HTTP_HOST} ^!example.com #(optional) do not redirect base domain
RewriteCond %{HTTP_HOST} (?(?=[a-z0-9\-\_]+\.[a-z0-9\-\_]{2,}$).+|[a-z0-9\-\_]+\.[a-z0-9\-\_]{2,})$
RewriteRule ^$ http://localhost/%0

All those domains:

www.example.com
img.example.com
cdn.example.com
static.img.example.com

will be redirected to /example.com.

Explanation

What the above does, essentially, is it takes the last two strings separated by a perdiod and redirects you to the newly found folder.


From a technical point of view:

This regex uses if then|else pattern. If 1 is found, then do 2 else do 3.

Do a test and then proceed with one of two options depending on the result of the text (?(?=[a-z0-9-_]+.[a-z0-9-_]{2,}$).+|[a-z0-9-_]+.[a-z0-9-_]{2,}$)

  1. (IF) Assert that the regex below can be matched, starting at this position (positive lookahead) (?=[a-z0-9\-\_]+\.[a-z0-9\-\_]{2,}$)
    • Match a single character present in the list below [a-z0-9\-\_]+
      • Between one and unlimited times, as many times as possible, giving back as needed (greedy) +
      • A character in the range between “a” and “z” a-z
      • A character in the range between “0” and “9” 0-9
      • A - character \-
      • A _ character \_
    • Match the character “.” literally \.
    • Match a single character present in the list below [a-z0-9\-\_]{2,}
      • Between 2 and unlimited times, as many times as possible, giving back as needed (greedy) {2,}
      • A character in the range between “a” and “z” a-z
      • A character in the range between “0” and “9” 0-9
      • A - character \-
      • A _ character \_
    • Assert position at the end of the string (or before the line break at the end of the string, if any) $
  2. (THEN) If the test succeeded, match the regular expression below .+
    • Match any single character that is not a line break character .+
    • Between one and unlimited times, as many times as possible, giving back as needed (greedy) +
  3. (ELSE) If the test failed, match the regular expression below if the test succeeded [a-z0-9\-\_]+\.[a-z0-9\-\_]{2,}$
    • Match a single character present in the list below [a-z0-9\-\_]+
    • Between one and unlimited times, as many times as possible, giving back as needed (greedy) +
    • A character in the range between “a” and “z” a-z
    • A character in the range between “0” and “9” 0-9
    • A - character \-
    • A _ character \_
    • Match the character “.” literally \.
    • Match a single character present in the list below [a-z0-9\-\_]{2,}
    • Between 2 and unlimited times, as many times as possible, giving back as needed (greedy) {2,}
    • A character in the range between “a” and “z” a-z
    • A character in the range between “0” and “9” 0-9
    • A - character \-
    • A _ character \_
  4. Assert position at the end of the string (or before the line break at the end of the string, if any) $

Test suite:

a.bc
ab.cd
abc.def
ab.cd.ef
12.34
12.34.56
1.2.3.4.5.67
cnn.com
no_country.for.old.men
Unamata Sanatarai
  • 6,475
  • 3
  • 29
  • 51
  • Great! thanks for this.. Almost there I would say.. Just 2 things, when I open `example.com`, it redirect to `example.com/example.com/` and then secondly what would be the rule to point both `example.com` and `www.example.com` to the same folder which is `example.com`. (I guess adding 2 rules?) – Atif Mar 19 '13 at 23:11
  • The above does just that. If you have `www.example.com` and `example.com` and `img.example.com` and `cdn.example.com` they all will get redirected to `/example.com` – Unamata Sanatarai Mar 20 '13 at 06:34
  • Cool, but the problem that when I open example.com, it redirect to example.com/example.com/ still exists.. can you help me with that? (bounty awarded) :-) – Atif Mar 20 '13 at 18:29
  • @AtifMohammedAmeenuddin added `RewriteCond %{HTTP_HOST} ^!example.com` which will stop it from going to `example.com/example.com` – Unamata Sanatarai Mar 21 '13 at 09:45
  • Well that makes it hardcoded again then, I'll have to add rewrite condition for each domain. what i am trying to say is this is not limited to example .com, just put any site for example a.com, it redirects to a.com/a.com and if you use mysite.com it is redirecting to mysite.com/mysite.com – Atif Mar 21 '13 at 11:16
  • What I mean to say is I want to rewrite and not redirect. – Atif Mar 21 '13 at 11:17
2

You have several ways to manage this task. There is even a special documentation page on apache httpd website for this.

This lead to several methods:

  • mod_rewrite (dedicated page), the swiss knife, but in my humble opinion this leads to seme cryptic syntax and strange behaviors
  • mod_vhost_alias, certainly the simpliest way to set simple virtualhosts (as simple asthe ones you usually use)

And for more complex vistualhosts you should check mod_macro, a great module. with this module you could write templates of virtualhosts with several parameters (not only domain and document root, any variable thing you could think about), and then simply add one line calling this macro with all the parameters for each virtualhost.

regilero
  • 29,806
  • 6
  • 60
  • 99
1

I'd write a small script to generate the vhost configuration files from a list of domains/sites, put all of the vhost configuration files in a separate directory, then use in the Include directive in my httpd.conf to include all the configuration files in that directory.

djc
  • 11,603
  • 5
  • 41
  • 54
  • Thank for your response, but that way I will have to run that script every time I want to add a new domain. I am actually looking to eliminate steps here – Atif Mar 13 '13 at 11:44