Configuring virtual hosts on the fly

Configuring virtual hosts on the fly

am 11.10.2009 20:54:27 von Scott Gifford

Hello,

I'm working on an Apache configuration for a cluster of machines
serving a variety of virtual hosts.

New virtual hosts are provisioned by a Web application, and all
information needed to set up the virtual hosts is in a database table.
I would like my Apache to set up the virtual hosts on the fly based on
information in the tables.

I have seen examples for generating the virtual hosts configuration
from a database when Apache starts. That leaves me with the problem
of how the unprivileged Web application doing the provisioning can
reliably trigger a reload across an entire cluster, and also what to
do if something goes wrong so I don't end up with a whole cluster of
dead Web servers.

It seems much cleaner to me to let Apache look up the information for
a virtual host as it is needed. Conceptually, when each request comes
in, I would like Apache to look at the Host: header, build a temporary
virtual host entry from that, and use it to service the request. I
will use caching to make it reasonably fast. Then the provisioning
script just writes to the database table and is done, and I can handle
any errors on a per-request basis without Apache failing to start.

I see some hooks in PerlTransHandler and PerlMapToStorageHandler that
seem like they can almost do what I want, but I don't see how to set
other virtual host parameters, like ServerAdmin, UseCanonicalName,
etc.

I'm just starting to work on this, and I thought I would see if
anybody had tried anything similar before and had some suggestions for
what to do, or what not to do.

Thanks!

----Scott.

Re: Configuring virtual hosts on the fly

am 11.10.2009 22:32:25 von aw

Scott Gifford wrote:
> Hello,
>
> I'm working on an Apache configuration for a cluster of machines
> serving a variety of virtual hosts.
>
> New virtual hosts are provisioned by a Web application, and all
> information needed to set up the virtual hosts is in a database table.
> I would like my Apache to set up the virtual hosts on the fly based on
> information in the tables.
Sounds intersting.

>
> I have seen examples for generating the virtual hosts configuration
> from a database when Apache starts. That leaves me with the problem
> of how the unprivileged Web application doing the provisioning can
> reliably trigger a reload across an entire cluster, and also what to
> do if something goes wrong so I don't end up with a whole cluster of
> dead Web servers.
>
> It seems much cleaner to me to let Apache look up the information for
> a virtual host as it is needed. Conceptually, when each request comes
> in, I would like Apache to look at the Host: header, build a temporary
> virtual host entry from that, and use it to service the request. I
> will use caching to make it reasonably fast. Then the provisioning
> script just writes to the database table and is done, and I can handle
> any errors on a per-request basis without Apache failing to start.
>
> I see some hooks in PerlTransHandler and PerlMapToStorageHandler that
> seem like they can almost do what I want, but I don't see how to set
> other virtual host parameters, like ServerAdmin
http://perl.apache.org/docs/2.0/api/Apache2/ServerRec.html#C _server_admin_

, UseCanonicalName,
> etc.
>
> I'm just starting to work on this, and I thought I would see if
> anybody had tried anything similar before and had some suggestions for
> what to do, or what not to do.
>
I have never tried this myself, but the mod_perl 2.x documentation
contains some hints that leads to believe that it should be possible.
Like
http://perl.apache.org/docs/2.0/api/Apache2/ServerRec.html
http://perl.apache.org/docs/2.0/api/Apache2/ServerUtil.html
http://perl.apache.org/docs/2.0/api/Apache2/PerlSections.htm l
....

I would start by defining a single VirtualHost (which will thus be the
default host), with a variety of configuration sections, and see if I
can *modify* them on-the-fly. Assuming that the VirtualHosts which you
want to configure on-the-fly have some high degree of similarity, that
sounds easier to do than building a whole configuration each time from
scratch.
Like

....


....

and then modify the first Location to become

....

etc..

Re: Configuring virtual hosts on the fly

am 12.10.2009 13:34:20 von torsten.foertsch

