I tried searching, but I couldn't really figure out the best search terms to find my answer.

I have a Ubuntu 10.04 server with Apache. I want to set up a site that will be versioned, so my file structure will look like:

/var/www/dev -> /var/www/html/MyApp1.1
/var/www/test -> /var/www/html/MyApp1.0

Where "dev" and "test" are symbolic links to the other folders. So my URL for those two environments will be "http://my-url.com/dev" or "http://my-url.com/test". For my prod environment, I want the URL in the browser to be just "http://my-url.com", without redirecting to something like "http://my-url.com/prod".

How can I set it up so that the base URL points to a specific version without a redirect changing the URL?




I feel that I should give more detail about our current setup and make it known that we don't have a ton of time to spend on making a ton of changes. Forgive the length, but I'm trying to paint an accurate image of our current setup, in order to get the best solution.

Our dev team consists of 9 people, 5 that work on our main project (C++), 3 that work on art for our main project, and me, working on all web design to supplement our main project. We use MS SourceSafe for version control. I know PLENTY of people have their gripes with it, but it is something that we have been using for a while and are not looking to change it at this point, since we have too many other priorities.

Each member of the dev team (including myself) works on a Windows workstation. We do not have Apache installed on any of our local machines. Before I started working here, they had a Ubuntu Linux server set up with Apache installed to host the site. They would develop in a dev area on that Linux server and whenever they were going to create a new web build, they would copy the files to their local machine and from there, check them into SourceSafe.

Since I have been here, I set up a Samba share on the Linux server and have it mapped to a network drive on my Windows workstation. This way, I can check files out and in without needing to copy them to my local machine. Since I am now the only person working on web stuff, I leave the files checked out all the time, and wrote a batch script to do the "build" process. Whenever I want to update our test environment with a new version, I run the batch script and it does the following:

  • create a new folder to contain the new site version
  • copy the files from the dev environment to the new folder
  • update the "test" link to point to the new folder
  • check the project in to SourceSafe, keeping the files checked out
  • label the project, using comments from a text changelog that I update as I make changes

So we do have a version control system in place that may not be the best, but works for us. I suppose that I could stop creating versioned folders and using symbolic links, but I kind of like having the ability to easily switch between different versions by simply and quickly updating a symbolic link.

I truly appreciate the answers letting me know what the actual best practices are (I realize now that I didn't give this topic a good title for my question). I found those very informative, and as someone who has only ever really worked by myself or in a small team of others who are equally inexperienced, I did not know that information before, and will follow those practices for future endeavors.

However, for the sake of time and ease, is there a good way for me to keep my current setup and just redirect the base URL to a different folder without changing the URL? Essentially, I would make /var/www a symbolic link to MyApp1.0, but the problem I would run into there is that I wouldn't be able to access /var/www/dev or /var/www/test anymore.

Thanks again,


migrated from webmasters.stackexchange.com Nov 30 '10 at 4:37

This question came from our site for pro webmasters.

  • I think this question better fits in Server Fault. – Dave Nov 29 '10 at 22:27
  • As this relates to creating symlinks on your file system, this is definately a question for ServerFault. If however it turns out that it's a mod_rewrite problem then it probably belongs back here. – Mark Henderson Nov 30 '10 at 4:36

I wouldn't do it with symlinks; I'd do it all with mod_rewrite.

RewriteEngine on
RewriteRule /dev/(.*) /var/www/MyApp1.1/$1 [L]
RewriteRule /test/(.*) /var/www/MyApp1.0/$1 [L]
RewriteRule /(.*) /var/www/MyApp0.9/$1 [L]
  • This sounds like it will probably work, but I have no idea how to use it. I will Google it and figure it out. Thanks! – Travesty3 Nov 30 '10 at 17:38
  • See my post below...my question would be much more difficult to read in a comment box, without formatting. Plus I'm far too long-winded to fit all I need in the comment box. – Travesty3 Nov 30 '10 at 22:58

Best practices here are to use a revision control system like subversion, mercurial, or git to handle the versions.

The process is that you set up a main or root repository anywhere (it might be on the web server or it might be somewhere else). To make changes to your site check out the code from the repository, modify and test on your local machine, and then commit or merge your changes back to the repository when you're happy with them (or even before - that's the beauty of versioning).

Then you set up exactly two sites in Apache - no more, no less. One site is and always will be your current live production site. The other is and always will be your QA/Staging/pre-production site. When you have a new change set you want to put live you first check out/update/merge changes for the appropriate revision number from the repository to the QA area, and re-test everything there to make sure it looks and works as expected. Assuming everything is okay, you can now do the same thing for your live site.

