NAME
PAGI::Server::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::Server::Runner;
PAGI::Server::Runner->run(@ARGV);
DESCRIPTION
PAGI::Server::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::Server::Runner supports environment modes similar to Plack's -E flag:
- development
-
Auto-enables PAGI::Middleware::Lint with strict mode to catch specification violations early (when PAGI-Tools is installed). 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 and new is called with the provided key=value arguments. The constructed value may be a native PAGI coderef or an instantiated application-provider object. A provider is normalized by calling to_app exactly once; to_app is never invoked as a class method.
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 either a native PAGI coderef or an instantiated application-provider object. A provider is normalized through to_app exactly once before the server is constructed.
For compatibility with Plack's plackup, the runner localizes $0 to the app file before loading it. This ensures FindBin::Bin resolves to the app file directory inside the app. If FindBin was already loaded, the runner also calls FindBin::again() to refresh its cached path.
Default
If no app is specified, defaults to serving the current directory:
pagi-server # same as: PAGI::App::Directory root=.
METHODS
run
PAGI::Server::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::Server::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 are passed separately via the server_options hashref (see "load_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 => ".")'
Server-Specific Options
Server-specific options should be parsed by the server's CLI wrapper (e.g., bin/pagi-server) and passed to Runner via the server_options hashref parameter. This keeps Runner server-agnostic.
See PAGI::Server for available options when using pagi-server.
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. Every accepted loading form is normalized to and returns the native PAGI app coderef used by the server.
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 if available (requires PAGI-Tools).
load_server
my $server = $runner->load_server;
Constructs the configured server class (-s CLASS, default PAGI::Server) according to this runner's backend convention: $class->new(%options) followed by $server->run. This is a PAGI::Server::Runner plugin interface, not a construction API required by PAGI::Spec::Server.
Creates the server instance with the prepared app and configuration. Parses server-specific options and passes them to the server constructor.
run
PAGI::Server::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::Server::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 byload_server()Development mode now auto-enables Lint middleware (when PAGI-Tools is installed)
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.