On Sun 11 Oct 2009, Andr=E9 Warnier wrote:
> > I see some hooks in PerlTransHandler and PerlMapToStorageHandler
> > that seem like they can almost do what I want, but I don't see how
> > to set other virtual host parameters, like ServerAdmin
>
> http://perl.apache.org/docs/2.0/api/Apache2/ServerRec.html#C _server_a
>dmin_
>
> , UseCanonicalName,
>
> > etc.
> >
> > I'm just starting to work on this, and I thought I would see if
> > anybody had tried anything similar before and had some suggestions
> > for what to do, or what not to do.
>
> I have never tried this myself, but the mod_perl 2.x documentation
> contains some hints that leads to believe that it should be possible.

Some things could work this way, others definitely will not. For example=20
you cannot create an IP based vhost on demand. You cannot create log=20
files on the fly. Well, you can but you cannot create them as root as=20
it is done during startup.

In general its not a good idea to mess with things that are not marked=20
as applicable in directory context for the following reason. Firstly,=20
you have to make sure to reset them when you request is done. See the=20
implementation of $r->document_root for example. And secondly, in a=20
threaded environment changing those values in one thread can affect the=20
behavior of other requests in other threads because they are shared.

UseCanonicalName is applyable in directory context. So, you can safely=20
set it via $r->add_config. It may however be useless to set it in a=20
translation or map2storage handler because if you have a directory or=20
location container or even a .htaccess file that sets the directive it=20
overwrites anything set in a translation handler. Best phase to do that=20
is probably fixup.