This keeps you from having to set up a new set of links or folders every time you want update your site and will work well with most of the tools commonly used to develop for the web. It will also do a much better job of tracking your history.


I'm not sure an apache install will let you serve up pages from symlinks anyway. I know mine won't.

  • 1
    It will with the appropriate Options. httpd.apache.org/docs/2.2/mod/core.html#options – Ignacio Vazquez-Abrams Nov 30 '10 at 14:25
  • I'm not sure if any default options have been changed or not, the last guy that did all this stuff was more familiar with that kind of stuff than me...he could have changed that setting I suppose. But I do know that it works for us. – Travesty3 Nov 30 '10 at 17:39

@Ignacio Vazquez-Abrams:

Your answer looks like my solution, but I had to change it a bit and I need some extra help on it. My .htaccess file (located at /var/www/LicenseManager, which is the root of my domain) looks like this:

Options +FollowSymLinks
Options +Indexes
RewriteEngine On
RewriteBase /
RewriteRule dev(.*) /var/www/LicenseManager/LicenseManager1.02/$1 [L]
RewriteRule test(.*) /var/www/LicenseManager/LicenseManager1.02/$1 [L]
RewriteRule ^$ /var/www/LicenseManager/LicenseManager1.02/$1 [L]

I have a few questions on this. With it set up this way, it works fine if my URL is "http://my-url.com/dev/", but if my URL is "http://my-url.com/dev" (without the trailing slash), then my include files are not found (CSS and JavaScript files). I'm not very familiar with regex, so perhaps it's just a matter of fixing those.

Also, I had to replace the fourth line in your example with the one from mine, otherwise I was getting an internal server error. After changing it, it works for either "http://my-url.com" or "http://my-url.com/", but in either case I still have the problem with my include files.

So how can I change my .htaccess file so that the include files are found with or without the trailing slash?

Thanks again!


P.S. I know that this isn't supposed to work like a forum, and that I should be posting a comment on someone else's post as an answer, but my question would be much more difficult to read in a comment box, without formatting. Plus I'm far too long-winded to fit all I need in the comment box.


Solved it! Here is what my final .htaccess file looks like:

Options +FollowSymLinks
Options +Indexes
RewriteEngine On
RewriteBase /
RewriteRule ^dev$ dev/ [R]
RewriteRule ^test$ test/ [R]
RewriteRule ^dev/(.*) /var/www/LicenseManager/LicenseManager1.02/$1 [L]
RewriteRule ^test/(.*) /var/www/LicenseManager/LicenseManager1.02/$1 [L]
RewriteRule ^(src/(.*)|$) /var/www/LicenseManager/LicenseManager1.02/$1 [L]

I had to change the regexes around a bit because with the way they were, they would match if "dev" or "test" was found anywhere, so "http://my-url.com/garbage/blahdevblah.html" would be redirected to "http://my-url.com/dev/". The caret (^) ensures that "dev" can only be found at the beginning, and the dollar sign ($) ensures that nothing else follows "dev". I changed the others to make sure that something like "http://my-url.com/garbagedev/nothing.html" doesn't match the rule.

For the last rule, I realized that if the regex is just (.*), that it matches anything, so even after it redirects, it still matches and attempts to redirect again, resulting in an endless loop, which ultimately shows you a 500 Internal Server Error. The "src" folder is the only directory in my project, and index.php is the only script in the main folder (index.php is automatically shown when omitted). So the last rule basically says "if the string starts with "src/" OR is blank, redirect."

Thanks again for your help, Ignacio!

  • Put the slashes back at the end of the first two rules, and add two rules before them that redirect ([R]) the path without slashes to the path with slashes. Then add the group back to the third rule. – Ignacio Vazquez-Abrams Dec 1 '10 at 2:43
  • Thanks again for the help. I got the first two to work by adding the redirect rules AFTER the other two. I'm still having trouble with the third rule, however. Notice that I have a "RewriteBase /", and with that, I needed to remove the beginning slash for the rules. Without the RewriteBase, I was getting a 404 error. If my third rule is just (.*), I get an internal server error. Anything else I can do to get the third rule to work? – Travesty3 Dec 2 '10 at 16:16
  • OK, I just figured out the problem. with the third rule just being (.*), it matches anything. So after it redirects, it still matches, and attempts to redirect again, in an infinite loop, which is what I think was causing the internal server error. To fix this, I changed it to ^(src/(.)|$) since src is the only directory in my project and index.php is the only script NOT in the src directory. – Travesty3 Dec 2 '10 at 20:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.