=head1 NAME
Carton::Doc::FAQ - Frequently Asked Questions
=head1 QUESTIONS
=head2 It looks useful, but what is the
use
case of this tool?
The particular problem that carton is trying to address is this:
You develop a Perl-based application, possibly but not limited to
webapps,
with
dozens of CPAN module dependencies. You install these
modules on your development machine, and describe these dependencies
in your I<cpanfile>.
Now you get a production environment, either on PaaS provider or some
VPS, you install the dependencies using C<cpanm --installdeps .> and
it will pull all the latest releases from CPAN as of today and
everything just works.
A few weeks later, your application becomes more popular, and you
think you need another machine to serve more requests. You set up
another machine
with
vanilla perl installation and install the
dependencies the same way. That will pull the I<latest> releases from
CPAN I<on that date>, rather than the same as what you have today.
And that is the problem. It's not likely that everything just breaks
one day, but there's always a chance that one of the dependencies
breaks an API compatibility, or just uploaded a buggy version to CPAN
on that particular day.
Carton allows you to I<
lock
> these dependencies into a version
controlled
system
, so that every
time
you deploy from a checkout, it
is guaranteed that all the same versions are installed into the
local
environment.
=head2 How is this different from Pinto or CPAN::Mini::Inject?
carton definitely shares the goal
with
these private CPAN repository
management tool. But the main difference is that rather than creating
an actual CPAN-like repository that works
with
any CPAN clients,
Carton provides a way to install specific versions of distributions
from CPAN, or any CPAN-like mirrors (as well as git repositories in
the future version of Carton).
Existing tools are designed to work I<
with
> CPAN clients such as
L<CPAN> or L<CPANPLUS>, and have accomplished that by working
around
the CPAN mirror structure.
carton I<internally> does the same thing, but its user interface is
centered
around
the installer, by implementing a wrapper
for
L<cpanm|App::cpanminus>, so you can
use
the same commands in the
development mode and deployment mode.
Carton automatically maintains the L<cpanfile.snapshot> file, which is meant
to be version controlled, inside your application directory. You don't
need a separate database, a directory or a web server to maintain
tarballs outside your application. The I<cpanfile.snapshot> file can always
be generated
with
C<carton install> command, and C<carton install> on
another machine can
use
the version in the snapshot.
=head2 I already
use
Pinto to create DarkPAN mirror. Can I
use
Carton
with
this?
Yes, by specifying Pinto mirror as your Carton mirror, you can take a
snapshot of your dependencies including your private modules on Pinto,
or whatever DarkPAN mirror.
=head2 I'm already using perlbrew and
local
::lib. Can I
use
carton
with
this?
If you're using L<
local
::lib> already
with
L<perlbrew> perl, possibly
with
the new C<perlbrew lib> command, that's great! There are multiple
benefits over using L<perlbrew> and L<
local
::lib>
for
development and
use
L<Carton>
for
deployment.
The best practice and workflow to get your perl environment as clean
as possible
with
lots of modules installed
for
quick development would
be this:
=over
=item *
Install fresh perl using perlbrew. The version must be the same
against the version you'll run on the production environment.
=item *
Once the installation is done,
use
C<perlbrew lib> command to create a
new
local
lib environment (let's call it I<devel>) and always
use
the
library as a
default
environment. Install as many modules as you would
like into the I<devel> library path.
This ensures to have a vanilla C<perl> library path as clean as
possible.
=item *
When you build a new project that you want to manage dependencies via
Carton, turn off the I<devel>
local
::lib and create a new one, like
I<myapp>. Install L<Carton> and all of its dependencies to the
I<myapp>
local
::lib path. Then run C<carton install> like you
normally
do
.
Because I<devel> and I<myapp> are isolated, the modules you installed
into I<devel> doesn't affect the process
when
carton builds the
dependency tree
for
your new project at all. This could often be
critical
when
you have a conditional dependency in your tree, like
L<Any::Moose>.
=back
=head2 I'm using perlbrew, but C<< carton install >> uses
system
perl, how to fix?
The issue is most likelly caused by a inital bad install of C<cpanm>
or C<carton> or both, that ended up
with
a shebang line pointed to the
(wrong)
system
perl.
=over 4
=item Re-install Carton on you perlbrew environment
Run C<< cpanm -f Carton >>. This will force-install Carton,
and because your C<cpanm> is now using the correct C<perl>,
the same will happen
with
C<carton>.
=back
Make sure the shebang (the first line) of your C<carton> script points to the right perl path, rather than C</usr/bin/perl>.