PHP on Scalingo
Detection
Your application will be detected as a PHP application if:
- There is a
composer.lock
file at the root of your project -
index.php
is present in the root directory (legacy app)
Stack
A stack based on Nginx and PHP-FPM will be installed.
Default Configuration
The default configuration for your application is defined in the buildpack’s
php.ini and
php-fpm.ini. You can
see on these files the configuration for parameters such as upload_max_filesize
and post_max_size
.
PHP Versions
Compatibility
The following PHP versions are compatible with the platform:
- 7.0 (up to 7.0.33, only for scalingo-18)
- 7.1 (up to 7.1.33, only for scalingo-18)
- 7.2 (up to 7.2.34, only for scalingo-18)
- 7.3 (up to 7.3.33, only for scalingo-18)
- 7.4 (up to 7.4.32, only for scalingo-18 and scalingo-20)
- 8.0 (up to 8.0.28, only for scalingo-18 and scalingo-20)
- 8.1 (up to 8.1.17)
- 8.2 (up to 8.2.4)
Select a Version
By default, the latest 7.4 version of PHP will be installed, if you need to install
a precise version it should be mentioned in your composer.json
file.
Example to install the latest PHP version from the 8.0
branch:
{
"require": {
"php": "^8.0"
}
}
It installs the version 8.0.25 at the time of writing.
Composer
Composer is the official package manager for PHP. The official website is here. It aims at handling the dependency management of your application: installing dependencies and freezing their versions.
If composer is used in a project, the deployment system will detect it and use it to install the dependencies of the project.
composer.json
This file defines the different dependencies used by your application. It is also used to configure custom deployment settings for the project (see below).
composer.lock
Once the third-party libraries have been defined, their versions need to be
frozen in order to ensure a precise version of the application will always
deploy a compatible set of Composer packages. These versions will be written in
a compose.lock
file. This file is required as it is read during the
deployment on the platform.
To generate compose.lock
you need to run:
$ composer install
When you need to upgrade a library, for instance slim
:
$ composer update slim/slim
After each command, the composer.lock
file will be updated automatically, do
not forget to commit the modifications of the file.
Private Dependency
If you want to install a private dependency, you need to define the COMPOSER_AUTH
environment variable on your application as specified in the Composer documentation. For instance, for a GitHub hosted private dependency, the COMPOSER_AUTH
environment variable should contain:
{
"github-oauth": {
"github.com": "MY-TOKEN"
}
}
MY-TOKEN
must be replaced with a valid token of your GitHub account.
Composer During the Deployment
It is considered that when an application is deployed on Scalingo, it is run in
“production” mode. As a result, composer install
is run with the flag
--no-dev
.
If, in order to debug an application, development dependencies should be installed, please set the following environment variable:
COMPOSER_DEV=true
Select a Composer Version
You can select the Composer version to install for your application deployment by specifying it in your composer.json
:
{
"extra": {
"paas": {
"engines": {
"composer": "1.x"
}
}
}
}
Scalingo supports the following versions of Composer:
- 2.2.18
- 2.3.10
- 2.4.4
- 2.5.5
Native PHP Extensions
Applications might require native PHP extensions, these extensions are usually
written in C and need to be compiled as shared libraries (.so
files) and be
used by PHP.
Some of them are bundled by default with the deployed version of PHP, the
others are installed dynamically if specified in the project composer.json
.
Native Extension Dependency
If an application requires a native PHP extension, it should be added in the
require
block of its composer.json
:
{
"require": {
"ext-mongodb": "*",
"ext-imagick": "*",
...
}
}
These dependency instructions are parsed by the deployment system which will install the require files.
List of Pre-Installed Extensions
These extensions are available by default with the installed version of PHP:
- Databases:
mysql
,mysqli
,pgsql
,pdo-mysql
,pdo-pgsql
, - Compression:
bz2
,zlib
,zip
- Web services:
soap
- XML manipulation:
xmlreader
- String encoding:
mbstring
- Process control:
pcntl
- Socket management:
sockets
- Math functions:
bcmath
- Images manipulation:
gd
- Intl (Internationalization):
intl
List of Available Extensions
These extensions will be installed dynamically if required in the composer.json
file.
- APC User Cache:
apcu
- MongoDB Driver:
mongodb
- MongoDB Legacy Driver:
mongo
, obsolete, only PHP 5.6 - Redis Driver:
redis
- Image manipulation with ImageMagick:
imagick
- Memcached driver:
memcached
- Event :
event
- GMP Multiple Precisions math functions:
gmp
- FTP Client:
ftp
- IMAP:
imap
- Tidy:
tidy
- Calendar:
calendar
- Data Structures:
ds
, incompatible with PHP 8.0 and above - Lua:
lua
, incompatible with PHP 8.0 and above - Gettext:
gettext
- mcrypt:
mcrypt
, automatically installed with all apps with PHP 7.1 and before. External dependency starting with PHP 7.2. - Sodium
sodium
, incompatible with PHP 7.1 and below - Always Populate Form Data
apfd
- Extension’s missing: contact us, the support for it will be added quickly
Officially Supported Frameworks
Scalingo supports out-of-the-box many well-known frameworks. When using such
frameworks, you have nothing special to configure in your composer.json
,
git push
your code and everything will work!
List of the frameworks:
- Symfony from 2 to 5
- Laravel
- Lumen
- Zend Framework 2
- Magento
- Slim
- Silex
- CakePHP 2 (up to PHP 7.3)
- Change 2
- CodeIgniter 3
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:
- 1.14.2
- 1.15.8
- 1.16.1
- 1.17.6
- 1.18.0
- 1.19.10
- 1.20.1
- 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.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.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 "http://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
Legacy projects 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 legacy .htaccess
which won’t work on Scalingo. You need
to replace it with the Nginx configuration following the example.
Legacy .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;
}