1Dancer::Deployment(3) User Contributed Perl DocumentationDancer::Deployment(3)
2
3
4
6 Dancer::Deployment - common ways to put your Dancer app into use
7
9 version 1.3513
10
12 Dancer has been designed to be flexible, and this flexibility extends
13 to your choices when deploying your Dancer app.
14
15 Running as a cgi-script (or fast-cgi) under Apache
16 In providing ultimate flexibility in terms of deployment, your Dancer
17 app can be run as a simple cgi-script out-of-the-box with no additional
18 web server configuration needed. Your web server should recognize .cgi
19 files and be able to serve Perl scripts. The Perl module Plack::Runner
20 is required.
21
22 Start by adding the following to your apache configuration (httpd.conf
23 or sites-available/*site*):
24
25 <VirtualHost *:80>
26 ServerName www.example.com
27
28 # /srv/www.example.com is the root of your
29 # dancer application
30 DocumentRoot /srv/www.example.com/public
31
32 ServerAdmin you@example.com
33
34 <Directory "/srv/www.example.com/public">
35 AllowOverride None
36 Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
37 Order allow,deny
38 Allow from all
39 AddHandler cgi-script .cgi
40 </Directory>
41
42 ScriptAlias / /srv/www.example.com/public/dispatch.cgi/
43
44 ErrorLog /var/log/apache2/www.example.com-error.log
45 CustomLog /var/log/apache2/www.example.com-access_log common
46 </VirtualHost>
47
48 Now you can access your dancer application URLs as if you were using
49 the embedded web server.
50
51 http://localhost/
52
53 This option is a no-brainer, easy to setup, low maintenance but serves
54 requests slower than all other options.
55
56 You can use the same technique to deploy with FastCGI, by just changing
57 the lines:
58
59 AddHandler cgi-script .cgi
60
61 ...
62
63 ScriptAlias / /srv/www.example.com/public/dispatch.cgi
64
65 To:
66
67 AddHandler fastcgi-script .fcgi
68
69 ...
70
71 ScriptAlias / /srv/www.example.com/public/dispatch.fcgi
72
73 Running stand-alone
74 At the simplest, your Dancer app can run standalone, operating as its
75 own webserver using HTTP::Server::Simple::PSGI.
76
77 Simply fire up your app:
78
79 $ perl bin/app.pl
80 >> Listening on 0.0.0.0:3000
81 == Entering the dance floor ...
82
83 Point your browser at it, and away you go!
84
85 This option can be useful for small personal web apps or internal apps,
86 but if you want to make your app available to the world, it probably
87 won't suit you.
88
89 Running on Perl webservers with plackup
90
91 A number of Perl web servers supporting PSGI are available on cpan:
92
93 Starman
94 "Starman" is a high performance web server, with support for
95 preforking, signals and more.
96
97 Twiggy
98 "Twiggy" is an "AnyEvent" web server, it's light and fast.
99
100 Corona
101 "Corona" is a "Coro" based web server.
102
103 WARNING: "Dancer"'s use of global variables and "Coro"'s threaded
104 behaviors can cause some unexpected behaviors. See this GitHub
105 issue <https://github.com/PerlDancer/Dancer/issues/929> for more
106 details. Unless you have really, really strongly compelling
107 reasons to use Corona, consider using "Twiggy" or "Starman"
108 instead.
109
110 To start your application, just run plackup (see Plack and specific
111 servers above for all available options):
112
113 $ plackup bin/app.pl
114 $ plackup -E deployment -s Starman --workers=10 -p 5001 -a bin/app.pl
115
116 As you can see, the scaffolded Perl script for your app can be used as
117 a PSGI startup file.
118
119 Enabling content compression
120
121 Content compression (gzip, deflate) can be easily enabled via a Plack
122 middleware (see Plack#Plack::Middleware): Plack::Middleware::Deflater.
123 It's a middleware to encode the response body in gzip or deflate, based
124 on Accept-Encoding HTTP request header.
125
126 Enable it as you would enable any Plack middleware. First you need to
127 install Plack::Middleware::Deflater, then in the configuration file
128 (usually environments/development.yml), add these lines:
129
130 plack_middlewares:
131 -
132 - Plack::Middleware::Deflater
133 - ...
134
135 These lines tell Dancer to add Plack::Middleware::Deflater to the list
136 of middlewares to pass to Plack::Builder, when wrapping the Dancer app.
137 The syntax is :
138
139 • as key: the name of the Plack middleware to use
140
141 • as value: the options to pass it as a list. In our case, there is
142 no option to specify to Plack::Middleware::Deflater, so we use an
143 empty YAML list.
144
145 To test if content compression works, trace the HTTP request and
146 response before and after enabling this middleware. Among other things,
147 you should notice that the response is gzip or deflate encoded, and
148 contains a header "Content-Encoding" set to "gzip" or "deflate"
149
150 Hosting on DotCloud
151
152 The simplest way to achieve this is to push your main application
153 directory to dotcloud with your "bin/app.pl" file copied to (or
154 symlinked from) "app.psgi".
155
156 Beware that the dotcloud service enforces one environment only, named
157 "deployment". So instead of having "environments/development.yml" or
158 "environments/production.yml" you must have a file named
159 "environments/deployment.yml".
160
161 Also make sure that your "Makefile.PL" (or other dependency mechanism)
162 includes both Dancer and Plack::Request.
163
164 The default in-memory session handler won't work, and instead you
165 should switch to something persistent. Edit "config.yml" to change
166 "session: 'Simple'" to (for example) "session: 'YAML'".
167
168 In case you have issues with Template::Toolkit on Dotcloud
169
170 If you use the Template::Toolkit and its "INCLUDE" or "PROCESS"
171 directives, you might need to add the search path of your view files to
172 the config. This is probably going to be something like "INCLUDE_PATH:
173 '/home/dotcloud/current/views'" in "config.yml".
174
175 An alternative implementation is to use a variation of the above
176 Plack::Builder template:
177
178 use Plack::Builder;
179 use Dancer ':syntax';
180 use Dancer::Handler;
181 use lib 'lib';
182
183 my $app1 = sub {
184 setting appdir => '/home/dotcloud/current';
185 load_app "My::App";
186 Dancer::App->set_running_app("My::App");
187 my $env = shift;
188 Dancer::Handler->init_request_headers($env);
189 my $req = Dancer::Request->new(env => $env);
190 Dancer->dance($req);
191 };
192
193 builder {
194 mount "/app1" => $app1;
195 };
196
197 This also supports hosting multiple apps, but you probably also need to
198 specify the specific Environment configuration to use in your
199 application.
200
201 When mounting under a path on dotcloud, as in the above example, always
202 create links using the "uri_for()" method for Dancer routes, and a
203 "uri_base" variable for static content as shown in Dancer::Cookbook.
204 This means whatever base path your app is mounted under, links and form
205 submissions will continue to work.
206
207 Creating a service
208
209 You can turn your app into proper service running in background using
210 one of the following examples:
211
212 Using Ubic
213
214 Ubic is a polymorphic service manager. You can use it to start and stop
215 any services, automatically start them on reboots or daemon failures,
216 and implement custom status checks.
217
218 A basic PSGI service description (usually in
219 /etc/ubic/service/application):
220
221 use parent qw(Ubic::Service::Plack);
222
223 __PACKAGE__->new(
224 server => 'Starman',
225 app => '/path/to/your/application/app.pl',
226 port => 5000,
227 user => 'www-data',
228 );
229
230 Run "ubic start application" to start the service.
231
232 Using daemontools
233
234 daemontools is a collection of tools for managing UNIX services. You
235 can use it to easily start/restart/stop services.
236
237 A basic script to start an application: (in /service/application/run)
238
239 #!/bin/sh
240
241 # if your application is not installed in @INC path:
242 export PERL5LIB='/path/to/your/application/lib'
243
244 exec 2>&1 \
245 /usr/local/bin/plackup -s Starman -a /path/to/your/application/app.pl -p 5000
246
247 Running stand-alone behind a proxy / load balancer
248
249 Another option would be to run your app stand-alone as described above,
250 but then use a proxy or load balancer to accept incoming requests (on
251 the standard port 80, say) and feed them to your Dancer app.
252
253 This could be achieved using various software; examples would include:
254
255 Using Apache's mod_proxy
256
257 You could set up a VirtualHost for your web app, and proxy all requests
258 through to it:
259
260 <VirtualHost mywebapp.example.com:80>
261 ProxyPass / http://localhost:3000/
262 ProxyPassReverse / http://localhost:3000/
263 </VirtualHost>
264
265 Or, if you want your webapp to share an existing VirtualHost, you could
266 have it under a specified dir:
267
268 ProxyPass /mywebapp/ http://localhost:3000/
269 <Location /mywebapp/>
270 RequestHeader set Request-Base /mywebapp
271 </Location>
272
273 HTTP header "Request-Base" is taken into account by Dancer, only when
274 "behind_proxy" setting is set to true.
275
276 It is important for you to note that the Apache2 modules mod_headers,
277 mod_proxy and mod_proxy_http must be enabled.
278
279 a2enmod headers
280 a2enmod proxy
281 a2enmod proxy_http
282
283 Note that Apache does not pass protocol information when proxying, so
284 if needed then you will need to set it manually in your Apache config:
285
286 RequestHeader set X_FORWARDED_PROTO "https"
287
288 It is also important to set permissions for proxying for security
289 purposes, below is an example.
290
291 <Proxy *>
292 Order allow,deny
293 Allow from all
294 </Proxy>
295
296 Using perlbal
297
298 "Perlbal" is a single-threaded event-based server written in Perl
299 supporting HTTP load balancing, web serving, and a mix of the two,
300 available from <http://www.danga.com/perlbal/>
301
302 It processes hundreds of millions of requests a day just for
303 LiveJournal, Vox and TypePad and dozens of other "Web 2.0"
304 applications.
305
306 It can also provide a management interface to let you see various
307 information on requests handled etc.
308
309 It could easily be used to handle requests for your Dancer apps, too.
310
311 It can be easily installed from CPAN:
312
313 perl -MCPAN -e 'install Perlbal'
314
315 Once installed, you'll need to write a configuration file. See the
316 examples provided with perlbal, but you'll probably want something
317 like:
318
319 CREATE POOL my_dancers
320 POOL my_dancers ADD 10.0.0.10:3030
321 POOL my_dancers ADD 10.0.0.11:3030
322 POOL my_dancers ADD 10.0.0.12:3030
323 POOL my_dancers ADD 10.0.0.13:3030
324
325 CREATE SERVICE my_webapp
326 SET listen = 0.0.0.0:80
327 SET role = reverse_proxy
328 SET pool = my_dancers
329 SET persist_client = on
330 SET persist_backend = on
331 SET verify_backend = on
332 ENABLE my_webapp
333
334 Using balance
335
336 "balance" is a simple load-balancer from Inlab Software, available from
337 <http://www.inlab.de/balance.html>.
338
339 It could be used simply to hand requests to a standalone Dancer app.
340 You could even run several instances of your Dancer app, on the same
341 machine or on several machines, and use a machine running balance to
342 distribute the requests between them, for some serious heavy traffic
343 handling!
344
345 To listen on port 80, and send requests to a Dancer app on port 3000:
346
347 balance http localhost:3000
348
349 To listen on a specified IP only on port 80, and distribute requests
350 between multiple Dancer apps on multiple other machines:
351
352 balance -b 10.0.0.1 80 10.0.0.2:3000 10.0.0.3:3000 10.0.0.4:3000
353
354 Using Lighttpd
355
356 You can use Lighttp's mod_proxy:
357
358 $HTTP["url"] =~ "/application" {
359 proxy.server = (
360 "/" => (
361 "application" => ( "host" => "127.0.0.1", "port" => 3000 )
362 )
363 )
364 }
365
366 This configuration will proxy all request to the /application path to
367 the path / on localhost:3000.
368
369 Using Nginx
370
371 with Nginx:
372
373 upstream backendurl {
374 server unix:THE_PATH_OF_YOUR_PLACKUP_SOCKET_HERE.sock;
375 }
376
377 server {
378 listen 80;
379 server_name YOUR_HOST_HERE;
380
381 access_log /var/log/YOUR_ACCESS_LOG_HERE.log;
382 error_log /var/log/YOUR_ERROR_LOG_HERE.log info;
383
384 root YOUR_ROOT_PROJECT/public;
385 location / {
386 try_files $uri @proxy;
387 access_log off;
388 expires max;
389 }
390
391 location @proxy {
392 proxy_set_header Host $http_host;
393 proxy_set_header X-Forwarded-Host $host;
394 proxy_set_header X-Real-IP $remote_addr;
395 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
396 proxy_set_header X-Forwarded-Proto $scheme;
397 proxy_pass http://backendurl;
398 }
399
400 }
401
402 You will need plackup to start a worker listening on a socket :
403
404 cd YOUR_PROJECT_PATH
405 sudo -u www plackup -E production -s Starman --workers=2 -l THE_PATH_OF_YOUR_PLACKUP_SOCKET_HERE.sock -a bin/app.pl
406
407 A good way to start this is to use "daemontools" and place this line
408 with all environments variables in the "run" file.
409
410 Using HAProxy
411
412 "HAProxy" is a reliable high-performance TCP/HTTP load balancer written
413 in C available from <http://haproxy.1wt.eu/>.
414
415 Suppose we want to run an application at "app.example.com:80" and would
416 to use two backends listen on hosts "app-be1.example.com:3000" and
417 "app-be2.example.com:3000".
418
419 Here is HAProxy configuration file (haproxy.conf):
420
421 global
422 nbproc 1
423 maxconn 4096
424 user nobody
425 group nobody
426 # haproxy logs will be collected by syslog
427 # syslog: unix socket path or tcp pair (ipaddress:port)
428 log /var/run/log local0
429 daemon
430 # enable compression (haproxy v1.5-dev13 and above required)
431 tune.comp.maxlevel 5
432
433 defaults
434 log global
435 option httpclose
436 option httplog
437 option dontlognull
438 option forwardfor
439 option abortonclose
440 mode http
441 balance roundrobin
442 retries 3
443 timeout connect 5s
444 timeout server 30s
445 timeout client 30s
446 timeout http-keep-alive 200m
447 # enable compression (haproxy v1.5-dev13 and above required)
448 compression algo gzip
449 compression type text/html application/javascript text/css application/x-javascript text/javascript
450
451 # application frontend (available at http://app.example.com)
452 frontend app.example.com
453 bind :80
454 # modify request headers
455 reqadd X-Forwarded-Proto:\ http
456 reqadd X-Forwarded-Port:\ 80
457 # modify response headers
458 rspdel ^Server:.*
459 rspdel ^X-Powered-By:.*
460 rspadd Server:\ Dethklok\ (Unix/0.2.3)
461 rate-limit sessions 1024
462 acl is-haproxy-stats path_beg /stats
463 # uncomment if you'd like to get haproxy usage statistics
464 # use_backend haproxy if is-haproxy-stats
465 default_backend dynamic
466
467 # haproxy statistics (available at http://app.example.com/stats)
468 backend haproxy
469 stats uri /stats
470 stats refresh 180s
471 stats realm app.example.com\ haproxy\ statistics
472 # change credentials
473 stats auth admin1:password1
474 stats auth admin2:password2
475 stats hide-version
476 stats show-legends
477
478 # application backends
479 backend dynamic
480 # change path_info to check and value of the Host header sent to application server
481 option httpchk HEAD / HTTP/1.1\r\nHost:\ app.example.com
482 server app1 app-be1.example.com:3000 check inter 30s
483 server app2 app-be2.example.com:3000 check inter 30s
484
485 We will need to start the workers on each backend of our application.
486 This can be done by starman utility:
487
488 # on app-be1.example.com
489 $ starman --workers=2 --listen :3000 /path/to/app.pl
490 # on app-be2.example.com
491 $ starman --workers=2 --listen :3000 /path/to/app.pl
492
493 Then start the haproxy itself:
494
495 # check the configuration..
496 $ sudo haproxy -c -f haproxy.conf
497 # now really start it..
498 $ sudo haproxy -f haproxy.conf
499
500 Plackup Chef Cookbook
501
502 A psgi chef cookbook supporting Dancer (as well as Catalyst) written by
503 Alexey Melezhik is available at
504 <http://community.opscode.com/cookbooks/psgi>.
505
506 Running from Apache
507 You can run your Dancer app from Apache using the following examples:
508
509 Running from Apache with Plack
510
511 You can run your app from Apache using PSGI (Plack), with a config like
512 the following:
513
514 <VirtualHost myapp.example.com>
515 ServerName www.myapp.example.com
516 ServerAlias myapp.example.com
517 DocumentRoot /websites/myapp.example.com
518
519 <Directory /websites/myapp.example.com>
520 AllowOverride None
521 Order allow,deny
522 Allow from all
523 </Directory>
524
525 <Location />
526 SetHandler perl-script
527 PerlResponseHandler Plack::Handler::Apache2
528 PerlSetVar psgi_app /websites/myapp.example.com/app.pl
529 </Location>
530
531 ErrorLog /websites/myapp.example.com/logs/error_log
532 CustomLog /websites/myapp.example.com/logs/access_log common
533 </VirtualHost>
534
535 To set the environment you want to use for your application (production
536 or development), you can set it this way:
537
538 <VirtualHost>
539 ...
540 SetEnv DANCER_ENVIRONMENT "production"
541 ...
542 </VirtualHost>
543
544 NOTE: Only a single Dancer application can be deployed using the
545 "Plack::Handler::Apache2" method. Multiple Dancer applications will not
546 work properly (The routes will be mixed-up between the applications).
547
548 It's recommended to start each app with "plackup" using your favorite
549 server (Starman, for example) and then put a web server (Apache, Nginx,
550 Perlbal, etc.) as a frontend server for both apps using reverse proxy
551 (HTTP based, no fastcgi).
552
553 Running from Apache under appdir
554
555 If you want to deploy multiple applications under the same VirtualHost,
556 using one application per directory for example, you can do the
557 following.
558
559 This example uses the FastCGI dispatcher that comes with Dancer, but
560 you should be able to adapt this to use any other way of deployment
561 described in this guide. The only purpose of this example is to show
562 how to deploy multiple applications under the same base
563 directory/virtualhost.
564
565 <VirtualHost *:80>
566 ServerName localhost
567 DocumentRoot "/path/to/rootdir"
568 RewriteEngine On
569 RewriteCond %{REQUEST_FILENAME} !-f
570
571 <Directory "/path/to/rootdir">
572 AllowOverride None
573 Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
574 Order allow,deny
575 Allow from all
576 AddHandler fastcgi-script .fcgi
577 </Directory>
578
579 RewriteRule /App1(.*)$ /App1/public/dispatch.fcgi$1 [QSA,L]
580 RewriteRule /App2(.*)$ /App2/public/dispatch.fcgi$1 [QSA,L]
581 ...
582 RewriteRule /AppN(.*)$ /AppN/public/dispatch.fcgi$1 [QSA,L]
583 </VirtualHost>
584
585 Of course, if your Apache configuration allows that, you can put the
586 RewriteRules in a .htaccess file directly within the application's
587 directory, which lets you add a new application without changing the
588 Apache configuration.
589
590 Running on lighttpd (CGI)
591 To run as a CGI app on lighttpd, just create a soft link to the
592 dispatch.cgi script (created when you run dancer -a MyApp) inside your
593 system's cgi-bin folder. Make sure mod_cgi is enabled.
594
595 ln -s /path/to/MyApp/public/dispatch.cgi /usr/lib/cgi-bin/mycoolapp.cgi
596
597 Running on lighttpd (FastCGI)
598 Make sure mod_fcgi is enabled. You also must have FCGI installed.
599
600 This example configuration uses TCP/IP:
601
602 $HTTP["url"] == "^/app" {
603 fastcgi.server += (
604 "/app" => (
605 "" => (
606 "host" => "127.0.0.1",
607 "port" => "5000",
608 "check-local" => "disable",
609 )
610 )
611 )
612 }
613
614 Launch your application:
615
616 plackup -s FCGI --port 5000 bin/app.pl
617
618 This example configuration uses a socket:
619
620 $HTTP["url"] =~ "^/app" {
621 fastcgi.server += (
622 "/app" => (
623 "" => (
624 "socket" => "/tmp/fcgi.sock",
625 "check-local" => "disable",
626 )
627 )
628 )
629 }
630
631 Launch your application:
632
633 plackup -s FCGI --listen /tmp/fcgi.sock bin/app.pl
634
636 Dancer Core Developers
637
639 This software is copyright (c) 2010 by Alexis Sukrieh.
640
641 This is free software; you can redistribute it and/or modify it under
642 the same terms as the Perl 5 programming language system itself.
643
644
645
646perl v5.32.1 2021-01-27 Dancer::Deployment(3)