PHP on Scalingo

Detection

Your application is detected as a PHP application if:

  • a composer.lock file is present in the root directory of your project
  • or if an index.php file is present in the root directory of your project (Classic app)

Stack

A stack based on Nginx and PHP-FPM is installed.

Default Configuration

The default configuration for your application is stored in two files, both available in the PHP buildpack:

Reviewing them can give you useful inputs, such as the default values for parameters like upload_max_filesize or post_max_size.

PHP Versions

Availability

The following PHP versions are available:

PHP Version scalingo-20 scalingo-22
7.4 up to 7.4.32 unsupported
8.0 up to 8.0.30 unsupported
8.1 up to 8.1.27 up to 8.1.27
8.2 up to 8.2.16 up to 8.2.16
8.3 up to 8.3.3 up to 8.3.3

Select a Version

The default PHP version on both scalingo-20 and scalingo-22 is the latest 8.1 version. If you need to install another version, specify it in your composer.json file. For example, to install the latest PHP version of the 8.2 branch:

{
  "require": {
    "php": "~8.2"
  }
}

PHP Extensions and Dependencies

See our dedicated documentation pages:

Supported Frameworks

Here is a non-exhaustive list of frameworks known to work on Scalingo:

Configuration Tweaks

Setup Basic Authentication

You may want to hide your application behind an authentication gateway. You can configure HTTP basic auth for your application.

PHP-FPM Concurrency

The level of concurrency configured is defined automatically according to the size of the containers of your application. If you want to override this value, you can define the environment variable: WEB_CONCURRENCY. It directly modifies the pm.max_children parameter of PHP-FPM, defining the upper limit of how many workers handling incoming requests will be running. Each of these processes will be able to run 1 request at a time.

The default values for pm.max_children are based on the memory_limit parameter of the PHP configuration, the used formula is: floor(available_memory / php_memory_limit) + 2

Container Size Default Concurrency
S 3
M 3
L 7
XL 12
2XL 22
3XL 43

Concurrency Fine Tuning

Fine tuning the value of the WEB_CONCURRENCY environment variable is a bit tricky and must be handled with care. There is no magic formulae and one must load test his application to find the best value matching his use case. If the application is swapping, you might need to lower the value of WEB_CONCURRENCY and increase the amount of containers. On the contrary, if your application does not use all his memory, one can try to slightly increase the WEB_CONCURRENCY value and make sure the application does not start swapping.

Note that if the WEB_CONCURRENCY value is too high your application will not be 100% available. You will see at some point the following error message in your application logs, multiple times:

connect() to unix:/tmp/php-fpm.sock failed (11: Resource temporarily
unavailable) while connecting to upstream, client: XXX.XXX.XXX.XXX, server:
localhost, request: "GET / HTTP/1.1", upstream:
"fastcgi://unix:/tmp/php-fpm.sock:", host: "example.com"

It happens when the PHP-FPM requests queue is full. Restarting your application empties this requests queue and makes your application back up. Then you should improve the value of the WEB_CONCURRENCY value.

Buildpack Custom Configuration

The buildpack allows you to configure precisely how your application is deployed. This configuration is done in your composer.json at the root of your project.

All these fields are optional, define them if you need to modify their default value.

{
   // Your content
  "extra": {
    // default values of PaaS specific instructions
    "paas": {
      "document-root": "",
      "index-document": "index.php",
      "engines": {
        "nginx": "default"
      },
      "framework": "",
      "php-config": [],
      "php-includes": [],
      "php-fpm-config": [],
      "php-fpm-includes": [],
      "nginx-includes": [],
      "log-files": [],
      "compile": [],
      "new-relic": false,
      "access-log-format": ""
    }
  }
}

.extra.paas.document-root

The directory where Nginx will define the root of your app.

This parameter can also be overridden with the DOCUMENT_ROOT environment variable.

.extra.paas.framework

Bypass framework detection by specifying the framework you want. It could also be useful if you need to specify your application does not use any framework. This is done by specifying default in the .extra.paas.framework configuration.

.extra.paas.index-document

