NAME

pagi-server - PAGI application server

SYNOPSIS

pagi-server [options] [app] [key=value ...]

# Serve current directory (default)
pagi-server

# Serve a specific directory
pagi-server PAGI::App::Directory root=/var/www

# Run a PAGI app file
pagi-server ./app.pl

# With environment modes
pagi-server -E development app.pl  # Lint middleware enabled
pagi-server -E production app.pl   # No auto-middleware

# With options
pagi-server -p 8080 PAGI::App::Directory root=/var/www
pagi-server --workers 4 ./myapp.pl

DESCRIPTION

pagi-server is the command-line interface for running PAGI applications. It uses PAGI::Runner for application loading and server orchestration, and PAGI::Server as the default server backend.

ENVIRONMENT MODES

pagi-server supports environment modes similar to Plack's -E flag:

development

Auto-enables PAGI::Middleware::Lint with strict mode. This catches specification violations early and provides helpful error messages.

This is the default when running interactively (TTY detected).

production

No middleware is auto-enabled, and access logging is disabled for maximum performance. Use --access-log FILE to enable logging in production.

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, pagi-server sets PAGI_ENV to the resolved value. Your app can check $ENV{PAGI_ENV} to know what mode it's running in, similar to Plack's PLACK_ENV.

OPTIONS

Common Options

These are handled by PAGI::Runner and work with any server backend.

-I, --lib PATH

Add PATH to @INC before loading the app. Can be specified multiple times, similar to perl -I.

pagi-server -I ./lib -I ./vendor/lib ./app.pl
-a, --app FILE

Path to .pl/.psgi file returning PAGI app coderef. Legacy option for backward compatibility; you can also just pass the file as an argument.

-e CODE

Inline app code, like perl -e. Must return a PAGI app coderef.

# Using a PAGI::App module
pagi-server -MPAGI::App::File -e 'PAGI::App::File->new(root => ".")->to_app'
-M MODULE

Load MODULE before evaluating -e code, like perl -M. Can be specified multiple times. Supports Module=import,args syntax.

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

Bind address (default: 127.0.0.1, localhost only)

The default only accepts connections from localhost, which is secure by default for development. For remote access:

pagi-server --host 0.0.0.0 ./app.pl    # All IPv4 interfaces
-p, --port PORT

Bind port (default: 5000)

-s, --server CLASS

Server class to use (default: PAGI::Server). Reserved for future use with pluggable server backends.

-E, --env MODE

Environment mode: development, production, or none.

-l, --loop BACKEND

Event loop backend (Poll, EV, Epoll, UV). Default is auto-detect.

--access-log FILE

Path to access log file (default: STDERR)

--no-access-log

Disable access logging entirely. Improves throughput by 5-15%.

-D, --daemonize

Fork to background and run as a daemon.

--pid FILE

Write the process ID to FILE.

--user USER

After binding, drop privileges to run as USER. Requires root.

--group GROUP

After binding, drop privileges to run as GROUP.

-q, --quiet

Suppress startup banner and development mode message.

--no-default-middleware

Disable auto-middleware even in development mode.

-v, --version

Show version info.

--help

Show help.

PAGI::Server Options

These options are passed through to PAGI::Server.

-w, --workers NUM

Number of worker processes (default: 1, single-process mode)

--reuseport

Enable SO_REUSEPORT mode for multi-worker servers.

--ssl-cert FILE, --ssl-key FILE

Enable HTTPS with the specified certificate and key files.

--max-requests NUM

Maximum requests per worker before restart (default: 0, unlimited)

--max-connections NUM

Maximum concurrent connections per worker (default: auto-detect)

--max-body-size NUM

Maximum request body size in bytes (default: 10MB)

--timeout NUM

Connection idle timeout in seconds (default: 60)

--shutdown-timeout NUM

Graceful shutdown timeout in seconds (default: 30)

--log-level LEVEL

Log verbosity: debug, info, warn, error (default: info)

-b, --listener-backlog NUM

Listen queue size (default: 2048)

--max-receive-queue NUM

Maximum WebSocket receive queue size (default: 1000)