ServerAdmin is valid only in server config and virtual host context=20
(http://httpd.apache.org/docs/2.2/mod/core.html#serveradmin) . So I=20
wouldn't mess with that. Better create custom error pages.

Torsten

=2D-=20
Need professional mod_perl support?
Just hire me: torsten.foertsch@gmx.net

Re: Configuring virtual hosts on the fly

am 12.10.2009 18:57:50 von Adam Prime

Scott Gifford wrote:
> Hello,
>
> I'm working on an Apache configuration for a cluster of machines
> serving a variety of virtual hosts.
>
> New virtual hosts are provisioned by a Web application, and all
> information needed to set up the virtual hosts is in a database table.
> I would like my Apache to set up the virtual hosts on the fly based on
> information in the tables.
>
> I have seen examples for generating the virtual hosts configuration
> from a database when Apache starts. That leaves me with the problem
> of how the unprivileged Web application doing the provisioning can
> reliably trigger a reload across an entire cluster, and also what to
> do if something goes wrong so I don't end up with a whole cluster of
> dead Web servers.
>
> It seems much cleaner to me to let Apache look up the information for
> a virtual host as it is needed. Conceptually, when each request comes
> in, I would like Apache to look at the Host: header, build a temporary
> virtual host entry from that, and use it to service the request. I
> will use caching to make it reasonably fast. Then the provisioning
> script just writes to the database table and is done, and I can handle
> any errors on a per-request basis without Apache failing to start.
>
> I see some hooks in PerlTransHandler and PerlMapToStorageHandler that
> seem like they can almost do what I want, but I don't see how to set
> other virtual host parameters, like ServerAdmin, UseCanonicalName,
> etc.
>
> I'm just starting to work on this, and I thought I would see if
> anybody had tried anything similar before and had some suggestions for
> what to do, or what not to do.
>
> Thanks!

I did some cursory investigation into something sort of like this, at
least the idea that the application would be able to create new virtual
hosts, and that those vhosts should start 'working' (for some definition
of working) immediately.

The approach that I had intended to take with regards to getting the
name based vhosts to work immediately (without a restart) was to have a
default virtual host that would detect requests that were coming in for
vhosts that we should be able to handle, and then setting up the handler
stack for that request using push_handlers in an init handler. There
are some problems with this approach (segmenting logs for one), but the
idea for me was to get the thing to work right away, and if it took
until the next restart to get the vhost actually configured as a vhost
properly, that wasn't a huge deal.

Not sure if that's any help or not, but...

Adam

Re: Configuring virtual hosts on the fly

am 13.10.2009 16:46:48 von William T

On Sun, Oct 11, 2009 at 11:54 AM, Scott Gifford
wrote:
> Hello,
>
> I'm working on an Apache configuration for a cluster of machines
> serving a variety of virtual hosts.

I would not try to unify disparate configs into one unless each server
is actually going to service all the virtual hosts your pulling in.
You would unnecessarily couple configs together that don't need to be.

> It seems much cleaner to me to let Apache look up the information for
> a virtual host as it is needed. =A0Conceptually, when each request comes
> in, I would like Apache to look at the Host: header, build a temporary
> virtual host entry from that, and use it to service the request. =A0I
> will use caching to make it reasonably fast. =A0Then the provisioning
> script just writes to the database table and is done, and I can handle
> any errors on a per-request basis without Apache failing to start.

Sounds like you might be pushing the envelope on what Apache can
actually do. If you cannot solve the problem in Apache you could
consider relying on Apache default vhost as a way to funnel all
requests into a Perl "dynamic vhost" implementation. You get exactly
what your looking for, but you tradeoff the speed and maturity of
Apache vhost code for yours.

-wjt

Re: Configuring virtual hosts on the fly

am 13.10.2009 17:08:45 von Scott Gifford

Thanks William, comments inline...

William T writes:

> On Sun, Oct 11, 2009 at 11:54 AM, Scott Gifford
> wrote:
>> Hello,
>>
>> I'm working on an Apache configuration for a cluster of machines
>> serving a variety of virtual hosts.
>
> I would not try to unify disparate configs into one unless each server
> is actually going to service all the virtual hosts your pulling in.
> You would unnecessarily couple configs together that don't need to
> be.

Each server will actually service all of the virtual hosts, so there
won't be anything unnecessary there.

[...]

> Sounds like you might be pushing the envelope on what Apache can
> actually do. If you cannot solve the problem in Apache you could
> consider relying on Apache default vhost as a way to funnel all
> requests into a Perl "dynamic vhost" implementation. You get exactly
> what your looking for, but you tradeoff the speed and maturity of
> Apache vhost code for yours.

Thanks, I will definitely take a look! Do you have any recommended
reading on this, or just what Google turns up for "dynamic vhost"?

Thanks again!

---Scott.

Re: Configuring virtual hosts on the fly

am 13.10.2009 17:23:35 von William T

On Tue, Oct 13, 2009 at 8:08 AM, Scott Gifford
wrote:
>> Sounds like you might be pushing the envelope on what Apache can
>> actually do. =A0If you cannot solve the problem in Apache you could
>> consider relying on Apache default vhost as a way to funnel all
>> requests into a Perl "dynamic vhost" implementation. =A0You get exactly
>> what your looking for, but you tradeoff the speed and maturity of
>> Apache vhost code for yours.
>
> Thanks, I will definitely take a look! =A0Do you have any recommended
> reading on this, or just what Google turns up for "dynamic vhost"?

I don't know of anything that specifically does this, then again I
havn't looked. I was mainly thinking about pushing the problem into a
different layer since I wasn't sure the Apache layer would work. If
it were me I would probably start by looking for through "Mass Dynamic
Virtual Hosting" and make sure you can't solve your problem in the
Apache layer, or with a ModPerl Apache module to extend Apache (either
one already written, or one you write yourself). Then move on to Perl
code that does webserving.

-wjt

RE: Configuring virtual hosts on the fly

am 13.10.2009 17:27:20 von Ryan Yagatich

What about mod_vhost_alias? (
http://httpd.apache.org/docs/2.0/mod/mod_vhost_alias.html )


Summary

This module creates dynamically configured virtual hosts, by allowing the IP
address and/or the Host: header of the HTTP request to be used as part of
the pathname to determine what files to serve. This allows for easy use of a
huge number of virtual hosts with similar configurations.





-----Original Message-----
From: Scott Gifford [mailto:sgifford@suspectclass.com]
Sent: Tuesday, October 13, 2009 11:09 AM
To: William T
Cc: modperl@perl.apache.org
Subject: Re: Configuring virtual hosts on the fly

Thanks William, comments inline...

William T writes:

> On Sun, Oct 11, 2009 at 11:54 AM, Scott Gifford
> wrote:
>> Hello,
>>
>> I'm working on an Apache configuration for a cluster of machines
>> serving a variety of virtual hosts.
>
> I would not try to unify disparate configs into one unless each server
> is actually going to service all the virtual hosts your pulling in.
> You would unnecessarily couple configs together that don't need to
> be.

Each server will actually service all of the virtual hosts, so there
won't be anything unnecessary there.

[...]

> Sounds like you might be pushing the envelope on what Apache can
> actually do. If you cannot solve the problem in Apache you could
> consider relying on Apache default vhost as a way to funnel all
> requests into a Perl "dynamic vhost" implementation. You get exactly
> what your looking for, but you tradeoff the speed and maturity of
> Apache vhost code for yours.

Thanks, I will definitely take a look! Do you have any recommended
reading on this, or just what Google turns up for "dynamic vhost"?

Thanks again!

---Scott.

Re: Configuring virtual hosts on the fly

am 13.10.2009 17:51:43 von mpeters

Looking at this from a different perspective, have you tried writing a
monitoring program that looks for updates to the database and then would
restart the appropriate apache servers on the various machines. It would
do them one at a time (taking them out of rotation from your load
balancer). It wouldn't be immediate response, could definitely be done
in under a minute.

--
Michael Peters
Plus Three, LP

Re: Configuring virtual hosts on the fly

am 13.10.2009 18:17:06 von Scott Gifford

Michael Peters writes:

> Looking at this from a different perspective, have you tried writing a
> monitoring program that looks for updates to the database and then
> would restart the appropriate apache servers on the various
> machines. It would do them one at a time (taking them out of rotation
> from your load balancer). It wouldn't be immediate response, could
> definitely be done in under a minute.

Thanks Michael,

I thought about that. It is probably what I will do if I can't get
something a little cleaner.

I have had mixed experiences in the past with automatically restarting
Apache after a configuration change. It is very easy to end up with
something unexpected in the configuration, which causes the
configuration to fail, which causes apache to stop. And with a
cluster, that would happen on all hosts.

Now, ideally, I wouldn't make any errors in my configuration code and
this would never be an issue. But I have learned the hard way that
making things as foolproof as possible is the best way to protect
myself from my own foolishness. :-)

When I have done this in the past, I have done it with generating
configuration files, so of course one misplaced newline or
angle-bracket will kill the server. Maybe generating the
configuration directly from a section is more robust? Maybe
there are ways to catch configuration errors in that layer and handle
them cleanly without preventing Apache from starting? Any suggestions
in this area would be appreciated.

Thanks again!

-----Scott.

Re: Configuring virtual hosts on the fly

am 13.10.2009 18:19:26 von Scott Gifford

"Ryan Yagatich" writes:

> What about mod_vhost_alias? (
> http://httpd.apache.org/docs/2.0/mod/mod_vhost_alias.html )
>
>
> Summary
>
> This module creates dynamically configured virtual hosts, by allowing the IP
> address and/or the Host: header of the HTTP request to be used as part of
> the pathname to determine what files to serve. This allows for easy use of a
> huge number of virtual hosts with similar configurations.
>


Thanks! That looks very close to what I want. I wonder if there is a
way to do a database lookup and substitute that?...

----Scott.

Re: Configuring virtual hosts on the fly

am 13.10.2009 18:31:00 von Joel Richard

I thought I'd weigh in on two items of note....

On Oct 13, 2009, at 12:17 PM, Scott Gifford wrote:

> When I have done this in the past, I have done it with generating
> configuration files, so of course one misplaced newline or
> angle-bracket will kill the server. Maybe generating the
> configuration directly from a section is more robust? Maybe
> there are ways to catch configuration errors in that layer and handle
> them cleanly without preventing Apache from starting? Any suggestions
> in this area would be appreciated.
>


It seems to me that you are assuming that your script must apply the
new configuration to the live apache server.

Why not have your script simply apply a potential new configuration to
a "test" apache installation (separate from all others), have it
restart apache there, hit a few critical URLs to test functionality
and then report to you if there's an error. If it's successful, it can
then apply that config to the live cluster, keeping fingers crossed,
of course. (and making sure your monitoring software is going to pull
the fire alarm if the cluster goes down.)

If there's an error, you have some time to gracefully solve it and
your system continues to run in the meantime. Of course, this means
that the new configuration wasn't applied, but in the grand scheme of
things, a missing update to a config is far, far better than taking
down an entire cluster because your automatic configurator has a screw
loose.


On another note, regarding mod_vhost_alias and a database lookup to
dynamically do something...

> "Ryan Yagatich" writes:
>
>> What about mod_vhost_alias? (
>> http://httpd.apache.org/docs/2.0/mod/mod_vhost_alias.html )
>>
>>
>> Summary
>>
>> This module creates dynamically configured virtual hosts, by
>> allowing the IP
>> address and/or the Host: header of the HTTP request to be used as
>> part of
>> the pathname to determine what files to serve. This allows for easy
>> use of a
>> huge number of virtual hosts with similar configurations.
>>

>
> Thanks! That looks very close to what I want. I wonder if there is a
> way to do a database lookup and substitute that?...
>

In my experience, you really want to minimize the hits on your
database and placing a lookup of any kind for -every- connection to
apache would be murderous regardless of which database you're using.

--Joel

Re: Configuring virtual hosts on the fly

am 13.10.2009 18:50:14 von mpeters

On 10/13/2009 12:17 PM, Scott Gifford wrote:

> I have had mixed experiences in the past with automatically restarting
> Apache after a configuration change. It is very easy to end up with
> something unexpected in the configuration, which causes the
> configuration to fail, which causes apache to stop. And with a
> cluster, that would happen on all hosts.

If you run apache with a -t option it will check that the configuration
is sane. I'm assuming that your configuration is auto-generated by this
monitor somehow, then you can create a new config file and test it with

httpd -t -f /path/to/new/file

Then if it's ok, you can move it to the real location and do the restart.

> When I have done this in the past, I have done it with generating
> configuration files, so of course one misplaced newline or
> angle-bracket will kill the server.

I generally prefer generated config files, especially if you have
multiple sites with basically the same config. I also use templated
config files so that the template I'm working on looks a lot like the
finished product. It's easier to prevent typos this way, IMO.

--
Michael Peters
Plus Three, LP

Re: Configuring virtual hosts on the fly

am 13.10.2009 23:28:12 von Scott Gifford

Joel Richard writes:

> I thought I'd weigh in on two items of note....
>
> On Oct 13, 2009, at 12:17 PM, Scott Gifford wrote:
>
>> When I have done this in the past, I have done it with generating
>> configuration files, so of course one misplaced newline or
>> angle-bracket will kill the server. Maybe generating the
>> configuration directly from a section is more robust? Maybe
>> there are ways to catch configuration errors in that layer and handle
>> them cleanly without preventing Apache from starting? Any suggestions
>> in this area would be appreciated.
>>
>
>
> It seems to me that you are assuming that your script must apply the
> new configuration to the live apache server.
>
> Why not have your script simply apply a potential new configuration to
> a "test" apache installation (separate from all others), have it
> restart apache there, hit a few critical URLs to test functionality
> and then report to you if there's an error. If it's successful, it can
> then apply that config to the live cluster, keeping fingers crossed,
> of course. (and making sure your monitoring software is going to pull
> the fire alarm if the cluster goes down.)

That's a good idea, though a bit involved to implement.

> If there's an error, you have some time to gracefully solve it and

Yeah, good point, thanks.

[...]

>> Thanks! That looks very close to what I want. I wonder if there is a
>> way to do a database lookup and substitute that?...
>>
>
> In my experience, you really want to minimize the hits on your
> database and placing a lookup of any kind for -every- connection to
> apache would be murderous regardless of which database you're using.

Right, absolutely the result would have to be cached. Then I think it
would be no problem.

----Scott.

Re: Configuring virtual hosts on the fly

am 14.10.2009 09:54:48 von Scott Gifford

Scott Gifford writes:

[...]

> I see some hooks in PerlTransHandler and PerlMapToStorageHandler that
> seem like they can almost do what I want, but I don't see how to set
> other virtual host parameters, like ServerAdmin, UseCanonicalName,
> etc.

I was able to get something I like working in PerlTransHandler. I
have it configured like this:

PerlTransHandler My::VirtualHost::TransHandler

Then in My::VirtualHost::TransHandler:

our %sitepath;
sub handler {
my $r = shift;
my $hn = $r->hostname();
if (!$hn) {
return Apache2::Const::DECLINED;
}
if (!exists($sitepath{$hn})) {
$sitepath{$hn} = db_lookup($hn);
}
if ($sitepath{$hn}) {
$r->filename($sitepath{$hn}.$r->uri());
return Apache2::Const::OK;
} else {
return Apache2::Const::DECLINED;
}

Thanks for all the suggestions, they were very helpful!

----Scott.