Skip to content

PHP

Railpack can automatically build and deploy PHP applications with FrankenPHP, a modern and efficient PHP application server.

Your project will be detected as a PHP application if any of these conditions are met:

  • An index.php file exists in the root directory
  • A composer.json file exists in the root directory

The PHP version is determined in the following order:

  • Read from the composer.json file
  • Defaults to 8.4

Only PHP 8.2 and above are supported.

Railpack will configure FrankenPHP for your application. For Laravel applications, the document root is set to the public directory.

Variable Description Example
RAILPACK_PHP_ROOT_DIR Override the document root /app/public
RAILPACK_PHP_EXTENSIONS Additional PHP extensions to install gd,imagick,redis
RAILPACK_SKIP_MIGRATIONS Disable running Laravel migrations (default: false) true

Railpack uses default Caddyfile and php.ini configuration files. You can override these by placing your own versions in your project root:

  • /Caddyfile - Custom Caddy server configuration
  • /php.ini - Custom PHP configuration

The application is started using a start-container.sh script that:

  • For Laravel applications:
    • Runs database migrations and seeding (enabled by default, can be disabled with RAILPACK_SKIP_MIGRATIONS)
    • Creates storage symlinks
    • Optimizes the application
  • Starts the FrankenPHP server using the Caddyfile configuration

You can customize the startup process by placing your own start-container.sh in the project root.

PHP extensions are automatically installed based on:

  • Requirements specified in composer.json (e.g., ext-redis)
  • Extensions listed in the RAILPACK_PHP_EXTENSIONS environment variable

Example composer.json with required extensions:

composer.json
{
"require": {
"php": ">=8.2",
"ext-pgsql": "*",
"ext-redis": "*"
}
}

Railpack normally normally installs build and deploy apt packages on different images. However, PHP uses the FrankenPHP image for both the build and the final image, instead of the standard railpack runtime base because mise does not support precompiled PHP binaries natively.

buildAptPackages and deploy.aptPackages are therefore installed together on the FrankenPHP image. ... entries from apt package lists are removed, and combined list of build and deploy packages are available in the final deploy image.

Packages added for Composer (git, zip, unzip, and ca-certificates) stay installed.

For example:

railpack.json
{
"$schema": "https://schema.railpack.com",
"buildAptPackages": ["libpng-dev"],
"deploy": {
"aptPackages": ["jq", "ffmpeg"]
}
}

Will result in libpng-dev, jq, and ffmpeg in the final deploy image.

Laravel applications are detected by the presence of an artisan file. When detected:

  • The document root is set to the /app/public directory
  • Storage directory permissions are set to be writable
  • Composer dependencies are installed
  • Artisan caches are optimized at build time:
    • Configuration cache
    • Event cache
    • Route cache
    • View cache

If a package.json file is detected in your PHP project:

  • Node.js will be installed
  • NPM dependencies will be installed
  • Build scripts defined in package.json will be executed
  • Development dependencies will be pruned in the final image

This is particularly useful for Laravel applications that use frontend frameworks like Vue.js or React.

You can see the node docs for information on how to configure node.

The PHP provider will cache /opt/cache/composer under the cache key composer.