Skip to content

Commit

Permalink
Move deployment information out of core manual
Browse files Browse the repository at this point in the history
This info belongs in the Deployment section of the manual; having it in
the core of the manual doesn't make sense.
  • Loading branch information
Jason A. Crome committed Aug 11, 2024
1 parent 71caa08 commit 4b12ad3
Show file tree
Hide file tree
Showing 2 changed files with 174 additions and 210 deletions.
210 changes: 0 additions & 210 deletions lib/Dancer2/Manual.pod
Original file line number Diff line number Diff line change
Expand Up @@ -1934,150 +1934,6 @@ access to the configuration using the imported keywords:

# ...

=head1 PACKAGING

=head2 Carton

=head3 What it does

L<Carton> sets up a local copy of your project prerequisites. You only
need to define them in a file and ask Carton to download all of them
and set them up.
When you want to deploy your app, you just carry the git clone and ask
Carton to set up the environment again and you will then be able to run it.

The benefits are multifold:

=over 4

=item * Local Directory copy

By putting all the dependencies in a local directory, you can make
sure they aren't updated by someone else by accident and their versions
locked to the version you picked.

=item * Sync versions

Deciding which versions of the dependent modules your project needs
allows you to sync this with other developers as well. Now you're all
using the same version and they don't change unless you want update the
versions you want. When updated everyone again uses the same new version
of everything.

=item * Carry only the requirement, not bundled modules

Instead of bundling the modules, you only actually bundle the requirements.
Carton builds them for you when you need it.

=back

=head3 Setting it up

First set up a new app:

$ dancer2 gen -a MyApp
...

Delete the files that are not needed:

$ rm -f Makefile.PL MANIFEST MANIFEST.SKIP

Create a git repo:

$ git init && git add . && git commit -m "initial commit"

Add a requirement using the L<cpanfile> format:

$ cat > cpanfile
requires 'Dancer2' => 0.155000;
requires 'Template' => 0;
recommends 'URL::Encode::XS' => 0;
recommends 'CGI::Deurl::XS' => 0;
recommends 'HTTP::Parser::XS' => 0;

Ask carton to set it up:

$ carton install
Installing modules using [...]
Successfully installed [...]
...
Complete! Modules were install into [...]/local

Now we have two files: I<cpanfile> and I<cpanfile.snapshot>. We
add both of them to our Git repository and we make sure we don't
accidentally add the I<local/> directory Carton created which holds
the modules it installed:

$ echo local/ >> .gitignore
$ git add .gitignore cpanfile cpanfile.snapshot
$ git commit -m "Start using carton"

When we want to update the versions on the production machine,
we simply call:

$ carton install --deployment

By using --deployment we make sure we only install the modules
we have in our cpanfile.snapshot file and do not fallback to querying
the CPAN.

=head2 FatPacker

L<App::FatPacker> (using its command line interface, L<fatpack>) packs
dependencies into a single file, allowing you to carry a single file
instead of a directory tree.

As long as your application is pure-Perl, you could create a single
file with your application and all of Dancer2 in it.

The following example will demonstrate how this can be done:

Assuming we have an application in I<lib/MyApp.pm>:

package MyApp;
use Dancer2;
get '/' => sub {'OK'};
1;

And we have a handler in I<bin/app.pl>:

use strict;
use warnings;
use FindBin;
use lib "$FindBin::Bin/../lib";
use MyApp;

MyApp->to_app;

To fatpack it, we begin by tracing the script:

$ fatpack trace bin/app.pl

This creates a I<fatpacker.trace> file. From this we create the packlists:

$ fatpack packlists-for `cat fatpacker.trace` > packlists

The packlists are stored in a file called I<packlists>.

Now we create the tree using the following command:

$ fatpack tree `cat packlists`

The tree is created under the directory I<fatlib>.

Now we create a file containing the dependency tree, and add our script to it,
using the following command:

$ (fatpack file; cat bin/app.pl) > myapp.pl

This creates a file called I<myapp.pl> with everything in it. Dancer2 uses
L<MIME::Types> which has a database of all MIME types and helps translate those.
The small database file containing all of these types is a binary and therefore
cannot be fatpacked. Hence, it needs to be copied to the current directory so our
script can find it:

$ cp fatlib/MIME/types.db .

=head1 MIDDLEWARES

=head2 Plack middlewares
Expand Down Expand Up @@ -2148,37 +2004,6 @@ This is necessary if you need to add eTag or ContentMD5 headers to
C<HEAD> requests, and you are encouraged to manually add those default
middleware back into your PSGI stack.

=head3 Running on Perl web servers with plackup

A number of Perl web servers supporting PSGI are available on CPAN:

=over 4

=item * L<Starman>

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

=item * L<Twiggy>

C<Twiggy> is an C<AnyEvent> web server, it's light and fast.

=item * L<Corona>

C<Corona> is a C<Coro> based web server.

=back

To start your application, just run plackup (see L<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.

=head4 Enabling content compression

Content compression (gzip, deflate) can be easily enabled via a Plack
Expand Down Expand Up @@ -2228,41 +2053,6 @@ Currently this still demands the same appdir for both (default circumstance)
but in a future version this will be easier to change while staying very
simple to mount.

=head3 Running from Apache 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>

=head1 PLUGINS

=head2 Writing a plugin
Expand Down
Loading

0 comments on commit 4b12ad3

Please sign in to comment.