CGI Mode¶
CGI mode is the simplest way to run VeloServe with PHP. It uses the standard php-cgi binary and works on any platform without special compilation.
How It Works¶
HTTP Request → VeloServe → spawn php-cgi → Execute Script → HTTP Response
↑
Process pool with semaphore
VeloServe maintains a pool of PHP worker slots. For each PHP request:
- A semaphore slot is acquired from the pool
- A
php-cgiprocess is spawned with the CGI environment - The request body is written to the process's stdin
- The response is read from stdout
- The slot is released back to the pool
This is the same model used by traditional web servers, but VeloServe's Rust async runtime makes the I/O handling significantly more efficient.
Performance Characteristics¶
| Metric | Value |
|---|---|
| Requests/sec | ~500 |
| Latency | ~50ms |
| Memory | Low (on-demand) |
| CPU overhead | Medium (process spawn) |
CGI mode is best suited for development, low-traffic sites, or environments where you cannot install libphp-embed.
Prerequisites¶
Download PHP from windows.php.net and ensure php-cgi.exe is in your PATH.
Building VeloServe for CGI¶
No special build flags needed — CGI is the default mode:
Or download a pre-built binary from the releases page.
Configuration¶
[server]
listen = "0.0.0.0:8080"
[php]
enable = true
mode = "cgi"
binary_path = "/usr/bin/php-cgi"
workers = 4
memory_limit = "256M"
max_execution_time = 30
[[virtualhost]]
domain = "*"
root = "/var/www/html"
Key Settings¶
| Setting | Description | Default |
|---|---|---|
binary_path | Path to php-cgi binary | auto-detected |
workers | Max concurrent PHP processes | 4 |
memory_limit | PHP memory limit per request | 256M |
max_execution_time | Script timeout in seconds | 30 |
extensions | File extensions treated as PHP | [".php", ".phtml"] |
Custom php.ini Settings¶
Pass custom INI directives via the config:
[php]
ini_settings = [
"upload_max_filesize=64M",
"post_max_size=64M",
"opcache.enable=1",
"opcache.memory_consumption=128"
]
Running¶
# With config file
veloserve --config veloserve.toml start
# Quick start (no config file)
veloserve start --root /var/www/html --listen 0.0.0.0:8080
CGI Environment Variables¶
VeloServe sets all standard CGI variables:
| Variable | Example |
|---|---|
SCRIPT_FILENAME | /var/www/html/index.php |
SCRIPT_NAME | /index.php |
REQUEST_URI | /blog/post?id=1 |
PATH_INFO | /blog/post |
DOCUMENT_ROOT | /var/www/html |
QUERY_STRING | id=1&page=2 |
REQUEST_METHOD | GET, POST |
HTTP_HOST | example.com |
REMOTE_ADDR | 192.168.1.1 |
SERVER_PORT | 80 |
HTTPS | on or off |
GATEWAY_INTERFACE | CGI/1.1 |
SERVER_SOFTWARE | VeloServe/1.0.5 |
REDIRECT_STATUS | 200 |
Clean URLs¶
VeloServe supports clean URLs (WordPress, Laravel, etc.) automatically. When a requested file does not exist and index.php is present, the request is routed through index.php with PATH_INFO set:
| URL | Script | PATH_INFO |
|---|---|---|
/index.php | index.php | (empty) |
/blog/post | index.php | /blog/post |
/api/users/1 | index.php | /api/users/1 |
Troubleshooting¶
"PHP binary not found"¶
Install PHP-CGI or set the correct path in your config:
502 Bad Gateway¶
This usually means PHP crashed or timed out. Try:
- Increase
max_execution_time - Increase
memory_limit - Check PHP error logs
- Test with a simple script:
<?php echo "OK"; ?>
Blank Page¶
PHP is executing but producing no output:
- Temporarily set
display_errors = truein your config - Check the PHP error log
- Verify file permissions on the document root
- Test with:
<?php phpinfo(); ?>
Next Steps¶
- SAPI Mode — 10-100x faster with embedded PHP
- PHP Configuration — full PHP config reference
- Performance Tuning — optimize for production