Provided by: libdancer2-perl_0.400001+dfsg-1_all bug

NAME

       Dancer2::Manual::Deployment - common ways to put your Dancer app into use

VERSION

       version 0.400001

DESCRIPTION

       Dancer has been designed to be flexible, and this flexibility extends to your choices when
       deploying your Dancer app.

   Running stand-alone
       To start your application, just run plackup:

           $ plackup bin/app.psgi
           HTTP::Server::PSGI: Accepting connections at http://0:5000/

       Point your browser at it, and away you go!

       This option can be useful for small personal web apps or internal apps, but if you want to
       make your app available to the world, it probably won't suit you.

       Auto Reloading the Application

       While developing your application, it is often handy to have the server automatically
       reload your application when changes are made. There are two recommended ways of handling
       this with Dancer: using " plackup -r " and Plack::Loader::Shotgun. Both have their
       advantages and disadvantages (which will be explained below).

       Regardless of the method you use, it is  not  recommended that you automatically reload
       your applications in a production environment, for reasons of performance, deployment best
       practices, etc.

       For Dancer 1 programmers that used the " auto_reload " option, please use one of these
       alternatives instead:

       Auto reloading with " plackup -r "

       Plack's built-in reloader will reload your application anytime a file in your
       application's directory (usually,  /bin ) changes. You will likely want to monitor your
       lib/  directory too, using the " -R " option:

           $ plackup -r -R lib bin/app.psgi

       There is a performance hit associated with this, as Plack will spin off a separate process
       that monitors files in the application and other specified directories. If the timestamp
       of any files in a watched directory changes, the application is recompiled and reloaded.

       See the plackup docs for more information on the " -r " and " -R " options.

       Auto reloading with plackup and Shotgun

       There may be circumstances where Plack's built-in reloader won't work for you, be it for
       the way it looks for changes, or because there are many directories you need to monitor,
       or you want to reload the application any time one of the modules in Perl's  lib/  path
       changes.  Plack::Loader::Shotgun makes this easy by recompiling the application on every
       request.

       To use Shotgun, specify it using the loader argument to " plackup (-L) ":

           $ plackup -L Shotgun bin/app.psgi

       The Shotgun, while effective, can quickly cause you performance issues, even during the
       development phase of your application. As the number of plugins you use in your
       application grows, as the number of static resources (images, etc.) grows, the more
       requests your server process needs to handle. Since each request recompiles the
       application, even simple page refreshes can get unbearably slow over time. Use with
       caution.

       You can bypass Shotgun's auto-reloading of specific modules with the " -M " switch:

           $ plackup -L Shotgun -M<MyApp::Foo> -M<MyApp::Bar> bin/app.psgi

       On Windows, Shotgun loader is known to cause huge memory leaks in a fork-emulation layer.
       If you are aware of this and still want to run the loader, please use the following
       command:

           > set PLACK_SHOTGUN_MEMORY_LEAK=1 && plackup -L Shotgun bin\app.psgi
           HTTP::Server::PSGI: Accepting connections at http://0:5000/

       Please note:  if you are using Dancer 2's asynchronous capabilities, using Shotgun will
       kill Twiggy. If you need async processing, consider an alternative to Shotgun.

   Running under Apache
       You can run your Dancer app from Apache using the following examples:

       As a CGI script

       In its simplest form, your Dancer app can be run as a simple CGI script out-of-the-box.
       You will need to enable the Apache mod_cgi or mod_cgid modules ("a2enmod cgi" or "a2enmod
       cgid" on Debian-based systems) and mod_rewrite ("a2enmod rewrite"). The Perl module
       Plack::Runner is required.

       The following is an example apache configuration. Depending on your Apache configuration
       layout, this should be placed in "httpd.conf" or "sites-available/*site*". The
       configuration options can also be placed in ".htaccess" files if you prefer.

           <VirtualHost *:80>
               ServerName www.example.com

               # /srv/www.example.com is the root of your
               # dancer application
               DocumentRoot /srv/www.example.com/public

               ServerAdmin you@example.com

               <Directory "/srv/www.example.com/public">
                   AllowOverride None
                   Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
                   AddHandler cgi-script .cgi
                   # Apache 2.2
                   Order allow,deny
                   Allow from all
                   # Apache 2.4
                   Require all granted
               </Directory>

               RewriteEngine On
               RewriteCond %{REQUEST_FILENAME} !-f
               RewriteRule ^(.*)$ /dispatch.cgi$1 [QSA,L]

               ErrorLog  /var/log/apache2/www.example.com-error.log
               CustomLog /var/log/apache2/www.example.com-access_log common
           </VirtualHost>

       Now you can access your dancer application URLs as if you were using the embedded web
       server.

           http://www.example.com/

       This option is a no-brainer, easy to setup and low maintenance, but serves requests slower
       than all other options, as each time a request is made to your server, Apache will start
       your application. This might be suitable for a small, occasionally-used sites, as the
       application is not using resources when it is not being accessed. For anything more, you
       probably want to use FastCGI instead (see next section).

       To list all currently loaded modules, type "apachectl -M" ("apache2ctl -M" on
       Debian/Ubuntu).

       As a FastCGI script

       This has all the easy-to-setup and low-maintenance advantages of CGI, but is much faster
       for each request, as it keeps a copy of the application running all the time.

       You will still need to enable "mod_rewrite", but will need to use a FastCGI module instead
       of a CGI module. There are 3 available: mod_fcgid <http://httpd.apache.org/mod_fcgid/>,
       mod_fastcgi <http://www.fastcgi.com/> and mod_proxy_fcgi
       <https://httpd.apache.org/docs/trunk/mod/mod_proxy_fcgi.html>.  For this example, we will
       use mod_fastcgi ("a2enmod fastcgi" in Debian).

       The CGI configuration above now changes as follows (differences highlighted with XXX):

           <VirtualHost *:80>
               ServerName www.example.com

               # /srv/www.example.com is the root of your
               # dancer application
               DocumentRoot /srv/www.example.com/public

               ServerAdmin you@example.com

               # XXX Start a FastCGI server to run in the background
               FastCgiServer /srv/www.example.com/public/dispatch.fcgi

               <Directory "/srv/www.example.com/public">
                   AllowOverride None
                   Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
                   # XXX Use FastCGI handler instead of CGI
                   AddHandler fastcgi-script .fcgi
                   # Apache 2.2
                   Order allow,deny
                   Allow from all
                   # Apache 2.4
                   Require all granted
               </Directory>

               RewriteEngine On
               RewriteCond %{REQUEST_FILENAME} !-f
               # Run FastCGI dispatcher instead of CGI dispatcher
               RewriteRule ^(.*)$ /dispatch.fcgi$1 [QSA,L]

               ErrorLog  /var/log/apache2/www.example.com-error.log
               CustomLog /var/log/apache2/www.example.com-access_log common
           </VirtualHost>

       This is the easiest way to get a production server up and running, as there is no need to
       worry about daemonizing your application. Apache manages all that for you.

       Reloading your application

       You can use "apache2ctl restart" or "apache2ctl graceful" to reload your application. The
       latter will be more friendly to your users in a production environment. If your
       application loads relatively quickly, then it should go unnoticed.

       Configuration

       See <http://www.fastcgi.com/mod_fastcgi/docs/mod_fastcgi.html> for FastCGI configuration
       options. An example configuration:

          FastCgiServer /srv/www.example.com/public/dispatch.fcgi -processes 5 -initial-env DANCER_ENVIRONMENT="production"

       With Plack

       You can run your app from Apache using PSGI (Plack), with a config like the following:

           <VirtualHost myapp.example.com>
               ServerName www.myapp.example.com
               ServerAlias myapp.example.com
               DocumentRoot /websites/myapp.example.com

               <Directory /home/myapp/myapp>
                   AllowOverride None
                   Order allow,deny
                   Allow from all
               </Directory>

               <Location />
                   SetHandler perl-script
                   PerlResponseHandler Plack::Handler::Apache2
                   PerlSetVar psgi_app /websites/myapp.example.com/app.psgi
               </Location>

               ErrorLog  /websites/myapp.example.com/logs/error_log
               CustomLog /websites/myapp.example.com/logs/access_log common
           </VirtualHost>

       To set the environment you want to use for your application (production or development),
       you can set it this way:

           <VirtualHost>
               ...
               SetEnv DANCER_ENVIRONMENT "production"
               ...
           </VirtualHost>

       Running multiple applications under the same virtualhost

       If you want to deploy multiple applications under the same "VirtualHost" (using one
       application per directory, for example) you can use the following example Apache
       configuration.

       This example uses the FastCGI dispatcher that comes with Dancer, but you should be able to
       adapt this to use any other way of deployment described in this guide. The only purpose of
       this example is to show how to deploy multiple applications under the same base
       directory/virtualhost.

           <VirtualHost *:80>
               ServerName localhost
               DocumentRoot "/path/to/rootdir"
               RewriteEngine On
               RewriteCond %{REQUEST_FILENAME} !-f

               <Directory "/path/to/rootdir">
                   AllowOverride None
                   Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
                   Order allow,deny
                   Allow from all
                   AddHandler fastcgi-script .fcgi
               </Directory>

               RewriteRule /App1(.*)$ /App1/public/dispatch.fcgi$1 [QSA,L]
               RewriteRule /App2(.*)$ /App2/public/dispatch.fcgi$1 [QSA,L]
               ...
               RewriteRule /AppN(.*)$ /AppN/public/dispatch.fcgi$1 [QSA,L]
           </VirtualHost>

       Of course, if your Apache configuration allows that, you can put the RewriteRules in a
       .htaccess file directly within the application's directory, which lets you add a new
       application without changing the Apache configuration.

   Running on PSGI-based Perl webservers
       A number of Perl web servers supporting PSGI are available on cpan:

       Starman
           "Starman" is a high performance web server, with support for preforking, signals,
           multiple interfaces, graceful restarts and dynamic worker pool configuration.

       Twiggy
           "Twiggy" is an "AnyEvent" web server, it's light and fast.

       Corona
           "Corona" is a "Coro" based web server.

       Similar to running standalone, use plackup to start your application (see Plack and
       specific servers above for all available options):

           $ plackup bin/app.psgi
           $ plackup -E deployment -s Starman --workers=10 -p 5001 -a bin/app.psgi

       As you can see, the scaffolded Perl script for your app can be used as a PSGI startup
       file.

       Enabling content compression

       Content compression (gzip, deflate) can be easily enabled via a Plack middleware (see
       "Plack::Middleware" in Plack): Plack::Middleware::Deflater.  It's a middleware to encode
       the response body in gzip or deflate, based on the "Accept-Encoding" HTTP request header.

       Enable it as you would enable any Plack middleware. First you need to install
       Plack::Middleware::Deflater, then in the handler (usually app.psgi) edit it to use
       Plack::Builder, as described above:

           use Dancer2;
           use MyWebApp;
           use Plack::Builder;

           builder {
               enable 'Deflater';
               dance;
           };

       To test if content compression works, trace the HTTP request and response before and after
       enabling this middleware. Among other things, you should notice that the response is gzip
       or deflate encoded, and contains a header "Content-Encoding" set to "gzip" or "deflate".

       Creating a service

       You can turn your app into proper service running in background using one of the following
       examples:

       Using Ubic

       Ubic is an extensible perlish service manager. You can use it to start and stop any
       services, automatically start them on reboots or daemon failures, and implement custom
       status checks.

       A basic PSGI service description (usually in "/etc/ubic/service/application"):

           use parent qw(Ubic::Service::Plack);

           # if your application is not installed in @INC path:
           sub start {
               my $self = shift;
               $ENV{PERL5LIB} = '/path/to/your/application/lib';
               $self->SUPER::start(@_);
           }

           __PACKAGE__->new(
               server => 'Starman',
               app => '/path/to/your/application/app.psgi',
               port => 5000,
               user => 'www-data',
           );

       Run "ubic start application" to start the service.

       Using daemontools

       daemontools is a collection of tools for managing UNIX services. You can use it to easily
       start/restart/stop services.

       A basic script to start an application: (in "/service/application/run")

           #!/bin/sh

           # if your application is not installed in @INC path:
           export PERL5LIB='/path/to/your/application/lib'

           exec 2>&1 \
           /usr/local/bin/plackup -s Starman -a /path/to/your/application/app.psgi -p 5000

   Running stand-alone behind a proxy / load balancer
       Another option would be to run your app stand-alone as described above, but then use a
       proxy or load balancer to accept incoming requests (on the standard port 80, say) and feed
       them to your Dancer app. Also, in this case you might want to look at the "behind_proxy"
       configuration option, to make sure that all the URLs are constructed properly.

           behind_proxy: 1

       This setup can be achieved using various software; examples would include:

       Using Apache's mod_proxy

       You could set up a "VirtualHost" for your web app, and proxy all requests through to it:

           <VirtualHost mywebapp.example.com:80>
           ProxyPass / http://localhost:3000/
           ProxyPassReverse / http://localhost:3000/
           </VirtualHost>

       Or, if you want your webapp to share an existing VirtualHost, you could have it under a
       specified dir:

           ProxyPass /mywebapp/ http://localhost:3000/
           ProxyPassReverse /mywebapp/ http://localhost:3000/

       It is important for you to note that the Apache2 modules "mod_proxy" and "mod_proxy_http"
       must be enabled:

           $ a2enmod proxy
           $ a2enmod proxy_http

       It is also important to set permissions for proxying for security purposes, below is an
       example.

           <Proxy *>
             Order allow,deny
             Allow from all
           </Proxy>

       Using perlbal

       "Perlbal" is a single-threaded event-based server written in Perl supporting HTTP load
       balancing, web serving, and a mix of the two, available from
       <http://www.danga.com/perlbal/>

       It processes hundreds of millions of requests a day just for LiveJournal, Vox and TypePad
       and dozens of other "Web 2.0" applications.

       It can also provide a management interface to let you see various information on requests
       handled etc.

       It could easily be used to handle requests for your Dancer apps, too.

       It can be easily installed from CPAN:

           perl -MCPAN -e 'install Perlbal'

       Once installed, you'll need to write a configuration file.  See the examples provided with
       perlbal, but you'll probably want something like:

           CREATE POOL my_dancers
           POOL my_dancers ADD 10.0.0.10:3030
           POOL my_dancers ADD 10.0.0.11:3030
           POOL my_dancers ADD 10.0.0.12:3030
           POOL my_dancers ADD 10.0.0.13:3030

           CREATE SERVICE my_webapp
           SET listen          = 0.0.0.0:80
           SET role            = reverse_proxy
           SET pool            = my_dancers
           SET persist_client  = on
           SET persist_backend = on
           SET verify_backend  = on
           ENABLE my_webapp

       Using balance

       "balance" is a simple load-balancer from Inlab Software, available from
       <http://www.inlab.de/balance.html>.

       It could be used simply to hand requests to a standalone Dancer app. You could even run
       several instances of your Dancer app, on the same machine or on several machines, and use
       a machine running "balance" to distribute the requests between them, for some serious
       heavy traffic handling!

       To listen on port 80, and send requests to a Dancer app on port 3000:

           balance http localhost:3000

       To listen on a specified IP only on port 80, and distribute requests between multiple
       Dancer apps on multiple other machines:

           balance -b 10.0.0.1 80 10.0.0.2:3000 10.0.0.3:3000 10.0.0.4:3000

       Using Lighttpd

       You can use Lighttpd's "mod_proxy":

           $HTTP["url"] =~ "/application" {
               proxy.server = (
                   "/" => (
                       "application" => ( "host" => "127.0.0.1", "port" => 3000 )
                   )
               )
           }

       This configuration will proxy all request to the /application path to the path / on
       localhost:3000.

       Using Nginx

       with Nginx:

           upstream backendurl {
               server unix:THE_PATH_OF_YOUR_PLACKUP_SOCKET_HERE.sock;
           }

           server {
             listen       80;
             server_name YOUR_HOST_HERE;

             access_log /var/log/YOUR_ACCESS_LOG_HERE.log;
             error_log  /var/log/YOUR_ERROR_LOG_HERE.log info;

             root YOUR_ROOT_PROJECT/public;
             location / {
               try_files $uri @proxy;
               access_log off;
               expires max;
             }

             location @proxy {
                   proxy_set_header Host $http_host;
                   proxy_set_header X-Forwarded-Host $host;
                   proxy_set_header X-Real-IP $remote_addr;
                   proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                   proxy_pass       http://backendurl;
             }

           }

       You will need plackup to start a worker listening on a socket :

           cd YOUR_PROJECT_PATH
           sudo -u www plackup -E production -s Starman --workers=2 -l THE_PATH_OF_YOUR_PLACKUP_SOCKET_HERE.sock -a bin/app.pl

       A good way to start this is to use "daemontools" and place this line with all environments
       variables in the "run" file.

       Using HAProxy

       "HAProxy" is a reliable high-performance TCP/HTTP load balancer written in C available
       from <https://www.haproxy.org/>.

       Suppose we want to run an application at "app.example.com:80" and would to use two
       backends listen on hosts "app-be1.example.com:3000" and "app-be2.example.com:3000".

       Here is HAProxy configuration file (haproxy.conf):

           global
               nbproc  1
               maxconn 4096
               user    nobody
               group   nobody
               # haproxy logs will be collected by syslog
               # syslog: unix socket path or tcp pair (ipaddress:port)
               log     /var/run/log local0
               daemon
               # enable compression (haproxy v1.5-dev13 and above required)
               tune.comp.maxlevel  5

           defaults
               log     global
               option  httpclose
               option  httplog
               option  dontlognull
               option  forwardfor
               option  abortonclose
               mode    http
               balance roundrobin
               retries 3
               timeout connect         5s
               timeout server          30s
               timeout client          30s
               timeout http-keep-alive 200m
               # enable compression (haproxy v1.5-dev13 and above required)
               compression algo gzip
               compression type text/html application/javascript text/css application/x-javascript text/javascript

           # application frontend (available at http://app.example.com)
           frontend app.example.com
               bind                  :80
               # modify request headers
               reqadd                X-Forwarded-Proto:\ http
               reqadd                X-Forwarded-Port:\ 80
               # modify response headers
               rspdel                ^Server:.*
               rspdel                ^X-Powered-By:.*
               rspadd                Server:\ Dethklok\ (Unix/0.2.3)
               rate-limit sessions   1024
               acl is-haproxy-stats  path_beg /stats
               # uncomment if you'd like to get haproxy usage statistics
               # use_backend haproxy   if is-haproxy-stats
               default_backend       dynamic

           # haproxy statistics (available at http://app.example.com/stats)
           backend haproxy
               stats uri             /stats
               stats refresh         180s
               stats realm           app.example.com\ haproxy\ statistics
               # change credentials
               stats auth            admin1:password1
               stats auth            admin2:password2
               stats hide-version
               stats show-legends

           # application backends
           backend dynamic
               # change path_info to check and value of the Host header sent to application server
               option httpchk HEAD / HTTP/1.1\r\nHost:\ app.example.com
               server app1 app-be1.example.com:3000 check inter 30s
               server app2 app-be2.example.com:3000 check inter 30s

       We will need to start the workers on each backend of our application. This can be done by
       starman utility:

           # on app-be1.example.com
           $ starman --workers=2 --listen :3000 /path/to/app.pl
           # on app-be2.example.com
           $ starman --workers=2 --listen :3000 /path/to/app.pl

       Then start the haproxy itself:

           # check the configuration..
           $ sudo haproxy -c -f haproxy.conf
           # now really start it..
           $ sudo haproxy -f haproxy.conf

   Running on lighttpd
       Running on lighttpd (CGI)

       To run as a CGI app on lighttpd, just create a soft link to the "dispatch.cgi" script
       (created when you run "dancer -a MyApp") inside your system's "cgi-bin" folder. Make sure
       "mod_cgi" is enabled.

           ln -s /path/to/MyApp/public/dispatch.cgi /usr/lib/cgi-bin/mycoolapp.cgi

       Running on lighttpd (FastCGI)

       Make sure "mod_fcgi" is enabled. You also must have FCGI installed.

       This example configuration uses TCP/IP:

           $HTTP["url"] == "^/app" {
               fastcgi.server += (
                   "/app" => (
                       "" => (
                           "host" => "127.0.0.1",
                           "port" => "5000",
                           "check-local" => "disable",
                       )
                   )
               )
           }

       Launch your application:

           plackup -s FCGI --port 5000 bin/app.psgi

       This example configuration uses a socket:

           $HTTP["url"] =~ "^/app" {
               fastcgi.server += (
                   "/app" => (
                       "" => (
                           "socket" => "/tmp/fcgi.sock",
                           "check-local" => "disable",
                       )
                   )
               )
           }

       Launch your application:

           plackup -s FCGI --listen /tmp/fcgi.sock bin/app.psgi

   Performance Improvements
       The following modules can be used to speed up an app in Dancer2:

       •   CGI::Deurl::XS

       •   Class::XSAccessor

       •   Cpanel::JSON::XS

       •   Crypt::URandom

       •   HTTP::XSCookies

       •   HTTP::XSHeaders

       •   Math::Random::ISAAC::XS

       •   MooX::TypeTiny

       •   Type::Tiny::XS

       •   URL::Encode::XS

       •   YAML::XS

       If you generated your application with "dancer2 gen", you can easily install these with
       the following command:

           cpanm --installdeps . --with-feature=accelerate

       To build them, you will need access to a C compiler, and using these modules will prevent
       you from fatpacking your application.

       These modules are installed by default when building a Docker container containing your
       application.

AUTHOR

       Dancer Core Developers

COPYRIGHT AND LICENSE

       This software is copyright (c) 2023 by Alexis Sukrieh.

       This is free software; you can redistribute it and/or modify it under the same terms as
       the Perl 5 programming language system itself.