--max-ws-frame-size NUM

Maximum WebSocket frame size in bytes (default: 65536)

--request-timeout NUM

Request stall timeout in seconds (default: 0, disabled)

--ws-idle-timeout NUM

WebSocket idle timeout in seconds (default: 0, disabled)

--sse-idle-timeout NUM

SSE idle timeout in seconds (default: 0, disabled)

--heartbeat-timeout NUM

Worker heartbeat timeout in seconds (default: 50, 0 = disabled). Only active in multi-worker mode. Workers send periodic heartbeats to the parent via a Unix pipe. If a worker's event loop is blocked for longer than this timeout (blocking syscall, deadlock, CPU-bound work), the parent kills it with SIGKILL and respawns a replacement.

This should be larger than the maximum time you expect any single operation to block the event loop. Async operations using await do not block the event loop and will never trigger this timeout.

--sync-file-threshold NUM

Sync file read threshold in bytes (default: 65536)

--access-log-format FORMAT

Access log format string or preset name (default: clf).

Preset names: clf, combined, common, tiny.

Custom format strings use Apache-style atoms:

--access-log-format combined
--access-log-format '%h %s %Dms'

See "ACCESS LOG FORMAT" in PAGI::Server for the full atoms table.

--future-xs

Enable Future::XS for improved Future performance. Must be installed separately: cpanm Future::XS

Can also be enabled via environment variable: PAGI_FUTURE_XS=1

--http2

Enable HTTP/2 support. Requires Net::HTTP2::nghttp2.

When combined with --ssl-cert/--ssl-key, uses ALPN negotiation (h2/http/1.1). Without TLS, enables h2c (cleartext HTTP/2) mode.

See PAGI::Server for HTTP/2 protocol tuning options (h2_max_concurrent_streams, h2_initial_window_size, etc.) which can be passed via the constructor API.

APP SPECIFICATION

Module Name

If the argument contains ::, it's treated as a Perl module name:

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

The module must have new() and to_app() methods.

File Path

If the argument contains / or ends with .pl/.psgi:

pagi-server ./app.pl

The file must return a PAGI app coderef.

Default

If no app is specified, serves the current directory:

pagi-server
# equivalent to: pagi-server PAGI::App::Directory root=.

SIGNAL HANDLING

TERM, INT

Graceful shutdown.

HUP

Graceful restart (multi-worker mode only).

TTIN, TTOU

Increase/decrease worker count (multi-worker mode only).

EXAMPLES

# Development (auto-detected from TTY)
pagi-server ./app.pl

# Explicit production mode
pagi-server -E production ./app.pl
PAGI_ENV=production pagi-server ./app.pl

# Multi-worker production
pagi-server --host 0.0.0.0 -p 80 --workers 4 -E production ./app.pl

# With HTTPS
pagi-server --ssl-cert cert.pem --ssl-key key.pem ./app.pl

# Maximum performance
pagi-server --no-access-log --workers 8 -E production ./app.pl

# Using EV event loop
pagi-server --loop EV ./app.pl

ENVIRONMENT

PAGI_ENV

Default environment mode if -E is not specified and no TTY detected.

IO_ASYNC_LOOP

Preferred IO::Async loop backend.

FUTURE::IO INTEGRATION

pagi-server automatically configures Future::IO to use the IO::Async backend if Future::IO::Impl::IOAsync is installed. This enables seamless use of Future::IO-based libraries in your PAGI applications:

# These just work under pagi-server:
use Async::Redis;
use Some::FutureIO::Database;

# PAGI::SSE->every() also works:
$sse->every(1, sub { $sse->send(data => time) });

In non-production mode, pagi-server will report when Future::IO is configured:

Future::IO configured for IO::Async

If you're using PAGI::Server programmatically (not via pagi-server), you must configure Future::IO yourself. See "LOOP INTEROPERABILITY" in PAGI::Server for details.

SEE ALSO

PAGI::Runner, PAGI::Server, PAGI::Middleware::Lint, Future::IO

AUTHOR

John Napiorkowski <jjnapiork@cpan.org>

LICENSE

This software is licensed under the same terms as Perl itself.