From e9dae1dd0be0d904492f6b0ed6d2307ae894eba6 Mon Sep 17 00:00:00 2001 From: Ludovic Cartier Date: Wed, 24 Sep 2025 14:59:40 +0200 Subject: [PATCH] add vhost template and tasks --- README.md | 145 +++++++++++++++++++++++++++++++++++++++-- defaults/main.yml | 50 +++++++++----- tasks/fpm_pools.yml | 35 ++++++++++ tasks/main.yml | 3 + templates/pool.conf.j2 | 40 ++++++++++++ 5 files changed, 251 insertions(+), 22 deletions(-) create mode 100644 tasks/fpm_pools.yml create mode 100644 templates/pool.conf.j2 diff --git a/README.md b/README.md index f55781c..06a7f50 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,15 @@ # PHP Ansible Role -This Ansible role installs and configures PHP with support for multiple versions and custom modules for each version. +This Ansible role installs and configures PHP with support for multiple versions, custom modules, and PHP-FPM pool configurations. ## Features - Install multiple PHP versions simultaneously (e.g., PHP 8.3 and 8.4) - Install single PHP version (just provide one version in the list) - Configure different module lists for each PHP version +- Create and manage PHP-FPM pools with custom configurations +- Support for multiple pools across different PHP versions +- Automatic log directory creation with proper ownership - Support for PHP-FPM - Automatic repository setup (Sury repository for latest PHP versions) @@ -18,7 +21,7 @@ This Ansible role installs and configures PHP with support for multiple versions ## Role Variables -### Configuration +### PHP Installation Configuration ```yaml php_versions: @@ -31,13 +34,132 @@ php_versions: - zip - version: "8.4" modules: - - -mysql + - mysql - gd - xml + - mbstring + - zip - redis - - ip ``` +### PHP-FPM Pool Configuration + +```yaml +php_pools: + - name: "www" + user: "www-data" + group: "www-data" + php_versions: + - version: "8.3" + - version: "8.4" + # Pool management settings + pm: "dynamic" + pm_start_servers: 5 + pm_min_spare_servers: 3 + pm_max_spare_servers: 8 + pm_max_children: 100 + pm_max_requests: 200 + # Timeouts and limits + request_slowlog_timeout: "30s" + request_terminate_timeout: "60s" + rlimit_files: 65536 + catch_workers_output: "yes" + # PHP settings + admin_flag_display_errors: "Off" + admin_flag_log_errors: "On" + admin_value_error_reporting: "E_ALL & ~E_NOTICE" + admin_value_memory_limit: "64M" + admin_value_upload_max_filesize: "16M" + admin_value_post_max_size: "16M" + +# Remove default www pool +php_remove_default_pool: false +``` + +## Example Playbooks + +### Multi-Version Setup with Custom Pools + +```yaml +--- +- hosts: webservers + become: yes + vars: + php_versions: + - version: "8.3" + modules: + - mysql + - gd + - xml + - mbstring + - zip + - version: "8.4" + modules: + - mysql + - gd + - xml + - mbstring + - zip + - redis + + php_pools: + - name: "app1" + user: "app1" + group: "app1" + php_versions: + - version: "8.3" + pm: "static" + pm_max_children: 50 + admin_value_memory_limit: "128M" + + - name: "app2" + user: "app2" + group: "app2" + php_versions: + - version: "8.4" + pm: "dynamic" + pm_max_children: 100 + admin_value_memory_limit: "256M" + + php_remove_default_pool: true + roles: + - php +``` + +### Single Version with Simple Pool + +```yaml +--- +- hosts: webservers + become: yes + vars: + php_versions: + - version: "8.4" + modules: + - mysql + - gd + + php_pools: + - name: "website" + user: "www-data" + group: "www-data" + php_versions: + - version: "8.4" + roles: + - php +``` + +## Pool Configuration Details + +Each pool configuration creates: + +- **Socket file**: `/run/php/php{version}-fpm-{pool_name}.sock` +- **Log directories**: `/var/log/php/{pool_name}/{version}/` +- **Error log**: `/var/log/php/{pool_name}/{version}/php-errors.log` +- **Slow log**: `/var/log/php/{pool_name}/{version}/php-slow.log` + +The pool configuration supports all standard PHP-FPM pool directives with sensible defaults. + ## Installed Packages For each PHP version, the following base packages are automatically installed: @@ -47,12 +169,21 @@ For each PHP version, the following base packages are automatically installed: Additional modules are installed based on the `modules` list for each version. +## Services + +The role will manage PHP-FPM services for each installed version: +- `php8.3-fpm` +- `php8.4-fpm` +- etc. + ## Notes - The role uses the Sury repository to provide the latest PHP versions -- Each PHP version runs its own FPM service on different sockets/ports -- Module names should include the PHP version prefix (e.g., `php8.3-mysql`) -- For single version installations, just provide one entry in the `php_versions` list +- Each PHP version runs its own FPM service +- Module names are simplified (e.g., `mysql` instead of `php8.3-mysql`) +- Log directories are automatically created with proper ownership +- Pool sockets are created with specific naming: `php{version}-fpm-{pool_name}.sock` +- You can create multiple pools for the same PHP version with different configurations ## License diff --git a/defaults/main.yml b/defaults/main.yml index c459089..56047ff 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -1,16 +1,36 @@ --- -# php_versions: -# - version: "8.3" -# modules: -# - php8.3-mysql -# - php8.3-gd -# - php8.3-xml -# - php8.3-mbstring -# - php8.3-zip -# - version: "8.4" -# modules: -# - php8.4-mysql -# - php8.4-gd -# - php8.4-xml -# - php8.4-mbstring -# - php8.4-zip +php_sapi: fpm + +php_versions: + - version: "8.4" + modules: + - curl + - opcache + +php_pools: + - name: "www" + user: "www-data" + group: "www-data" + php_versions: + - version: "8.4" + # Pool management settings + pm: "dynamic" + pm_start_servers: 5 + pm_min_spare_servers: 3 + pm_max_spare_servers: 8 + pm_max_children: 100 + pm_max_requests: 200 + # Timeouts and limits + request_slowlog_timeout: "30s" + request_terminate_timeout: "60s" + rlimit_files: 65536 + catch_workers_output: "yes" + # PHP settings + admin_flag_display_errors: "Off" + admin_flag_log_errors: "On" + admin_value_error_reporting: "E_ALL & ~E_NOTICE" + admin_value_memory_limit: "64M" + admin_value_upload_max_filesize: "16M" + admin_value_post_max_size: "16M" + +php_remove_default_pool: false diff --git a/tasks/fpm_pools.yml b/tasks/fpm_pools.yml new file mode 100644 index 0000000..6028190 --- /dev/null +++ b/tasks/fpm_pools.yml @@ -0,0 +1,35 @@ +--- +- name: php | create php log directories for pools + file: + path: "/var/log/php/{{ item.0.name }}/{{ item.1.version }}" + state: directory + owner: "{{ item.0.user | default('www-data') }}" + group: "{{ item.0.group | default('www-data') }}" + mode: '0755' + recurse: yes + loop: "{{ php_pools | subelements('php_versions') }}" + when: php_pools is defined and php_pools | length > 0 + +- name: php | create php-fpm pool configurations + template: + src: pool.conf.j2 + dest: "/etc/php/{{ item.1.version }}/fpm/pool.d/{{ item.0.name }}.conf" + owner: root + group: root + mode: '0644' + backup: yes + loop: "{{ php_pools | subelements('php_versions') }}" + when: php_pools is defined and php_pools | length > 0 + notify: + - restart php-fpm services + +- name: php | remove default www pool if requested + file: + path: "/etc/php/{{ item.version }}/fpm/pool.d/www.conf" + state: absent + loop: "{{ php_versions }}" + when: + - php_remove_default_pool is defined + - php_remove_default_pool | bool + notify: + - restart php-fpm services diff --git a/tasks/main.yml b/tasks/main.yml index d7c04e9..3ba2494 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -4,3 +4,6 @@ - name: php | installation include_tasks: install.yml + +- name: php | create fpm pools + include_tasks: fpm_pools.yml \ No newline at end of file diff --git a/templates/pool.conf.j2 b/templates/pool.conf.j2 new file mode 100644 index 0000000..7006e46 --- /dev/null +++ b/templates/pool.conf.j2 @@ -0,0 +1,40 @@ +[{{ item.0.name }}] + +user = {{ item.0.user | default('www-data') }} +group = {{ item.0.group | default('www-data') }} + +listen = /run/php/php{{ item.1.version }}-fpm-{{ item.0.name }}.sock +listen.owner = {{ item.0.user | default('www-data') }} +listen.group = www-data +listen.mode = 0660 +listen.backlog = -1 + +pm = {{ item.0.pm | default('dynamic') }} +pm.start_servers = {{ item.0.pm_start_servers | default(5) }} +pm.min_spare_servers = {{ item.0.pm_min_spare_servers | default(3) }} +pm.max_spare_servers = {{ item.0.pm_max_spare_servers | default(8) }} +pm.max_children = {{ item.0.pm_max_children | default(100) }} + +pm.max_requests = {{ item.0.pm_max_requests | default(200) }} + +pm.status_path = /status +ping.path = /ping +ping.response = pong + +request_slowlog_timeout = {{ item.0.request_slowlog_timeout | default('30s') }} +slowlog = /var/log/php/{{ item.0.name }}/{{ item.1.version }}/php-slow.log + +request_terminate_timeout = {{ item.0.request_terminate_timeout | default('60s') }} +rlimit_files = {{ item.0.rlimit_files | default(65536) }} +catch_workers_output = {{ item.0.catch_workers_output | default('yes') }} + +security.limit_extensions = .php + +;; PHP FLAGS and VALUES +php_admin_flag[display_errors] = {{ item.0.admin_flag_display_errors | default('Off') }} +php_admin_flag[log_errors] = {{ item.0.admin_flag_log_errors | default('On') }} +php_admin_value[error_log] = /var/log/php/{{ item.0.name }}/{{ item.1.version }}/php-errors.log +php_admin_value[error_reporting] = {{ item.0.admin_value_error_reporting | default('E_ALL & ~E_NOTICE') }} +php_admin_value[memory_limit] = {{ item.0.admin_value_memory_limit | default('64M') }} +php_admin_value[upload_max_filesize] = {{ item.0.admin_value_upload_max_filesize | default('16M') }} +php_admin_value[post_max_size] = {{ item.0.admin_value_post_max_size | default('16M') }} \ No newline at end of file