Name of the index document of each directory. When accessing a directory (https://example.osc-fr1.scalingo.io/web/), Nginx looks by default for an index.php file to execute, if your project is using another name, specify it here.

.extra.paas.engines.composer

Define a specific version of Composer to use. By default your application uses the latest Composer version available. Most of the time, you don’t need to change this value.

.extra.paas.engines.nginx

Define a precise version of Nginx to use. By default your application is reachable through the last stable version of the server. Most of the time, you don’t need to change this value.

Scalingo supports the following versions of Nginx:

Nginx version scalingo-20 scalingo-22
1.15 Up to 1.15.12 Unsupported
1.16 Up to 1.16.0 Unsupported
1.17 Up to 1.17.10 Unsupported
1.18 Up to 1.18.0 Unsupported
1.19 Up to 1.19.10 Unsupported
1.20 Up to 1.20.2 Unsupported
1.21 Up to 1.21.6 Up to 1.21.6
1.22 Up to 1.22.1 Up to 1.22.1

.extra.paas.php-config

List of directives which will be added to your php.ini. The default values used for your application are in the buildpack’s php.ini.

Example:

{
  "php-config": [
    "display_errors=off",
    "short_open_tag=on"
  ]
}

.extra.paas.php-fpm-config

List of directives which will be added to your php-fpm.ini.

Example:

{
  "php-fpm-config": [
    "log_level=debug"
  ]
}

.extra.paas.php-includes

Extra files which will be included in the php.ini.

.extra.paas.php-fpm-includes

Extra files which will be included in the php-fpm.ini.

.extra.paas.nginx-http-includes

Extra files which will be included in the Nginx configuration of your application. These files are injected at the http scope of the configuration file.

.extra.paas.nginx-includes

Extra files which will be included in the Nginx configuration of your application. These files are injected at the server scope of the configuration file.

.extra.paas.compile

Commands to run after the dependency installation.

Example:

{
  "compile": [
    "php app/console assetic:dump --env=prod --no-debug"
  ]
}

.extra.paas.log-files

If your project is writing in custom log files, you can specify them here and they will be streamed to the logs of your application.

Your can read the logs on your dashboard or with the Scalingo CLI utility.

.extra.paas.datadog

To enable Datadog support, set the extra.paas.datadog property to true. It makes the following Datadog products available:

  • Datadog APM (Application Performance Monitoring)
  • Datadog ASM (Application Security Management)

This automatically installs the latest available version of the Datadog Tracer and enables APM. To disable the tracer, set the DATADOG_TRACER_VERSION environment variable to 0 (latest by default). Note that disabling the tracer will also disable APM and ASM.

The Datadog ASM (Application Security Management) extension is disabled by default. To install and enable ASM, set the DATADOG_APPSEC_VERSION environment variable to latest (0 by default).

.extra.paas.new-relic

If true, enable New Relic instrumentation tools.

The environment variable named NEW_RELIC_LICENSE_KEY is required.

It is also highly recommended to include the NEW_RELIC_APP_NAME environment variable to specify the name of the application as displayed in the New Relic UI.

.extra.paas.scout

If true, enable Scout APM support.

You may want to use the environment variable SCOUT_APM_VERSION to install a specific version of the PECL extension.

.extra.paas.access-log-format

The format of the logs produced by the proxy Nginx for each request to your application.

It is empty by default, it means that Nginx will use the following format:

'$http_x_forwarded_for - "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent"'

e.g.

109.26.203.98 - "GET / HTTP/1.1" 200 1761 "https://google.com/search" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:51.0) Gecko/20100101 Firefox/51.0"

When defining a custom value for the log format, please refer to the Nginx documentation page..

This parameter can also be overridden with the ACCESS_LOG_FORMAT environment variable.

Warning: .htaccess Files

Classic PHP applications often use .htaccess file in their project to modify the configuration of the Apache server. As the buildpack is based on Nginx and PHP-FPM, these files are ineffective.

Instead of using these files, you have to write directives for Nginx and configure the nginx-includes part of your composer.json. It can contains one or more configuration files:

{
  
  "extra": {
    "paas": {
      "nginx-includes": ["path/to/nginx_conf_file", ]
    }
  }
}

Example: Configuring Rate Limiting

In the following example we will set a rate limit of one request per second per IP.

Create a nginx-http.conf file at the root of your project:

limit_req_zone $binary_remote_addr zone=mylimit:10m rate=1r/s;

Then create a nginx-app.conf file at the root of your project:

location /login {
    limit_req zone=mylimit;
    try_files $uri $uri/ /index.php?$query_string;
}

Then modify your composer.json to add nginx-http-includes and nginx-includes config:

{
  "extra": {
    "paas": {
      "nginx-http-includes": ["nginx-http.conf"],
      "nginx-includes": ["nginx-app.conf"]
    }
  }
}

Example: URL Rewriting (e.g. WordPress)

Here is an example of classic .htaccess which won’t work on Scalingo. You need to replace it with the Nginx configuration following the example.

Classic .htaccess example:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

Nginx configuration:

location / {
  try_files $uri $uri/ /index.php?$args;
}

Suggest edits

PHP on Scalingo

©2024 Scalingo