using Starman for powering dancer apps
I have been using Dancer exclusively with Apache until now, but in a new environment, I want to experiment with Starman (or any other perl-based server) via Apache proxy. The machine in question is running Apache, and I am not inclined to tinker with that more than the minimum necessary. I created an app "foo" in ~/Documents/www. I am able to run it like so ~/Documents/www/foo$ plackup -E deployment -s Starman --workers=10 -p 5001 -a bin/app.pl 2011/07/03-17:43:13 Starman::Server (type Net::Server::PreFork) starting! pid(3374) Binding to TCP port 5001 on host * Setting gid to "501 501 501 401 204 100 98 80 61 12 102 402" Going to http://127.0.0.1:5001/ gives me my app "foo" Now, I added the following in the apache conf file ---- ProxyRequests Off <Proxy *> Order deny,allow Allow from all </Proxy> ProxyPass /foo http://127.0.0.1:5001 ProxyPassReverse /foo http://127.0.0.1:5001 ---- and then, going to http://mycomputer.local/foo also returns my app "foo" correctly. Ok, then I added another app "bar" under ~/Documents/www (sibling to "foo"). Now, I am trying to run multiple apps as per the instructions at [http://search.cpan.org/~sukria/Dancer-1.3060/lib/Dancer/Deployment.pod] under the heading "Running multiple apps with Plack::Builder". I created the following web.psgi file in ~/bin ---- use Dancer ':syntax'; use Plack::Builder; setting apphandler => 'PSGI'; my $app1 = sub { my $env = shift; setting appdir => '/Users/punkish/Documents/www/foo', setting appname => 'foo'; load_app "foo"; Dancer::Config->load; my $request = Dancer::Request->new( env => $env ); Dancer->dance( $request ); }; my $app2 = sub { my $env = shift; setting appdir => '/Users/punkish/Documents/www/bar', setting appname => 'bar'; load_app "bar"; Dancer::Config->load; my $request = Dancer::Request->new( env => $env ); Dancer->dance( $request ); }; builder { mount "/foo" => builder {$app1}; mount "/bar" => builder {$app2}; }; ---- and then I entered the following command: ~/bin$ plackup -E deployment -s Starman --workers=10 -p 5001 -a ~/bin/web.psgi But, now I get "Not Found" error. So, besides generally seeking guidance for this, I have the following specific questions -- One, in "setting appdir => '/Users/punkish/Documents/www/foo'" what exactly is my appdir? Is '/Users/punkish/Documents/www/foo' correct? Two, are both "foo" and "bar" going to be accessible at http://127.0.0.1:5001/? Do I just add the following lines to my httpd.conf ---- ProxyPass /foo http://127.0.0.1:5001 ProxyPassReverse /foo http://127.0.0.1:5001 ProxyPass /bar http://127.0.0.1:5001 ProxyPassReverse /bar http://127.0.0.1:5001 ---- Three, how do I run plackup in the background? I want to run it, but be able to close the shell, and even logout and have it running. Four, if I have a single web.psgi as above, one disadvantage is that if I tinker with any one app, and have to turn off or restart Starman, it will affect all the apps powered by Starman. Perhaps a better situation would be to have a separate Starman process for each app. What is the best practice here? Puneet.
Following up on my own email, I discovered a solution, and encountered another problem. See below, but note, the deployment documentation is still woefully inadequate -- On Jul 3, 2011, at 5:59 PM, Mr. Puneet Kishor wrote:
I have been using Dancer exclusively with Apache until now, but in a new environment, I want to experiment with Starman (or any other perl-based server) via Apache proxy. The machine in question is running Apache, and I am not inclined to tinker with that more than the minimum necessary.
I created an app "foo" in ~/Documents/www. I am able to run it like so
~/Documents/www/foo$ plackup -E deployment -s Starman --workers=10 -p 5001 -a bin/app.pl 2011/07/03-17:43:13 Starman::Server (type Net::Server::PreFork) starting! pid(3374) Binding to TCP port 5001 on host * Setting gid to "501 501 501 401 204 100 98 80 61 12 102 402"
Going to http://127.0.0.1:5001/ gives me my app "foo"
Now, I added the following in the apache conf file
---- ProxyRequests Off
<Proxy *> Order deny,allow Allow from all </Proxy>
ProxyPass /foo http://127.0.0.1:5001 ProxyPassReverse /foo http://127.0.0.1:5001 ----
and then, going to http://mycomputer.local/foo also returns my app "foo" correctly. Ok, then I added another app "bar" under ~/Documents/www (sibling to "foo"). Now, I am trying to run multiple apps as per the instructions at [http://search.cpan.org/~sukria/Dancer-1.3060/lib/Dancer/Deployment.pod] under the heading "Running multiple apps with Plack::Builder". I created the following web.psgi file in ~/bin
---- use Dancer ':syntax'; use Plack::Builder;
setting apphandler => 'PSGI';
my $app1 = sub { my $env = shift; setting appdir => '/Users/punkish/Documents/www/foo', setting appname => 'foo'; load_app "foo"; Dancer::Config->load; my $request = Dancer::Request->new( env => $env ); Dancer->dance( $request ); };
my $app2 = sub { my $env = shift; setting appdir => '/Users/punkish/Documents/www/bar', setting appname => 'bar'; load_app "bar"; Dancer::Config->load; my $request = Dancer::Request->new( env => $env ); Dancer->dance( $request ); };
builder { mount "/foo" => builder {$app1}; mount "/bar" => builder {$app2}; }; ----
Looking at [https://github.com/sukria/Dancer/commit/6c7ea733d5eac1d9ccfe39d70580ecf7d189...], I discovered that the documentation is wrong. Per the fix suggested at the above commit link, I changed the above to my $app1 = sub { my $env = shift; local $ENV{DANCER_APPDIR} = "/Users/punkish/Documents/www/foo"; setting appdir => "/Users/punkish/Documents/www/foo"; load_app "foo"; Dancer::App->set_running_app('foo'); Dancer::Config->load; my $request = Dancer::Request->new( env => $env ); Dancer->dance( $request ); };
and then I entered the following command:
~/bin$ plackup -E deployment -s Starman --workers=10 -p 5001 -a ~/bin/web.psgi
But, now I get "Not Found" error. So, besides generally seeking guidance for this, I have the following specific questions --
One, in "setting appdir => '/Users/punkish/Documents/www/foo'" what exactly is my appdir? Is '/Users/punkish/Documents/www/foo' correct?
The above appdir is correct.
Two, are both "foo" and "bar" going to be accessible at http://127.0.0.1:5001/? Do I just add the following lines to my httpd.conf
---- ProxyPass /foo http://127.0.0.1:5001 ProxyPassReverse /foo http://127.0.0.1:5001 ProxyPass /bar http://127.0.0.1:5001 ProxyPassReverse /bar http://127.0.0.1:5001 ----
I have to change the above to ProxyPass /foo http://127.0.0.1:5001/foo ProxyPassReverse /foo http://127.0.0.1:5001/foo ProxyPass /bar http://127.0.0.1:5001/bar ProxyPassReverse /bar http://127.0.0.1:5001/bar Now, I can access http://myserver.com/foo and http://myserver.com/bar and get my Dancer apps. There is a new problem -- seems like relative paths for files in the public folder are not calculated properly. If I request http://myserver.com/foo, I get the content, but I don't get any of the stylesheets in '/Users/punkish/Documents/www/foo/public/css' (they all result in 404). On the other hand, if I request http://myserver.com/foo/ (note the trailing slash) then the path to the stylesheets is resolved correctly. How do I fix this? Additionally, I still don't know the answer to the following two questions.
Three, how do I run plackup in the background? I want to run it, but be able to close the shell, and even logout and have it running.
Four, if I have a single web.psgi as above, one disadvantage is that if I tinker with any one app, and have to turn off or restart Starman, it will affect all the apps powered by Starman. Perhaps a better situation would be to have a separate Starman process for each app. What is the best practice here?
Puneet.
Hi, On Sun, Jul 3, 2011 at 11:59 PM, Mr. Puneet Kishor <punk.kish@gmail.com> wrote:
Ok, then I added another app "bar" under ~/Documents/www (sibling to "foo"). Now, I am trying to run multiple apps as per the instructions at [http://search.cpan.org/~sukria/Dancer-1.3060/lib/Dancer/Deployment.pod] under the heading "Running multiple apps with Plack::Builder".
There was a thread one or two weeks back discussing this point. I didn't pay much attention to it, but I think the result was that the current instructions are wrong and a new version was committed to the git repo for the next release. Check the ML archives.
I created the following web.psgi file in ~/bin
---- [...]
builder { mount "/foo" => builder {$app1}; mount "/bar" => builder {$app2}; }; ----
<aside> Running multiple Dancer apps in the same process can be done, but I've always found it to be awkward. Its a design thing. Dancer uses a lot of global variables to do its magic so you need to keep switching the global context, including the configuration, per request. Its a tradeoff: you get a very cool and simple DSL to manipulate your request and response, but this requires a global context. For the same reason, its practically impossible to use Dancer with Twiggy and do long polling, where each perl interpreter will have multiple requests going at the same time. I don't see this as bugs or limitations, on the contrary. They are design tradeoffs, where you get a very very practical DSL but loose the possibility to do some things. I like that Dancer is willing to loose some features in order to be excellent at the rest. Not many frameworks are willing to do that, and the Dancer developers should be commended by this. </aside> If you are using a frontend reverse proxy (apache in your case), then my suggestion is that you start two starman instances with plackup, one for foo app and another for bar app, on different ports, and configure apache to do the proper url mapping to each one. Its simpler, IMHO more robust, and you can start/stop/restart each app separately, and tune the number of workers per app. I reverse setting up multiple apps in the same perl interpreter for very extreme cases, and I don't recommend it as a general solution.
Two, are both "foo" and "bar" going to be accessible at http://127.0.0.1:5001/? Do I just add the following lines to my httpd.conf
---- ProxyPass /foo http://127.0.0.1:5001 ProxyPassReverse /foo http://127.0.0.1:5001 ProxyPass /bar http://127.0.0.1:5001 ProxyPassReverse /bar http://127.0.0.1:5001 ----
If you follow my suggestion above, tweek the second pair of lines to use 5002.
Three, how do I run plackup in the background? I want to run it, but be able to close the shell, and even logout and have it running.
nohup plackup_cmd_line & is the usual way to do this, but plackup has a better way: -D, --daemonize Makes the process go background. It's up to the backend server/handler implementation whether this option is respected or not.
Four, if I have a single web.psgi as above, one disadvantage is that if I tinker with any one app, and have to turn off or restart Starman, it will affect all the apps powered by Starman. Perhaps a better situation would be to have a separate Starman process for each app. What is the best practice here?
One plackup per app is my recommended approach as I wrote above. My modesty prevents me from calling this a "best practice" :) Bye, -- Pedro Melo @pedromelo http://www.simplicidade.org/ http://about.me/melo xmpp:melo@simplicidade.org mailto:melo@simplicidade.org
On Mon, Jul 4, 2011 at 3:55 AM, Pedro Melo <melo@simplicidade.org> wrote:
Hi,
On Sun, Jul 3, 2011 at 11:59 PM, Mr. Puneet Kishor <punk.kish@gmail.com> wrote:
Ok, then I added another app "bar" under ~/Documents/www (sibling to "foo"). Now, I am trying to run multiple apps as per the instructions at [http://search.cpan.org/~sukria/Dancer-1.3060/lib/Dancer/Deployment.pod] under the heading "Running multiple apps with Plack::Builder".
There was a thread one or two weeks back discussing this point. I didn't pay much attention to it, but I think the result was that the current instructions are wrong and a new version was committed to the git repo for the next release. Check the ML archives.
I created the following web.psgi file in ~/bin
---- [...]
builder { mount "/foo" => builder {$app1}; mount "/bar" => builder {$app2}; }; ----
<aside> Running multiple Dancer apps in the same process can be done, but I've always found it to be awkward.
Its a design thing. Dancer uses a lot of global variables to do its magic so you need to keep switching the global context, including the configuration, per request. Its a tradeoff: you get a very cool and simple DSL to manipulate your request and response, but this requires a global context.
For the same reason, its practically impossible to use Dancer with Twiggy and do long polling, where each perl interpreter will have multiple requests going at the same time.
I don't see this as bugs or limitations, on the contrary. They are design tradeoffs, where you get a very very practical DSL but loose the possibility to do some things. I like that Dancer is willing to loose some features in order to be excellent at the rest. Not many frameworks are willing to do that, and the Dancer developers should be commended by this. </aside>
If you are using a frontend reverse proxy (apache in your case), then my suggestion is that you start two starman instances with plackup, one for foo app and another for bar app, on different ports, and configure apache to do the proper url mapping to each one.
Its simpler, IMHO more robust, and you can start/stop/restart each app separately, and tune the number of workers per app.
I reverse setting up multiple apps in the same perl interpreter for very extreme cases, and I don't recommend it as a general solution.
Two, are both "foo" and "bar" going to be accessible at http://127.0.0.1:5001/? Do I just add the following lines to my httpd.conf
---- ProxyPass /foo http://127.0.0.1:5001 ProxyPassReverse /foo http://127.0.0.1:5001 ProxyPass /bar http://127.0.0.1:5001 ProxyPassReverse /bar http://127.0.0.1:5001 ----
If you follow my suggestion above, tweek the second pair of lines to use 5002.
Three, how do I run plackup in the background? I want to run it, but be able to close the shell, and even logout and have it running.
nohup plackup_cmd_line &
is the usual way to do this, but plackup has a better way:
-D, --daemonize Makes the process go background. It's up to the backend server/handler implementation whether this option is respected or not.
Four, if I have a single web.psgi as above, one disadvantage is that if I tinker with any one app, and have to turn off or restart Starman, it will affect all the apps powered by Starman. Perhaps a better situation would be to have a separate Starman process for each app. What is the best practice here?
One plackup per app is my recommended approach as I wrote above. My modesty prevents me from calling this a "best practice" :)
Bye, -- Pedro Melo
Pedro, I think your explanation was excellent about the tradeoff that Dancer makes. After reading this, I believe that the section in Dancer::Deployment pod on deploying multiple apps should contain a caveat. Something to the effect of, "Here is how you can deploy multiple apps, but this is not the way Dancer is meant to be used. Instead, consider multiple plackup processes." -Naveed
On 4-07-2011 at 9:55, Pedro Melo wrote:
One plackup per app is my recommended approach as I wrote above. My modesty prevents me from calling this a "best practice" :)
I combined multiple Dancer apps this way: ==== load_app 'ED::AccountServer::AdminWeb', prefix => '/app1'; load_app 'ED::AccountServer::APIWeb', prefix => '/app2'; dance; ==== Then, I'm using plack -s Starman -d to run everything. I prefer to do this because I need to run many different apps, and having a bunch of Starman processes for each app is memory-consuming. The load_app approach works nicely... apart from a few issues: https://github.com/sukria/Dancer/issues/425 https://github.com/sukria/Dancer/issues/421 https://github.com/sukria/Dancer/issues/429 Cheers, - alessandro.
participants (4)
-
Alessandro Ranellucci -
Mr. Puneet Kishor -
Naveed Massjouni -
Pedro Melo