Setup automatic per-folder subdomains on your local linux based computer
WARNING: this is a fully linux-based tutorial. I’m pretty sure that this is possible on Micro$oft Windows and OS/X, but unfortunately I’m not using them, neither I know a good DNS server for them and the impact on XAMPP and MAMP.
As you probably already know, one of the main problems when you’re doing multiple projects is to organize them properly, first for fast local testing of changes, second for your own sake, to not get lost on your own computer.
One more problem are the testing local domains. Well, the easiest way when you create a project is to create a new project folder, put a new domain (and every subdomain you’ll use) into your /etc/hosts file, create a new virtual host in the apache config, run a2ensite #### (or however you enable a new site on your distribution), restart the webserver… Which means, you need to do that everytime when you’re creating a new project. Not a very convenient way if you ask me, as you’re bloating your /etc/hosts file and your Apache2 virtualHost file(s).
So, one day, I was thinking about that and looking for a solution for it. I’m sure there are a bunch of ways to get rid of this problem, and this solution which I’ll show you is how I managed to do it.
In the end of this tutorial, you’ll have a automatic way to create local subdomains entirely by only creating a new folder (or linking your project) and adding 1 line to the htaccess file.
No more a2ensite, no more apache restarts/reloads, no more bloating of any hosts files, and no more boring c/p and editing of vhost files.
Btw, we’re using this method too on a internal development server the past few months, without any problems, althrough I don’t recommend this for production servers.
Well, first thing to know is what I’ll use to accomplish this.
– a main local domain. Mine is test.loc . Use any name you want.
– DNSMasq: a small dns daemon which is really easy to configure. This’ll be used for wildcard subdomain domain names.
– Apache2 vhost_alias module: while not used very often, it’s a relatively easy way (and yes, I know you can do that with mod_rewrite too, but I didn’t take the time to investigate, as my method is working) to tell your apache server how to handle the subdomains.
– the .htaccess file of your project: a oneliner so apache doesn’t mix up the root folder of the project
– read/write privileges to the /var/www folder (it’s on you to properly manage the folder/file privileges, so it’s not in the scope of this tutorial. I can make another one about it if somebody wants to know)
Let’s start with the DNS server. I’m using a Ubuntu based derivative, so my package manager is apt-get.
sudo apt-get install dnsmasq
After the install passes, you need to create a file in the folder /etc/dnsmasq.d (name it after your domain) for the subdomain wildcard to work.
My /etc/dnsmasq.d/test file:
address=/.test.loc/127.0.0.1
Now restart dnsmasq:
sudo service dnsmasq restart
That’s about it for your subdomains to work. Pretty straightforward, don’t you think?
Now the apache configuration. I don’t like to have all the projects directly in the /var/www folder, so I created the folder /var/www/test. You can use the /var/www folder or any other you like.
Enable the vhost_alias module:
sudo a2enmod vhost_alias
Edit a new vhost file (like /etc/apache2/sites-available/test.loc):
<VirtualHost *:80>
ServerAdmin webmaster@localhost
ServerName test.loc
ServerAlias *.test.loc
# This will be the wildcarded document root. Any folder you create in /var/www/test will be automatically a subdomain name.
VirtualDocumentRoot /var/www/test/%-3
# For symlinking your projects and htaccesses to work
<Directory />
Options FollowSymLinks
AllowOverride All
</Directory>
ErrorLog /var/log/apache2/vhosts-error.log
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn
CustomLog /var/log/apache2/vhosts-access.log combined
</VirtualHost>
Disable the main vhost site (named default):
sudo a2dissite default
Enable your site (enter the right vhost filename)
sudo a2ensite test.loc
Create a new webserver root folder. This will be the folder which’ll be called if you just call http://test.loc/ (please pay attention for the folder named _ (underscore), it’s not a typing mistake)
mkdir /var/www/test/_
Almost done!
Before going further, I’d like to explain to you the VirtualDocumentRoot directive a bit more. The %-3 means ‘give me the third dot-splitted string of the domain from right to left’. This way you can pick any level deep subdomain you want.
Let me give you another more ‘advanced’ example with two-level deep subdomains (like bar.foo.test.loc):
VirtualDocumentRoot /var/www/test/%-3/%-4
Which would mean that if you enter a domain like bar.foo.test.loc apache will try to find the folder /var/www/test/foo/bar/ and serve this one as the main domain.
Some people would ask ‘Alright smarta.. uhm.. smart guy, but I want to access foo.test.loc too, without the bar. How do I do that?’.
Well, that’s done with the ‘magic’ folder _
For example, if you’d want foo.test.loc, you’d create the folder /var/www/test/foo/_ which would be the server root for it.
Unfortunately, there’s one little catch in this example: while calling bar.foo.test.loc, it won’t automatically fallback to foo.test.loc if you don’t have the /var/www/foo/bar folder, but it will always fallback to bar.foo.test.loc from anything.bar.foo.test.loc, because you didn’t explicitly tell vhost_alias for the deeper level (which’d btw be %-5, as the fifth string from right).
If you’re a mazochist, you can always take a look on the documentation for vhost_alias which has a few more examples and explanations about it.
Next thing: the .htaccess file in your project folder. Why, you ask? It’s because without it apache2 thinks without it that the webserver root is /var/www and you can forget your precious url rewrites.
So, open up the main .htaccess file of your project and just put this line into it:
RewriteBase /
That’s it, folks!
Now all you’ve got to do is copy/symlink the project folder every time to a according folder under /var/www/test, put the oneliner into your htaccess file, and have fun with developing. No more vhosts, /etc/hosts or any other boring *hosts. The folder /var/www/test/project_a magically becomes http://project_a.test.loc/, /var/www/test/project_b becomes http://project_b.test.loc/, and so on.
I hope somebody finds it useful, as I couldn’t find any tutorials which cover all of it properly with this folder structure.
As the subsubdomains and subdomain stuff with vhost_alias are a bit confusing, please feel free to ask me any questions.
17 comments
im installing linux in my virtual box your post was very helpful to me
My URL rewriting doesn’t work at all a little help would be appreciated
Here is my vhost :
And I have the subfolder : “app”, I can access it via http://app.local.dev
And I have this htaccess file in the app folder :
And of course mod_rewrite is activated
Thanks
I fixed it !
Just have to change the line
to
Old post, but working perfectly for me : many thanks !! really easy and useful !
I don’t know man, I’d rather know what I’m doing and just edit or cp a file. This is really more trouble than it’s worth. Seems the instructions as given don’t work either but I’m going to look up vhost alias and see what the config options are. Thanks for sharing in any case. Having multiple test sites is never an easy thing to manage.
Really nice tutorial.
Unfortunately instead of successful using vhosts all requests return the old /var/www directory. Apparently I’m doing something wrong.
mod_rewrite is on, so is vhost_alias
The Acrylic DNS server for windows can do what DNSmasq Does on linux/osx.
I’ve been experimenting with this confuration for a while and it works pretty good. One observation that I recently made is that when I’m running the debugger the debugger does not stop at any breakpoints in the “subdomains”.
For what’s worth, I was able to fully implement the process on another computer so any errors I’m getting are probably a configuration issue that I will eventually sort out.
Thank you, this works great!
You indicated that you wouldn’t recommend this for a production environment. Is there something other than it has not been throughly tested driving this statement? Are there potential security or scalability issues?
When I execute the command:
sudo service dnsmasq restart
I get an error message saying:
dnsmasq: failed to create listening socket for port 53: Address already in use
Hey, I’m having trouble getting the site to redirect to anywhere other than the “_” directory in my subdomain directory. Why would this happen? I just replaced everything that had ‘test’ in it with my own name.
Please help!
I’m facing the same issue, anyone helps?
great tutorial. Also thanks docsta for the additional info.
Thanks! Finally I got this to work. Great!
A few additions:
1. VirtualDocumentRoot /var/www/%2+/%1
This will make it really easy to organize your domains and subdomains in one step. I like to keep all my dev top level domains in one folder. Each domain can have as many subdomains as you like:
So these will work:
And so on. Really convenient.
2. Fix DOCUMENT_ROOT in $_SERVER
By default $_SERVER[‘DOCUMENT_ROOT’] will be ‘/etc/apache2/htdocs’ (or wherever apache resides). This is not true and will eventually cause trouble with scripts.
This command in the VirtualHost directive will correct this:
setdocroot.php:
My full vhost config:
Hello,
first of all thanks,
I think I am going to setup VirtualBox, Ubuntu, AMP and this one to do developing instead of doing it on my MacBook nativly. Should make deployment to linux hosts much smoother and keep constraints seperated.
A question though: could I not add RewriteBase to apache.conf/httpd.conf instead of .htaccess?
I dont’ like .htaccess files spread around.
And: while I saw you do magento development: any tips on what to read if you are already an experienced php/sql/html/css developer?
Hi Jonas,
thank you for your reply.
The RewriteBase directive’s context is directory based. That means you either need to create/edit the .htaccess file in the root folder of your project and add it there, or you can put everytime you create a new subdomain-folder something like that into the httpd.conf (I didn’t try that out, just writing from memory):
Which isn’t very convenient, and quite opposite to the theory that you don’t want to edit your apache files every time you create a new subdomain.
If you don’t want to edit the .htaccess of your root project folder every time and are using something like magento/wordpress/any-other-solution-available, copy the htaccess file from the project root somewhere safe, put the ‘RewriteBase /’ into it, and copy it every time into the subdomain folder after you create the new subdomain.
About the tips for reading, I’d suggest you browse a bit in the archives of Inchoo, and the magento knowledge base has good tutorials for magento starters ( http://www.magentocommerce.com/knowledge-base/categories/category/development/ ).
Good luck with setting up the environment.