I am developing a website, and I want to keep the live and some development code on the site. I was thinking of using .htaccess
to allow me to develop new code, and then cut over to the new version when ready. Is this a stupid idea? and what's wrong with my .htaccess
?
So, I have directories v1.1
and v1.2
in my web root.
and this is my .htaccess
file:
#########################
RewriteEngine On
RewriteRule ^live/(.*)$ v1.1/$1 [L]
Redirect 301 /live$ http://blah.com/live/
RewriteRule ^debug/(.*)$ v1.2/$1 [L]
# Disable directory browsing
Options All -Indexes
# Deny access to all .htaccess files
<files ~ "^.*\.([Hh][Tt][Aa])">
order allow,deny
deny from all
satisfy all
</files>
I've got this to work, and it allows example.com/live/
to show the code in v1.1
and example.com/debug
to let me play with the code in v1.2
.
There are 2 issues with this:
- The user sees the word
/live/
in the URL and may go digging... - I can't get the
.htaccess
file to redirectexample.com/
tov1.1/
I would prefer to have example.com/<almost anything>
to go to example.com/v1.1/
and example.com/debug/<anything>
to go to example.com/v1.2/
.
I tried...
RewriteRule ^$ v1.1/ [L]
and
RewriteRule ^(.*)$ v1.1/$1 [L]
but these did not work... (Internal Server Error).
I had a play with this excellent tool - https://htaccess.madewithlove.be/ - which seems to think my htaccess file is great (when obviously its not)
You can achieve this behaviour without any
RewriteRule
s by using symbolic links. If yourDocumentRoot
points to/var/www/html
, you could move your versioned directoriesv1.1
andv2.2
to/var/www
and symlink
v1.1
tohtml
Your live-version now points to
v1.1
.Then symlink
v1.2
insidev1.1
asdebug
You should then add some kind of access protection (password / ip address) to your development version.
When you're done with developing and want to switch to the new version, remove both symlinks and create new symlinks to the new live and development version.
You might need to enable FollowSymLinks if this option is disabled in your Apache config /
.htaccess
(default is enabled).Yes, this would certainly be preferable. (Also consider using a
debug
subdomain instead and keep the same URL-path for the "live" and "debug" versions.)Try the following instead:
The
RewriteRule
pattern!^(v\d\.\d|debug)/
ensures we do not rewrite requests that already start/vN.N/
(whereN
is a digit 0-9), or those that start/debug/
. This is to avoid a rewrite loop, after rewriting the request to/v1.1/...
or/v1.2/...
.Note, however, that
/v1.1/...
and/v1.2/...
are still directly accessible. You don't necessarily need to redirect these, unless these have previously been publicly accessible (and indexed / linked to by third parties).Aside...
This won't actually do anything. The
Redirect
directive does not take a regex as its second argument, so/live$
will never match (unless maybe you have a literal$
in your URL).Note also that
Redirect
is a mod_alias directive.RewriteRule
is mod_rewrite. You should avoid mixing redirects/rewrites from both modules as you can get unexpected results. (Different modules run at different times throughout the request, not necessarily in the order of the directives in your config file. On Apache mod_rewrite runs first.)This will result in an internal rewrite loop as
v1.1/...
will be rewritten repeatedly. This manifests itself as an HTTP 500 (Internal Server Error) response returned to the client when the internal redirection limit is reached (default 10 loops). See your server's error log for the details of the error.By itself,
RewriteRule ^$ v1.1/ [L]
should not have resulted in such an error.This does more than block
.htaccess
files, as it also matches files of the form<anything>.hta<anything>
.order
anddeny
are Apache 2.2 directives. If you are on Apache 2.4+ (which is more likely) then you should be usingRequire all denied
instead (the older Apache 2.2 directives are deprecated).However,
.htaccess
files should already be blocked by your server config, so this may be unnecessary anyway.