1Dancer2::Manual::DeployUmseenrt(C3o)ntributed Perl DocumDeanntcaetri2o:n:Manual::Deployment(3)
2
3
4
6 Dancer2::Manual::Deployment - common ways to put your Dancer app into
7 use
8
10 version 0.301004
11
13 Dancer has been designed to be flexible, and this flexibility extends
14 to your choices when deploying your Dancer app.
15
16 Running stand-alone
17 To start your application, just run plackup:
18
19 $ plackup bin/app.psgi
20 HTTP::Server::PSGI: Accepting connections at http://0:5000/
21
22 Point your browser at it, and away you go!
23
24 This option can be useful for small personal web apps or internal apps,
25 but if you want to make your app available to the world, it probably
26 won't suit you.
27
28 Auto Reloading the Application
29
30 While developing your application, it is often handy to have the server
31 automatically reload your application when changes are made. There are
32 two recommended ways of handling this with Dancer: using " plackup -r "
33 and Plack::Loader::Shotgun. Both have their advantages and
34 disadvantages (which will be explained below).
35
36 Regardless of the method you use, it is not recommended that you
37 automatically reload your applications in a production environment, for
38 reasons of performance, deployment best practices, etc.
39
40 For Dancer 1 programmers that used the " auto_reload " option, please
41 use one of these alternatives instead:
42
43 Auto reloading with " plackup -r "
44
45 Plack's built-in reloader will reload your application anytime a file
46 in your application's directory (usually, /bin ) changes. You will
47 likely want to monitor your lib/ directory too, using the " -R "
48 option:
49
50 $ plackup -r -R lib bin/app.psgi
51
52 There is a performance hit associated with this, as Plack will spin off
53 a separate process that monitors files in the application and other
54 specified directories. If the timestamp of any files in a watched
55 directory changes, the application is recompiled and reloaded.
56
57 See the plackup docs for more information on the " -r " and " -R "
58 options.
59
60 Auto reloading with plackup and Shotgun
61
62 There may be circumstances where Plack's built-in reloader won't work
63 for you, be it for the way it looks for changes, or because there are
64 many directories you need to monitor, or you want to reload the
65 application any time one of the modules in Perl's lib/ path changes.
66 Plack::Loader::Shotgun makes this easy by recompiling the application
67 on every request.
68
69 To use Shotgun, specify it using the loader argument to " plackup (-L)
70 ":
71
72 $ plackup -L Shotgun bin/app.psgi
73
74 The Shotgun, while effective, can quickly cause you performance issues,
75 even during the development phase of your application. As the number of
76 plugins you use in your application grows, as the number of static
77 resources (images, etc.) grows, the more requests your server process
78 needs to handle. Since each request recompiles the application, even
79 simple page refreshes can get unbearably slow over time. Use with
80 caution.
81
82 You can bypass Shotgun's auto-reloading of specific modules with the "
83 -M " switch:
84
85 $ plackup -L Shotgun -M<MyApp::Foo> -M<MyApp::Bar> bin/app.psgi
86
87 On Windows, Shotgun loader is known to cause huge memory leaks in a
88 fork-emulation layer. If you are aware of this and still want to run
89 the loader, please use the following command:
90
91 > set PLACK_SHOTGUN_MEMORY_LEAK=1 && plackup -L Shotgun bin\app.psgi
92 HTTP::Server::PSGI: Accepting connections at http://0:5000/
93
94 Please note: if you are using Dancer 2's asynchronous capabilities,
95 using Shotgun will kill Twiggy. If you need async processing, consider
96 an alternative to Shotgun.
97
98 Running under Apache
99 You can run your Dancer app from Apache using the following examples:
100
101 As a CGI script
102
103 In its simplest form, your Dancer app can be run as a simple CGI script
104 out-of-the-box. You will need to enable the Apache mod_cgi or mod_cgid
105 modules ("a2enmod cgi" or "a2enmod cgid" on Debian-based systems) and
106 mod_rewrite ("a2enmod rewrite"). The Perl module Plack::Runner is
107 required.
108
109 The following is an example apache configuration. Depending on your
110 Apache configuration layout, this should be placed in "httpd.conf" or
111 "sites-available/*site*". The configuration options can also be placed
112 in ".htaccess" files if you prefer.
113
114 <VirtualHost *:80>
115 ServerName www.example.com
116
117 # /srv/www.example.com is the root of your
118 # dancer application
119 DocumentRoot /srv/www.example.com/public
120
121 ServerAdmin you@example.com
122
123 <Directory "/srv/www.example.com/public">
124 AllowOverride None
125 Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
126 AddHandler cgi-script .cgi
127 # Apache 2.2
128 Order allow,deny
129 Allow from all
130 # Apache 2.4
131 Require all granted
132 </Directory>
133
134 RewriteEngine On
135 RewriteCond %{REQUEST_FILENAME} !-f
136 RewriteRule ^(.*)$ /dispatch.cgi$1 [QSA,L]
137
138 ErrorLog /var/log/apache2/www.example.com-error.log
139 CustomLog /var/log/apache2/www.example.com-access_log common
140 </VirtualHost>
141
142 Now you can access your dancer application URLs as if you were using
143 the embedded web server.
144
145 http://www.example.com/
146
147 This option is a no-brainer, easy to setup and low maintenance, but
148 serves requests slower than all other options, as each time a request
149 is made to your server, Apache will start your application. This might
150 be suitable for a small, occasionally-used sites, as the application is
151 not using resources when it is not being accessed. For anything more,
152 you probably want to use FastCGI instead (see next section).
153
154 To list all currently loaded modules, type "apachectl -M" ("apache2ctl
155 -M" on Debian/Ubuntu).
156
157 As a FastCGI script
158
159 This has all the easy-to-setup and low-maintenance advantages of CGI,
160 but is much faster for each request, as it keeps a copy of the
161 application running all the time.
162
163 You will still need to enable "mod_rewrite", but will need to use a
164 FastCGI module instead of a CGI module. There are 3 available:
165 mod_fcgid <http://httpd.apache.org/mod_fcgid/>, mod_fastcgi
166 <http://www.fastcgi.com/> and mod_proxy_fcgi
167 <https://httpd.apache.org/docs/trunk/mod/mod_proxy_fcgi.html>. For
168 this example, we will use mod_fastcgi ("a2enmod fastcgi" in Debian).
169
170 The CGI configuration above now changes as follows (differences
171 highlighted with XXX):
172
173 <VirtualHost *:80>
174 ServerName www.example.com
175
176 # /srv/www.example.com is the root of your
177 # dancer application
178 DocumentRoot /srv/www.example.com/public
179
180 ServerAdmin you@example.com
181
182 # XXX Start a FastCGI server to run in the background
183 FastCgiServer /srv/www.example.com/public/dispatch.fcgi
184
185 <Directory "/srv/www.example.com/public">
186 AllowOverride None
187 Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
188 # XXX Use FastCGI handler instead of CGI
189 AddHandler fastcgi-script .fcgi
190 # Apache 2.2
191 Order allow,deny
192 Allow from all
193 # Apache 2.4
194 Require all granted
195 </Directory>
196
197 RewriteEngine On
198 RewriteCond %{REQUEST_FILENAME} !-f
199 # Run FastCGI dispatcher instead of CGI dispatcher
200 RewriteRule ^(.*)$ /dispatch.fcgi$1 [QSA,L]
201
202 ErrorLog /var/log/apache2/www.example.com-error.log
203 CustomLog /var/log/apache2/www.example.com-access_log common
204 </VirtualHost>
205
206 This is the easiest way to get a production server up and running, as
207 there is no need to worry about daemonizing your application. Apache
208 manages all that for you.
209
210 Reloading your application
211
212 You can use "apache2ctl restart" or "apache2ctl graceful" to reload
213 your application. The latter will be more friendly to your users in a
214 production environment. If your application loads relatively quickly,
215 then it should go unnoticed.
216
217 Configuration
218
219 See <http://www.fastcgi.com/mod_fastcgi/docs/mod_fastcgi.html> for
220 FastCGI configuration options. An example configuration:
221
222 FastCgiServer /srv/www.example.com/public/dispatch.fcgi -processes 5 -initial-env DANCER_ENVIRONMENT="production"
223
224 With Plack
225
226 You can run your app from Apache using PSGI (Plack), with a config like
227 the following:
228
229 <VirtualHost myapp.example.com>
230 ServerName www.myapp.example.com
231 ServerAlias myapp.example.com
232 DocumentRoot /websites/myapp.example.com
233
234 <Directory /home/myapp/myapp>
235 AllowOverride None
236 Order allow,deny
237 Allow from all
238 </Directory>
239
240 <Location />
241 SetHandler perl-script
242 PerlResponseHandler Plack::Handler::Apache2
243 PerlSetVar psgi_app /websites/myapp.example.com/app.psgi
244 </Location>
245
246 ErrorLog /websites/myapp.example.com/logs/error_log
247 CustomLog /websites/myapp.example.com/logs/access_log common
248 </VirtualHost>
249
250 To set the environment you want to use for your application (production
251 or development), you can set it this way:
252
253 <VirtualHost>
254 ...
255 SetEnv DANCER_ENVIRONMENT "production"
256 ...
257 </VirtualHost>
258
259 Running multiple applications under the same virtualhost
260
261 If you want to deploy multiple applications under the same
262 "VirtualHost" (using one application per directory, for example) you
263 can use the following example Apache configuration.
264
265 This example uses the FastCGI dispatcher that comes with Dancer, but
266 you should be able to adapt this to use any other way of deployment
267 described in this guide. The only purpose of this example is to show
268 how to deploy multiple applications under the same base
269 directory/virtualhost.
270
271 <VirtualHost *:80>
272 ServerName localhost
273 DocumentRoot "/path/to/rootdir"
274 RewriteEngine On
275 RewriteCond %{REQUEST_FILENAME} !-f
276
277 <Directory "/path/to/rootdir">
278 AllowOverride None
279 Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
280 Order allow,deny
281 Allow from all
282 AddHandler fastcgi-script .fcgi
283 </Directory>
284
285 RewriteRule /App1(.*)$ /App1/public/dispatch.fcgi$1 [QSA,L]
286 RewriteRule /App2(.*)$ /App2/public/dispatch.fcgi$1 [QSA,L]
287 ...
288 RewriteRule /AppN(.*)$ /AppN/public/dispatch.fcgi$1 [QSA,L]
289 </VirtualHost>
290
291 Of course, if your Apache configuration allows that, you can put the
292 RewriteRules in a .htaccess file directly within the application's
293 directory, which lets you add a new application without changing the
294 Apache configuration.
295
296 Running on PSGI-based Perl webservers
297 A number of Perl web servers supporting PSGI are available on cpan:
298
299 Starman
300 "Starman" is a high performance web server, with support for
301 preforking, signals, multiple interfaces, graceful restarts and
302 dynamic worker pool configuration.
303
304 Twiggy
305 "Twiggy" is an "AnyEvent" web server, it's light and fast.
306
307 Corona
308 "Corona" is a "Coro" based web server.
309
310 Similar to running standalone, use plackup to start your application
311 (see Plack and specific servers above for all available options):
312
313 $ plackup bin/app.psgi
314 $ plackup -E deployment -s Starman --workers=10 -p 5001 -a bin/app.psgi
315
316 As you can see, the scaffolded Perl script for your app can be used as
317 a PSGI startup file.
318
319 Enabling content compression
320
321 Content compression (gzip, deflate) can be easily enabled via a Plack
322 middleware (see "Plack::Middleware" in Plack):
323 Plack::Middleware::Deflater. It's a middleware to encode the response
324 body in gzip or deflate, based on the "Accept-Encoding" HTTP request
325 header.
326
327 Enable it as you would enable any Plack middleware. First you need to
328 install Plack::Middleware::Deflater, then in the handler (usually
329 app.psgi) edit it to use Plack::Builder, as described above:
330
331 use Dancer2;
332 use MyWebApp;
333 use Plack::Builder;
334
335 builder {
336 enable 'Deflater';
337 dance;
338 };
339
340 To test if content compression works, trace the HTTP request and
341 response before and after enabling this middleware. Among other things,
342 you should notice that the response is gzip or deflate encoded, and
343 contains a header "Content-Encoding" set to "gzip" or "deflate".
344
345 Creating a service
346
347 You can turn your app into proper service running in background using
348 one of the following examples:
349
350 Using Ubic
351
352 Ubic is an extensible perlish service manager. You can use it to start
353 and stop any services, automatically start them on reboots or daemon
354 failures, and implement custom status checks.
355
356 A basic PSGI service description (usually in
357 "/etc/ubic/service/application"):
358
359 use parent qw(Ubic::Service::Plack);
360
361 # if your application is not installed in @INC path:
362 sub start {
363 my $self = shift;
364 $ENV{PERL5LIB} = '/path/to/your/application/lib';
365 $self->SUPER::start(@_);
366 }
367
368 __PACKAGE__->new(
369 server => 'Starman',
370 app => '/path/to/your/application/app.psgi',
371 port => 5000,
372 user => 'www-data',
373 );
374
375 Run "ubic start application" to start the service.
376
377 Using daemontools
378
379 daemontools is a collection of tools for managing UNIX services. You
380 can use it to easily start/restart/stop services.
381
382 A basic script to start an application: (in "/service/application/run")
383
384 #!/bin/sh
385
386 # if your application is not installed in @INC path:
387 export PERL5LIB='/path/to/your/application/lib'
388
389 exec 2>&1 \
390 /usr/local/bin/plackup -s Starman -a /path/to/your/application/app.psgi -p 5000
391
392 Running stand-alone behind a proxy / load balancer
393 Another option would be to run your app stand-alone as described above,
394 but then use a proxy or load balancer to accept incoming requests (on
395 the standard port 80, say) and feed them to your Dancer app. Also, in
396 this case you might want to look at the "behind_proxy" configuration
397 option, to make sure that all the URLs are constructed properly.
398
399 behind_proxy: 1
400
401 This setup can be achieved using various software; examples would
402 include:
403
404 Using Apache's mod_proxy
405
406 You could set up a "VirtualHost" for your web app, and proxy all
407 requests through to it:
408
409 <VirtualHost mywebapp.example.com:80>
410 ProxyPass / http://localhost:3000/
411 ProxyPassReverse / http://localhost:3000/
412 </VirtualHost>
413
414 Or, if you want your webapp to share an existing VirtualHost, you could
415 have it under a specified dir:
416
417 ProxyPass /mywebapp/ http://localhost:3000/
418 ProxyPassReverse /mywebapp/ http://localhost:3000/
419
420 It is important for you to note that the Apache2 modules "mod_proxy"
421 and "mod_proxy_http" must be enabled:
422
423 $ a2enmod proxy
424 $ a2enmod proxy_http
425
426 It is also important to set permissions for proxying for security
427 purposes, below is an example.
428
429 <Proxy *>
430 Order allow,deny
431 Allow from all
432 </Proxy>
433
434 Using perlbal
435
436 "Perlbal" is a single-threaded event-based server written in Perl
437 supporting HTTP load balancing, web serving, and a mix of the two,
438 available from <http://www.danga.com/perlbal/>
439
440 It processes hundreds of millions of requests a day just for
441 LiveJournal, Vox and TypePad and dozens of other "Web 2.0"
442 applications.
443
444 It can also provide a management interface to let you see various
445 information on requests handled etc.
446
447 It could easily be used to handle requests for your Dancer apps, too.
448
449 It can be easily installed from CPAN:
450
451 perl -MCPAN -e 'install Perlbal'
452
453 Once installed, you'll need to write a configuration file. See the
454 examples provided with perlbal, but you'll probably want something
455 like:
456
457 CREATE POOL my_dancers
458 POOL my_dancers ADD 10.0.0.10:3030
459 POOL my_dancers ADD 10.0.0.11:3030
460 POOL my_dancers ADD 10.0.0.12:3030
461 POOL my_dancers ADD 10.0.0.13:3030
462
463 CREATE SERVICE my_webapp
464 SET listen = 0.0.0.0:80
465 SET role = reverse_proxy
466 SET pool = my_dancers
467 SET persist_client = on
468 SET persist_backend = on
469 SET verify_backend = on
470 ENABLE my_webapp
471
472 Using balance
473
474 "balance" is a simple load-balancer from Inlab Software, available from
475 <http://www.inlab.de/balance.html>.
476
477 It could be used simply to hand requests to a standalone Dancer app.
478 You could even run several instances of your Dancer app, on the same
479 machine or on several machines, and use a machine running "balance" to
480 distribute the requests between them, for some serious heavy traffic
481 handling!
482
483 To listen on port 80, and send requests to a Dancer app on port 3000:
484
485 balance http localhost:3000
486
487 To listen on a specified IP only on port 80, and distribute requests
488 between multiple Dancer apps on multiple other machines:
489
490 balance -b 10.0.0.1 80 10.0.0.2:3000 10.0.0.3:3000 10.0.0.4:3000
491
492 Using Lighttpd
493
494 You can use Lighttpd's "mod_proxy":
495
496 $HTTP["url"] =~ "/application" {
497 proxy.server = (
498 "/" => (
499 "application" => ( "host" => "127.0.0.1", "port" => 3000 )
500 )
501 )
502 }
503
504 This configuration will proxy all request to the /application path to
505 the path / on localhost:3000.
506
507 Using Nginx
508
509 with Nginx:
510
511 upstream backendurl {
512 server unix:THE_PATH_OF_YOUR_PLACKUP_SOCKET_HERE.sock;
513 }
514
515 server {
516 listen 80;
517 server_name YOUR_HOST_HERE;
518
519 access_log /var/log/YOUR_ACCESS_LOG_HERE.log;
520 error_log /var/log/YOUR_ERROR_LOG_HERE.log info;
521
522 root YOUR_ROOT_PROJECT/public;
523 location / {
524 try_files $uri @proxy;
525 access_log off;
526 expires max;
527 }
528
529 location @proxy {
530 proxy_set_header Host $http_host;
531 proxy_set_header X-Forwarded-Host $host;
532 proxy_set_header X-Real-IP $remote_addr;
533 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
534 proxy_pass http://backendurl;
535 }
536
537 }
538
539 You will need plackup to start a worker listening on a socket :
540
541 cd YOUR_PROJECT_PATH
542 sudo -u www plackup -E production -s Starman --workers=2 -l THE_PATH_OF_YOUR_PLACKUP_SOCKET_HERE.sock -a bin/app.pl
543
544 A good way to start this is to use "daemontools" and place this line
545 with all environments variables in the "run" file.
546
547 Using HAProxy
548
549 "HAProxy" is a reliable high-performance TCP/HTTP load balancer written
550 in C available from <https://www.haproxy.org/>.
551
552 Suppose we want to run an application at "app.example.com:80" and would
553 to use two backends listen on hosts "app-be1.example.com:3000" and
554 "app-be2.example.com:3000".
555
556 Here is HAProxy configuration file (haproxy.conf):
557
558 global
559 nbproc 1
560 maxconn 4096
561 user nobody
562 group nobody
563 # haproxy logs will be collected by syslog
564 # syslog: unix socket path or tcp pair (ipaddress:port)
565 log /var/run/log local0
566 daemon
567 # enable compression (haproxy v1.5-dev13 and above required)
568 tune.comp.maxlevel 5
569
570 defaults
571 log global
572 option httpclose
573 option httplog
574 option dontlognull
575 option forwardfor
576 option abortonclose
577 mode http
578 balance roundrobin
579 retries 3
580 timeout connect 5s
581 timeout server 30s
582 timeout client 30s
583 timeout http-keep-alive 200m
584 # enable compression (haproxy v1.5-dev13 and above required)
585 compression algo gzip
586 compression type text/html application/javascript text/css application/x-javascript text/javascript
587
588 # application frontend (available at http://app.example.com)
589 frontend app.example.com
590 bind :80
591 # modify request headers
592 reqadd X-Forwarded-Proto:\ http
593 reqadd X-Forwarded-Port:\ 80
594 # modify response headers
595 rspdel ^Server:.*
596 rspdel ^X-Powered-By:.*
597 rspadd Server:\ Dethklok\ (Unix/0.2.3)
598 rate-limit sessions 1024
599 acl is-haproxy-stats path_beg /stats
600 # uncomment if you'd like to get haproxy usage statistics
601 # use_backend haproxy if is-haproxy-stats
602 default_backend dynamic
603
604 # haproxy statistics (available at http://app.example.com/stats)
605 backend haproxy
606 stats uri /stats
607 stats refresh 180s
608 stats realm app.example.com\ haproxy\ statistics
609 # change credentials
610 stats auth admin1:password1
611 stats auth admin2:password2
612 stats hide-version
613 stats show-legends
614
615 # application backends
616 backend dynamic
617 # change path_info to check and value of the Host header sent to application server
618 option httpchk HEAD / HTTP/1.1\r\nHost:\ app.example.com
619 server app1 app-be1.example.com:3000 check inter 30s
620 server app2 app-be2.example.com:3000 check inter 30s
621
622 We will need to start the workers on each backend of our application.
623 This can be done by starman utility:
624
625 # on app-be1.example.com
626 $ starman --workers=2 --listen :3000 /path/to/app.pl
627 # on app-be2.example.com
628 $ starman --workers=2 --listen :3000 /path/to/app.pl
629
630 Then start the haproxy itself:
631
632 # check the configuration..
633 $ sudo haproxy -c -f haproxy.conf
634 # now really start it..
635 $ sudo haproxy -f haproxy.conf
636
637 Running on lighttpd
638 Running on lighttpd (CGI)
639
640 To run as a CGI app on lighttpd, just create a soft link to the
641 "dispatch.cgi" script (created when you run "dancer -a MyApp") inside
642 your system's "cgi-bin" folder. Make sure "mod_cgi" is enabled.
643
644 ln -s /path/to/MyApp/public/dispatch.cgi /usr/lib/cgi-bin/mycoolapp.cgi
645
646 Running on lighttpd (FastCGI)
647
648 Make sure "mod_fcgi" is enabled. You also must have FCGI installed.
649
650 This example configuration uses TCP/IP:
651
652 $HTTP["url"] == "^/app" {
653 fastcgi.server += (
654 "/app" => (
655 "" => (
656 "host" => "127.0.0.1",
657 "port" => "5000",
658 "check-local" => "disable",
659 )
660 )
661 )
662 }
663
664 Launch your application:
665
666 plackup -s FCGI --port 5000 bin/app.psgi
667
668 This example configuration uses a socket:
669
670 $HTTP["url"] =~ "^/app" {
671 fastcgi.server += (
672 "/app" => (
673 "" => (
674 "socket" => "/tmp/fcgi.sock",
675 "check-local" => "disable",
676 )
677 )
678 )
679 }
680
681 Launch your application:
682
683 plackup -s FCGI --listen /tmp/fcgi.sock bin/app.psgi
684
685 Performance Improvements
686 The following modules can be used to speed up an app in Dancer2:
687
688 • CGI::Deurl::XS
689
690 • Class::XSAccessor
691
692 • Cpanel::JSON::XS
693
694 • Crypt::URandom
695
696 • HTTP::XSCookies
697
698 • HTTP::XSHeaders
699
700 • Math::Random::ISAAC::XS
701
702 • MooX::TypeTiny
703
704 • Type::Tiny::XS
705
706 • URL::Encode::XS
707
708 • YAML::XS
709
710 If you generated your application with "dancer2 gen", you can easily
711 install these with the following command:
712
713 cpanm --installdeps . --with-feature=accelerate
714
715 To build them, you will need access to a C compiler, and using these
716 modules will prevent you from fatpacking your application.
717
718 These modules are installed by default when building a Docker container
719 containing your application.
720
722 Dancer Core Developers
723
725 This software is copyright (c) 2021 by Alexis Sukrieh.
726
727 This is free software; you can redistribute it and/or modify it under
728 the same terms as the Perl 5 programming language system itself.
729
730
731
732perl v5.34.0 2022-01-21 Dancer2::Manual::Deployment(3)