Only show guides for your app
Run PHP on Falix's PHP Web Server application — nginx and PHP-FPM under supervisord, pretty URLs through a front controller, and how to bring in Composer packages.
PHP still runs a huge share of the web, and Falix has an application built for it: the PHP Web Server. Unlike the plain PHP CLI, this one puts a real nginx and PHP-FPM in front of your code, so you serve a proper website — static assets, .php pages, and clean URLs — not just a script. This guide covers how it fits together and how to bring in Composer libraries.
| At a glance | |
|---|---|
| You need | A server running the PHP Web Server application, and comfort editing files |
| Plan | Any plan |
| Time | Twenty minutes |
If servers are new to you, read Create your first app server first.
The application's startup command is supervisord -c /home/container/supervisord.conf. supervisord is a small process manager; here it keeps two things alive together: PHP-FPM (which executes your PHP) and nginx (which serves files and hands .php requests to PHP-FPM). Your site lives in the folder named by the Web Root variable — public by default.
⚠️ Heads up: nginx needs your assigned
SERVER_PORTbaked into its config, and a fresh PHP Web Server's default config doesn't do that substitution — so it crash-loops withhost not found in "SERVER_PORT"and nothing serves. The fix isn't to hand-patch config files; it's to deploy the template first.
Use the PHP website template on this page. It ships the working stack: a supervisord.conf, an nginx.template.conf that gets your real port and web root filled in at boot, a php-fpm.conf, and a sample public/index.php. Deploying it onto a fresh PHP Web Server is what turns "crash-loop" into "serving."
(A template only overwrites same-named files. Deploying it onto a server running a different application switches that server to PHP Web Server first — a reinstall that wipes files, which the panel warns about. On a fresh PHP Web Server there's nothing to lose.)
Press Start, then open your server's address (from the Network page). The sample page loads and prints the PHP version — proof that nginx, PHP-FPM, and your port are all wired correctly.
Everything lives in public/:
.css, .js, images, .html) are served directly by nginx, fast, with no PHP involved..php files are executed by PHP-FPM and their output is returned.try_files $uri $uri/ /index.php?$query_string: if the requested path isn't a real file or folder, nginx falls back to index.php and keeps the query string. That means one index.php can route your whole site.A minimal front controller looks like this — save it as public/index.php:
<?php
$path = strtok($_SERVER['REQUEST_URI'], '?');
switch ($path) {
case '/':
echo 'Home page';
break;
case '/about':
echo 'About page';
break;
default:
http_response_code(404);
echo 'Not found';
}
Now /about works even though no about.php file exists — nginx routed it to index.php, which read the path and responded. Query values like /search?q=cats are still available in $_GET as usual.
🎯 Good to know: Unlike the PHP Composer application, the PHP Web Server does not run
composer installfor you — acomposer.jsonsitting in your files does nothing on its own.
You have three ways to get a vendor/ folder onto the server:
| Route | How | Best when |
|---|---|---|
| Packages page | Runs the real composer require in a helper container against your files, writing vendor/ to your disk (restart after) |
You want it done in the panel |
Upload vendor/ |
Run composer install on your own machine, upload the folder via File Manager or SFTP |
You already build locally |
| Git deploy | Add composer install as a post-deploy command, built on the server after each pull — see Add build steps to a deploy |
You deploy from Git |
Whichever you choose, require 'vendor/autoload.php'; at the top of your PHP then works normally.
Two things most PHP sites eventually need — file uploads and sessions — run through PHP's own settings, which the template leaves at PHP's built-in defaults.
File uploads. PHP caps upload and request-body sizes with upload_max_filesize and post_max_size, and the built-in defaults are small — a large upload quietly fails, or the form arrives empty. To raise them, add lines to the [www] pool in php-fpm.conf (the file the template ships) and restart:
php_admin_value[upload_max_filesize] = 20M
php_admin_value[post_max_size] = 24M
Keep post_max_size a little above upload_max_filesize so the whole form fits. Those numbers are just examples — set what suits your app.
Sessions. session_start() works, and PHP writes session data to its default temporary location. If your console shows a failed to write session data warning, that default path isn't writable in the container — point sessions at a folder you own before starting them:
session_save_path(__DIR__ . '/../tmp');
session_start();
The startup already creates a tmp/ folder next to public/, which makes a safe home for session files.
host not found in "SERVER_PORT" in the console — the default config never substituted your port. Deploy the PHP website template, which ships the config that does.public by default); confirm the Web Root variable in Settings matches where your files actually are.logs/php-fpm.log; the console (nginx/PHP-FPM output) also carries errors. For local debugging you can set display_errors on in your code, but keep it off in anything public.upload_max_filesize / post_max_size. Raise both in php-fpm.conf and restart (see Uploads and sessions above).