NAME

PAGI::Runner - PAGI application loader and server runner

SYNOPSIS

# Command line usage via pagi-server
pagi-server PAGI::App::Directory root=/var/www
pagi-server ./app.pl -p 8080
pagi-server                        # serves current directory

# With environment modes
pagi-server -E development app.pl  # enable Lint middleware
pagi-server -E production app.pl   # no auto-middleware
PAGI_ENV=production pagi-server app.pl

# Programmatic usage
use PAGI::Runner;

PAGI::Runner->run(@ARGV);

DESCRIPTION

PAGI::Runner is a loader and runner for PAGI applications, similar to Plack::Runner for PSGI. It handles CLI argument parsing, app loading (from files or modules), environment modes, and server orchestration.

The runner is designed to be server-agnostic. Common options like host, port, and daemonize are handled by the runner, while server-specific options are passed through to the server backend.

ENVIRONMENT MODES

PAGI::Runner supports environment modes similar to Plack's -E flag:

development

Auto-enables PAGI::Middleware::Lint with strict mode to catch specification violations early. This is the default when running interactively (TTY detected).

production

No middleware is auto-enabled. This is the default when running non-interactively (no TTY, e.g., systemd, docker, cron).

none

Explicit opt-out of all auto-middleware, regardless of TTY detection.

Mode is determined by (in order of precedence):

1. -E / --env command line flag
2. PAGI_ENV environment variable
3. Auto-detection: TTY = development, no TTY = production

After determining the mode, the runner sets PAGI_ENV to the resolved value. This allows your application to check $ENV{PAGI_ENV} to know what mode it's running in, similar to Plack's PLACK_ENV.

Use --no-default-middleware to disable auto-middleware while keeping the mode for other purposes.

APP LOADING

The runner supports three ways to specify an application:

Module Name

If the app specifier contains ::, it's treated as a module name:

pagi-server PAGI::App::Directory root=/var/www show_hidden=1

The module is loaded, instantiated with the provided key=value arguments, and to_app is called to get the PAGI app coderef.

File Path

If the app specifier contains / or ends with .pl or .psgi, it's treated as a file path:

pagi-server ./app.pl
pagi-server /path/to/myapp.psgi

The file is loaded via do and must return a coderef.

Default

If no app is specified, defaults to serving the current directory:

pagi-server                        # same as: PAGI::App::Directory root=.

METHODS

run

PAGI::Runner->run(@ARGV);

Class method that creates a runner, parses options, loads the app, and runs the server. This is the main entry point for CLI usage.

new

my $runner = PAGI::Runner->new(%options);

Creates a new runner instance. Most users should use run() instead.

parse_options

$runner->parse_options(@args);

Parses CLI options from the argument list. Common options are stored in the runner object. Server-specific options (those not recognized) are collected for pass-through to the server.

Common Options (handled by Runner)

-a, --app FILE      Load app from file (legacy option)
-e CODE             Inline app code (like perl -e)
-M MODULE           Load MODULE before -e (repeatable, like perl -M)
-o, --host HOST     Bind address (default: 127.0.0.1)
-p, --port PORT     Bind port (default: 5000)
-s, --server CLASS  Server class (default: PAGI::Server)
-E, --env MODE      Environment mode (development, production, none)
-I, --lib PATH      Add PATH to @INC (repeatable)
-l, --loop BACKEND  Event loop backend (EV, Epoll, UV, Poll)
-D, --daemonize     Run as background daemon
--access-log FILE   Access log file (default: STDERR)
--no-access-log     Disable access logging
--pid FILE          Write PID to file
--user USER         Run as specified user (after binding)
--group GROUP       Run as specified group (after binding)
-q, --quiet         Suppress startup messages
--default-middleware  Toggle mode middleware (default: on)
-v, --version       Show version info
--help              Show help

Example with -e and -M:

pagi-server -MPAGI::App::File -e 'PAGI::App::File->new(root => ".")->to_app'

Server-Specific Options (passed through)

All unrecognized options starting with - are passed to the server. For PAGI::Server, these include:

-w, --workers       Number of worker processes
--reuseport         Enable SO_REUSEPORT mode
--ssl-cert, --ssl-key  TLS configuration
--max-requests, --max-connections, --max-body-size
--timeout, --log-level, etc.

See PAGI::Server for the full list of server-specific options.

mode

my $mode = $runner->mode;

Returns the current environment mode. Determines mode by checking (in order): explicit -E flag, PAGI_ENV environment variable, or auto-detection based on TTY.

load_app

my $app = $runner->load_app;

Loads the PAGI application based on the app specifier from command line arguments. Returns the app coderef.

prepare_app

my $app = $runner->prepare_app;

Loads the app and wraps it with mode-appropriate middleware. In development mode (with default_middleware enabled), wraps with PAGI::Middleware::Lint.

load_server

my $server = $runner->load_server;

Creates the server instance with the prepared app and configuration. Parses server-specific options and passes them to the server constructor.

run

PAGI::Runner->run(@ARGV);
$runner->run(@ARGV);

Main entry point. Parses options, loads the app, creates the server, and delegates to $server->run() which manages the event loop.

BREAKING CHANGES

As of version 1.0, PAGI::Runner has been refactored to be server-agnostic:

  • Server-specific options are now passed through to the server

  • The prepare_server() method has been replaced by load_server()

  • Development mode now auto-enables Lint middleware

The CLI interface is unchanged - existing command-line usage continues to work as before.

SEE ALSO

PAGI::Server, PAGI::Middleware::Lint, Plack::Runner

AUTHOR

John Napiorkowski <jjnapiork@cpan.org>

LICENSE

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