This Ansible role is designed to install and configure PHP on Debian, by default it installs PHP packaged by Ondřej Surý from deb.sury.org, but it can also be used to install and configure PHP packages from Debian.
This role is tested using molecule via GitLab CI on Debian Bookworm using three molecule senarios, firstly by installing and configuring the Debian Bookworm PHP CLI Server API (SAPI), secondly installing the Debian Bookworm FPM SAPI and finally installing the Ondřej Surý packages and enabling and starting PHP-FPM pools for PHP 7.4, 8.0, 8.1, 8.2, 8.3, 8.4 and 8.5.
This role enforces unique PHP-FPM pool names across all versions of PHP as this enables better monitoring, by default the www pools are renamed to www82, www81 etc.
The safe way to run this role is incrementally using --diff -C to diff and check what changes are to be made:
- Run with the
php_apttag to update the apt repo configuration, this supports check mode. - Run with the
php_pkgtag to update the packages, this doesn't support check mode. - Run with the
php_modstags to updates SAPI mods enabled and mods disabled. - Run with the
php_cfgtag to update the PHP configuration, this supports check mode. - Run with the
phptag to update everything.
This role supports having all the PHP settings in Ansible, to read existing config files and convert them into YAML you can do something like this:
cat /etc/php/8.2/fpm/php.ini | jc --ini -p | yq -o=yaml -PThis role can be used to remove config from CONF / INI files using conf_absent with php_config however it is probably better to template files with the config required when there are variables to remove.
NOTE When installing multiple versions of PHP-FPM at the same time the package configuration will fail as the www pools for each version will listen on the same port and conflict, when this happens the role can be used to fix the pool names something like this:
ansible-playbook all.yml -t php_cfg -l example.org --extra-vars "php_fpm_pool_check_fail=false"See the defaults/main.yml file for the default variables, the vars/main.yml file for the preset variables and the meta/argument_specs.yml file for the variable specification.
This role has two required boolean variables, php and php_fpm_pool_check_fail, two optional boolean variables, php_check_legacy_variables, php_sury and php_verify and three optional lists, php_config, php_modules and php_versions, see the meta/argument_specs.yml for all the variables.
The php variable is required to be defined, by default it is false, when it is true all tasks in this role will be run.
The optional php_check_legacy_variables variable is true by default, this results in the role failing if any variables names from older versions of this role are defined, set it to false to skip these checks.
The php_config is combined with the php_default_config from vars/main.yml to produce the php_combined_config and this is use by the role for PHP configuration.
The optional php_config list is used to specify the state of the PHP configuration, it enables the editing, generating and removal of PHP .conf and .ini files.
Each item in the list requires a state, which can be absent or present and a version which must be a string from this list of PHP versions:
- "8.5"
- "8.4"
- "8.3"
- "8.2"
- "8.1"
- "8.0"
- "7.4"
- "7.3"
- "7.2"
- "7.1"
- "7.0"
- "5.6"Optional item variables are name and files, which is used to define the PHP version configuration state.
The files dictionary requires a path and state for each file, the state can be one of four options:
- absent
- edited
- present
- templatedThe edited state can only be used for existing files, it enables the Ansible ini module to be used to edit configuration files without the need to template them, using a optional dictionary that is converted into a INI dictionary for the configuration to be present and a conf_absent optional dictionary that is converted into a INI dictionary for the configuration to be absent.
The present state will result in existing files being edited and not existing files to be templated.
The templated state can be used to generate new configuration files and to remove configuration through only specifing the configuration to be present.
File configuration is defined using a conf dictionary for edited and templated states and conf_absent for edited states.
An example php_config dictionary, these settings will be combined with the php_default_config:
php_config:
- name: PHP 8.5 configuration
version: "8.5"
state: absent
files: []
- name: PHP 8.4 configuration
version: "8.4"
state: absent
files: []
- name: PHP 8.3 configuration
version: "8.3"
state: absent
files: []
- name: PHP 8.3 configuration
version: "8.3"
state: present
files:
- name: PHP 8.3 FPM configuration
path: /etc/php/8.3/fpm/php.ini
state: edited
conf:
apc:
"apc.enabled": "1"
Date:
"date.timezone": "Europe/London"
opcache:
"opcache.memory_consumption": "2048"
- name: PHP 8.1 configuration
version: "8.1"
state: absent
files: []
- name: PHP 8.0 configuration
version: "8.0"
state: absent
files: []
- name: PHP 7.4 configuration
version: "7.4"
state: absent
files: []The compulsory php_fpm_pool_check_fail variable defaults to true, set it to false to allw this role to run when duplicate PHP-FPM pool names are found on the server, once this role has updated the poool names to ensure that are unique it can be set back to true.
The php_modules is combined with the php_default_modules from vars/main.yml to produce the php_combined_modules and this is use by the role for PHP module configuration.
The optional php_modules list can be used to enable and disable PHP modules using phpmyquery, which adds and removes symlinks in the apache2/conf.d, cli/conf.d and fpm/conf.d directories which point to .ini files in the mods-available directory for each version of PHP.
Each item in the list requires a state, which can be absent or present and a version which must be a string from this list of PHP versions:
- "8.5"
- "8.4"
- "8.3"
- "8.2"
- "8.1"
- "8.0"
- "7.4"
- "7.3"
- "7.2"
- "7.1"
- "7.0"
- "5.6"Plus a lists of sapis, each item of which requires an sapi, which can be one of apache2, cli or fpm and an optional mods_enabled and mods_disabled list.
An example php_modules dictionary, these settings will be combined with the php_default_modules:
php_modules:
- name: PHP 8.5 modules
version: "8.5"
state: absent
sapis: []
- name: PHP 8.4 modules
version: "8.4"
state: absent
sapis: []
- name: PHP 8.3 modules
⦙ version: "8.3"
⦙ state: present
⦙ sapis:
⦙ ⦙ - name: PHP 8.3 CLI modules
⦙ ⦙ ⦙ sapi: cli
⦙ ⦙ ⦙ mods_enabled:
⦙ ⦙ ⦙ ⦙ - apcu
⦙ ⦙ ⦙ ⦙ - mysqli
- name: PHP 8.1 modules
version: "8.1"
state: absent
sapis: []
- name: PHP 8.0 modules
version: "8.0"
state: absent
sapis: []
- name: PHP 7.4 modules
version: "7.4"
state: absent
sapis: []The optional php_sury variable is true by default which results in the Debian PHP repo provided by Ondřej Surý being enabled for installing .deb packages. When php_sury is false the Ondřej Surý repo configuration is removed if present.
The optional php_verify variable is true by default which results in all variables that start with php_ being checked using the meta/argument_specs.yml, this is a stricter check than Ansible uses by default as non-defined variables, such as php_foo cause the verification to fail.
The php_versions is combined with the php_default_versions from vars/main.yml to produce the php_combined_versions and this is use by the role for PHP package configuration.
The optional php_versions list is used to install and remove PHP packages, each item in the list requires a state, which can be absent or present and a version which must be a string from this list of PHP versions:
- "8.5"
- "8.4"
- "8.3"
- "8.2"
- "8.1"
- "8.0"
- "7.4"
- "7.3"
- "7.2"
- "7.1"
- "7.0"
- "5.6"Two optional lists, pkg_absent and pkg_present are used to list .deb packages that are to be installed or removed.
An example php_version dictionary, these settings will be combined with the php_default_versions:
php_versions:
- name: PHP 8.5 packages
version: "8.5"
state: absent
pkg_absent: []
pkg_present: []
- name: PHP 8.4 packages
version: "8.4"
state: absent
pkg_absent: []
pkg_present: []
- name: PHP 8.3 packages
version: "8.3"
state: present
pkg_absent:
- libapache2-mod-php8.3
pkg_present:
- php8.3-apcu
- name: PHP 8.2 packages
version: "8.2"
state: absent
pkg_absent: []
pkg_present: []
- name: PHP 8.1 packages
version: "8.1"
state: absent
pkg_absent: []
pkg_present: []
- name: PHP 8.0 packages
version: "8.0"
state: absent
pkg_absent: []
pkg_present: []
- name: PHP 7.4 packages
version: "7.4"
state: absent
pkg_absent: []
pkg_present: []Reinstall a package and the configuration files when they have been deleted (see serverfault comment):
UCF_FORCE_CONFFMISS=1 apt-get -o Dpkg::Options::="--force-confmiss" install --reinstall "php8.1-fpm"The primary URL of this repo is https://git.coop/webarch/php however it is also mirrored to GitHub and available via Ansible Galaxy.
If you use this role please use a tagged release, see the release notes.
This repo had the master branch set to the default until June 2023, then the sury branch that was used to refactor the role to support the Debian packages built and provided by Ondřej Surý, was renamed to main and made the default.
In June 2021 this role was renamed from phpfpm to php and the URL of the git repo was updated to match, at the same time the git repo that was at https://git.coop/webarch/php was archived to git.coop/webarch/php7.
Copyright 2019-2025 Chris Croome, <chris@webarchitects.co.uk>.
This role is released under the same terms as Ansible itself, the GNU GPLv3.