1Dancer::Deployment(3) User Contributed Perl DocumentationDancer::Deployment(3)
2
3
4

NAME

6       Dancer::Deployment - common ways to put your Dancer app into use
7

VERSION

9       version 1.3513
10

DESCRIPTION

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

AUTHOR

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.0                      2020-07-28             Dancer::Deployment(3)
Impressum