NAME¶
Carton::Doc::FAQ - Frequently Asked Questions
QUESTIONS¶
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
cpanfile.
Now you get a production environment, either on PaaS provider or some VPS, you
install the dependencies using "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
latest releases from CPAN
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
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.
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
with CPAN clients such as CPAN or
CPANPLUS, and have accomplished that by working around the CPAN mirror
structure.
carton
internally does the same thing, but its user interface is centered
around the installer, by implementing a wrapper for cpanm, so you can use the
same commands in the development mode and deployment mode.
Carton automatically maintains the 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
cpanfile.snapshot file can always be generated
with "carton install" command, and "carton install" on
another machine can use the version in the snapshot.
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.
I'm already using perlbrew and local::lib. Can I use carton with this?¶
If you're using local::lib already with perlbrew perl, possibly with the new
"perlbrew lib" command, that's great! There are multiple benefits
over using perlbrew and local::lib for development and use 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:
- •
- Install fresh perl using perlbrew. The version must be the same against
the version you'll run on the production environment.
- •
- Once the installation is done, use "perlbrew lib" command to
create a new local lib environment (let's call it devel) and always
use the library as a default environment. Install as many modules as you
would like into the devel library path.
This ensures to have a vanilla "perl" library path as clean as
possible.
- •
- When you build a new project that you want to manage dependencies via
Carton, turn off the devel local::lib and create a new one, like
myapp. Install Carton and all of its dependencies to the
myapp local::lib path. Then run "carton install" like you
normally do.
Because devel and myapp are isolated, the modules you
installed into 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
Any::Moose.