PHP Application Server In Rust
Pasir is an Indonesian word for "sands" (pronounced "PA-seer").
It is a high-performance PHP application server written in Rust that provides a solid foundation for PHP applications by embedding PHP execution directly into a modern HTTP server. Built with a custom SAPI and C bindings through ext-php-rs, Pasir offers a fast and efficient alternative to traditional PHP-FPM setups while maintaining compatibility with existing PHP applications.
β οΈ Development Status: Pasir is currently in active development and not yet production-ready. While functional, it should be considered experimental for production use cases.
- π High Performance: Built on Rust's async ecosystem with Hyper and Tokio for optimal performance
- βοΈ Minimal Configuration: Works out of the box without configuration, but offers intuitive TOML-based routing that's friendlier than .htaccess, nginx.conf, or Caddyfile when customization is needed
- π§ Embedded PHP: Custom SAPI integration with PHP 8.1+ (ZTS required)
- π‘ Modern HTTP: Full HTTP/1.1 and HTTP/2 support with automatic protocol detection
- π― Flexible Routing: Regex-based URL pattern matching with configurable handlers
- π Static File Serving: Built-in static file server with gzip compression support
- π Non-Persistent Execution: Similar behavior to PHP-FPM for application compatibility
- π‘οΈ Graceful Shutdown: SIGINT handling with configurable timeout
- π Request Tracing: Built-in HTTP request tracing and logging
- π³ Docker Ready: Containerized deployment support
- β‘ Zero Downtime: Hot-swappable connections during graceful shutdown
- PHP: Version 8.1+ compiled with
--disable-zend-signals --enable-embed --enable-zts
Pre-built binaries can be downloaded from the latest release.
The binaries are built on the latest PHP version and are statically linked, meaning they won't be able to load dynamic
extensions.
To view the list of installed extensions, run pasir -m
command.
brew install el7cosmos/pasir/pasir
Pre-built Docker images are available on Docker Hub at el7cosmos/pasir.
# Pull the latest image
docker pull el7cosmos/pasir
# Run with your PHP application
docker run -p 8080:8080 -v /path/to/your/app:/app el7cosmos/pasir
# Run with custom port and address
docker run -p 3000:3000 -v /path/to/your/app:/app el7cosmos/pasir --address 0.0.0.0 --port 3000
- Rust: Version 1.x (2024 edition)
- PHP: Version 8.1+ compiled with
--disable-zend-signals --enable-embed --enable-zts
- System Dependencies:
libclang-dev
for ext-php-rs compilation
# Clone the repository
git clone <repository-url>
cd pasir
# Build the project
cargo build --release
# Run with default configuration
cargo run --release
# Build the Docker image
docker build -t pasir .
# Run with Docker
docker run -p 8080:8080 -v $(pwd):/app pasir
# Using docker-bake
docker buildx bake
# Run with required port (required parameter)
pasir --port 8080
# Custom address and port with document root
pasir --address 0.0.0.0 --port 3000 /path/to/your/webroot
# Enable verbose logging
pasir --port 8080 --verbose
# Quiet logging
pasir --port 8080 --quiet
PHP Application Server In Rust
Usage: pasir [OPTIONS] --port <PORT> [ROOT]
Arguments:
[ROOT] [default: .]
Options:
-a, --address <ADDRESS> [env: PASIR_ADDRESS=] [default: 127.0.0.1]
-p, --port <PORT> [env: PASIR_PORT=]
-d, --define <foo[=bar]> Define INI entry foo with value 'bar'
-i, --info PHP information
-m, --modules Show compiled in modules
-v, --verbose... Increase logging verbosity
-q, --quiet... Decrease logging verbosity
-h, --help Print help
-V, --version Print version
Pasir uses a pasir.toml
configuration file in your document root to define routing rules:
# Serve PHP files
[[routes]]
match.uri = '(/(index|update)\.php)|(/core/[^/]*\.php$)'
serve = "php"
# Serve static files
[[routes]]
match.uri = 'favicon.ico'
serve = "static"
# Block sensitive files (optional)
[[routes]]
match.uri = [
"*/composer.json",
"*/composer.lock",
]
action.status = 404
serve = "default"
# Custom headers for assets (optional)
[[routes]]
match.uri = [
"*.css",
"*.js",
]
action.response_headers.append = [
{ "Cache-Control" = "public, max-age=3600" }
]
[[routes]]
match = { }
action.response_headers.remove = [
"X-Generator"
]
match.uri
: Regex pattern(s) for URL matchingserve
: Handler type ("php"
,"static"
, or"default"
). When specified, directly serves the request without processing other route matches furtheraction.status
: HTTP status code for direct responsesaction.response_headers
: Header manipulation (insert, append, remove)
# Run with custom configuration
docker run -d \
--name pasir-server \
-p 8080:8080 \
-v /path/to/your/app:/app
9EC7
\
-v /path/to/pasir.toml:/app/pasir.toml \
pasir
# With environment variables
docker run -d \
--name pasir-server \
-p 3000:3000 \
-e PASIR_ADDRESS=0.0.0.0 \
-e PASIR_PORT=3000 \
-v /path/to/your/app:/app \
pasir --address $PASIR_ADDRESS --port $PASIR_PORT
Create a simple index.php
in your document root:
<?php
echo "Hello from Pasir!\n";
echo "Current time: " . date('Y-m-d H:i:s') . "\n";
echo "Server: " . $_SERVER['HTTP_HOST'] . "\n";
?>
With the basic configuration above, this will be served at http://localhost:8080/index.php
.
Pasir combines several key technologies:
- Rust + Tokio: Async runtime for high-concurrency request handling
- Hyper: Modern HTTP server implementation
- ext-php-rs: PHP SAPI integration for embedded execution
- Tower: Middleware and service abstractions
- Regex: Flexible URL pattern matching
The server processes each request through:
- Router Service: Matches URLs against configured patterns
- PHP Service: Executes PHP scripts in embedded environment
- Static Service: Serves static files with optimizations
- Response Pipeline: Applies headers and transformations
We welcome contributions! Please see our development guidelines:
- Code Style: Follow the project's Rustfmt configuration (2-space indentation)
- Testing: Add tests for new functionality using
cargo test
- Documentation:
todo!
- Security: Review any unsafe blocks and PHP integration code carefully
# Clone and setup
git clone <repository-url>
cd pasir
# Install development dependencies
cargo build
# Run tests
cargo test
# Format code
cargo fmt
# Lint code
cargo clippy
# Build development image
docker build -t pasir-dev .
# Run with hot reload (bind mount for development)
docker run -it --rm \
-p 8080:8080 \
-v $(pwd):/workspace \
-w /workspace \
pasir-dev
This project is licensed under the terms specified in the LICENSE file.
- PHP-FPM - Traditional FastCGI Process Manager
- FrankenPHP - Go-based PHP application server
- RoadRunner - High-performance PHP application server
- NGINX Unit - Polyglot web application server
- Issues: Report bugs and feature requests via GitHub Issues
- Documentation:
todo!
- Discussions:
todo!
Pasir - Bringing modern performance to PHP applications through Rust's reliability and speed.