From aac65b18d3e266bfcb0ed4e740886175b0cb9796 Mon Sep 17 00:00:00 2001 From: Greg Harvey Date: Wed, 3 Apr 2024 17:05:01 +0200 Subject: [PATCH 1/4] Moving SSL handling to a separate tasks file. --- docs/roles/debian/nginx.md | 2 +- roles/debian/nginx/README.md | 2 +- roles/debian/nginx/tasks/domain.yml | 59 +-------------------------- roles/debian/nginx/tasks/main.yml | 33 ++++++++------- roles/debian/nginx/tasks/ssl.yml | 63 +++++++++++++++++++++++++++++ 5 files changed, 85 insertions(+), 74 deletions(-) create mode 100644 roles/debian/nginx/tasks/ssl.yml diff --git a/docs/roles/debian/nginx.md b/docs/roles/debian/nginx.md index 4751e36bc..0241cbbcd 100644 --- a/docs/roles/debian/nginx.md +++ b/docs/roles/debian/nginx.md @@ -1,6 +1,6 @@ # NGINX -Install and configure the nginx webserver. +Install and configure the NGINX webserver. Note, the directives are mostly DENY FIRST so if you're expecting to find config that blocks a certain file extension or pattern you should consider it the other way and ensure that pattern is not *allowed* anywhere. diff --git a/roles/debian/nginx/README.md b/roles/debian/nginx/README.md index 4751e36bc..0241cbbcd 100644 --- a/roles/debian/nginx/README.md +++ b/roles/debian/nginx/README.md @@ -1,6 +1,6 @@ # NGINX -Install and configure the nginx webserver. +Install and configure the NGINX webserver. Note, the directives are mostly DENY FIRST so if you're expecting to find config that blocks a certain file extension or pattern you should consider it the other way and ensure that pattern is not *allowed* anywhere. diff --git a/roles/debian/nginx/tasks/domain.yml b/roles/debian/nginx/tasks/domain.yml index 57c7d7b9e..3da1f900b 100644 --- a/roles/debian/nginx/tasks/domain.yml +++ b/roles/debian/nginx/tasks/domain.yml @@ -1,61 +1,4 @@ --- -- name: Temporarily place a vhost for LetsEncrypt to work. - ansible.builtin.template: - src: vhost_letsencrypt.j2 - dest: "/etc/nginx/sites-available/{{ domain.server_name }}.conf" - owner: root - group: root - mode: 0644 - when: - - domain.ssl is defined - - domain.ssl.handling == 'letsencrypt' - - domain.ssl.services | length > 0 # if services[] is defined we can assume we are running certbot on port 80 or 443 - -- name: Enable vhost. - ansible.builtin.file: - src: "/etc/nginx/sites-available/{{ domain.server_name }}.conf" - dest: "/etc/nginx/sites-enabled/{{ domain.server_name }}.conf" - state: link - when: - - domain.ssl is defined - - domain.ssl.handling == 'letsencrypt' - - domain.ssl.services | length > 0 - -- name: Reload the nginx service. - ansible.builtin.service: - name: nginx - state: reloaded - when: - - domain.ssl is defined - - domain.ssl.handling == 'letsencrypt' - - domain.ssl.services | length > 0 - -- name: Generates SSL keys. - ansible.builtin.include_role: - name: debian/ssl - public: true - when: domain.ssl is defined - vars: - ssl: "{{ domain.ssl }}" - -- name: Delete the link to the vhost for LetsEncrypt. - ansible.builtin.file: - path: "/etc/nginx/sites-enabled/{{ domain.server_name }}.conf" - state: absent - when: - - domain.ssl is defined - - domain.ssl.handling == 'letsencrypt' - - domain.ssl.services | length > 0 - -- name: Delete the temporary vhost for LetsEncrypt. - ansible.builtin.file: - path: "/etc/nginx/sites-available/{{ domain.server_name }}.conf" - state: absent - when: - - domain.ssl is defined - - domain.ssl.handling == 'letsencrypt' - - domain.ssl.services | length > 0 - # If auth_enabled is defined and yes, and auth_pass is not defined or is defined but empty, generate a random password. - name: Generate random htauth password. ansible.builtin.set_fact: @@ -119,12 +62,14 @@ owner: root group: root mode: 0644 + force: true - name: Enable vhost. ansible.builtin.file: src: "/etc/nginx/sites-available/{{ domain.server_name }}.conf" dest: "/etc/nginx/sites-enabled/{{ domain.server_name }}.conf" state: link + force: true - name: Generates AWS Cloudwatch vhost config. ansible.builtin.template: diff --git a/roles/debian/nginx/tasks/main.yml b/roles/debian/nginx/tasks/main.yml index 384fd1dad..60196bc99 100644 --- a/roles/debian/nginx/tasks/main.yml +++ b/roles/debian/nginx/tasks/main.yml @@ -1,5 +1,5 @@ --- -- name: Ensure nginx is installed. +- name: Ensure NGINX is installed. ansible.builtin.apt: name: nginx state: present @@ -29,7 +29,7 @@ packages: - name: passlib -- name: Copy main nginx config. +- name: Copy main NGINX config. ansible.builtin.template: src: nginx.conf.j2 dest: "/etc/nginx/nginx.conf" @@ -75,17 +75,10 @@ path: "/var/log/nginx" state: directory -- name: Remove existing vhosts - ansible.builtin.file: - path: "/etc/nginx/sites-enabled" - state: absent - when: nginx.recreate_vhosts - -- name: Recreate vhosts folder +- name: Ensure vhosts folder is present. ansible.builtin.file: path: "/etc/nginx/sites-enabled" state: directory - when: nginx.recreate_vhosts - name: Check if we have an AWS Cloudwatch folder. ansible.builtin.stat: @@ -99,6 +92,16 @@ when: - _nginx_cloudwatch_dir.stat.isdir is defined and _nginx_cloudwatch_dir.stat.isdir +- name: Generate SSL certificates. + ansible.builtin.include_tasks: ssl.yml + with_items: "{{ nginx.domains }}" + loop_control: + loop_var: domain + when: + - nginx.domains is defined + - nginx.domains | length > 0 + - nginx.recreate_vhosts + - name: Generate domain specific configuration. ansible.builtin.include_tasks: domain.yml with_items: "{{ nginx.domains }}" @@ -118,21 +121,21 @@ - nginx.overrides is defined - nginx.overrides | length > 0 -- name: Test Nginx configuration. +- name: Test NGINX configuration. ansible.builtin.command: nginx -t register: nginx_test_result failed_when: false -- name: Display Nginx test result. +- name: Display NGINX test result. ansible.builtin.debug: msg: "{{ nginx_test_result.stderr }}" -- name: Fail the playbook if Nginx test fails. +- name: Fail the playbook if NGINX test fails. ansible.builtin.fail: - msg: "Nginx configuration test failed." + msg: "NGINX configuration test failed." when: nginx_test_result.rc != 0 -- name: Ensure Nginx is restarted. +- name: Ensure NGINX is restarted. ansible.builtin.service: name: nginx state: restarted diff --git a/roles/debian/nginx/tasks/ssl.yml b/roles/debian/nginx/tasks/ssl.yml new file mode 100644 index 000000000..d5a755077 --- /dev/null +++ b/roles/debian/nginx/tasks/ssl.yml @@ -0,0 +1,63 @@ +--- +# If there is an existing vhost it will have LE proxy handling already. +- name: Check for an existing vhost. + ansible.builtin.stat: + path: "/etc/nginx/sites-enabled/{{ domain.server_name }}.conf" + register: _nginx_vhost_link + +- name: Temporarily place a vhost for LetsEncrypt to work. + ansible.builtin.template: + src: vhost_letsencrypt.j2 + dest: "/etc/nginx/sites-available/{{ domain.server_name }}.conf" + owner: root + group: root + mode: 0644 + when: + - domain.ssl is defined + - domain.ssl.handling == 'letsencrypt' + - _nginx_vhost_link.stat.islnk is not defined or domain.ssl.services | length > 0 # if services[] is defined we can assume we are running certbot on port 80 or 443 + +- name: Enable vhost. + ansible.builtin.file: + src: "/etc/nginx/sites-available/{{ domain.server_name }}.conf" + dest: "/etc/nginx/sites-enabled/{{ domain.server_name }}.conf" + state: link + when: + - domain.ssl is defined + - domain.ssl.handling == 'letsencrypt' + - _nginx_vhost_link.stat.islnk is not defined or domain.ssl.services | length > 0 + +- name: Reload the nginx service. + ansible.builtin.service: + name: nginx + state: reloaded + when: + - domain.ssl is defined + - domain.ssl.handling == 'letsencrypt' + - _nginx_vhost_link.stat.islnk is not defined or domain.ssl.services | length > 0 + +- name: Generates SSL keys. + ansible.builtin.include_role: + name: debian/ssl + public: true + when: domain.ssl is defined + vars: + ssl: "{{ domain.ssl }}" + +- name: Delete the link to the vhost for LetsEncrypt. + ansible.builtin.file: + path: "/etc/nginx/sites-enabled/{{ domain.server_name }}.conf" + state: absent + when: + - domain.ssl is defined + - domain.ssl.handling == 'letsencrypt' + - _nginx_vhost_link.stat.islnk is not defined or domain.ssl.services | length > 0 + +- name: Delete the temporary vhost for LetsEncrypt. + ansible.builtin.file: + path: "/etc/nginx/sites-available/{{ domain.server_name }}.conf" + state: absent + when: + - domain.ssl is defined + - domain.ssl.handling == 'letsencrypt' + - _nginx_vhost_link.stat.islnk is not defined or domain.ssl.services | length > 0 From 58147987d4eddce42fbe11f9b11e424a0a7eeaae Mon Sep 17 00:00:00 2001 From: Greg Harvey Date: Wed, 3 Apr 2024 17:51:01 +0200 Subject: [PATCH 2/4] Making more NGINX settings available for modification. --- docs/roles/debian/nginx.md | 23 +++++++++++++++ roles/debian/nginx/README.md | 23 +++++++++++++++ roles/debian/nginx/defaults/main.yml | 23 +++++++++++++++ roles/debian/nginx/tasks/main.yml | 2 ++ roles/debian/nginx/templates/_common.j2 | 29 ++++++------------- .../nginx/templates/_common_cloudfront.j2 | 10 +++---- roles/debian/nginx/templates/nginx.conf.j2 | 4 +-- 7 files changed, 87 insertions(+), 27 deletions(-) diff --git a/docs/roles/debian/nginx.md b/docs/roles/debian/nginx.md index 0241cbbcd..08130a46c 100644 --- a/docs/roles/debian/nginx.md +++ b/docs/roles/debian/nginx.md @@ -29,6 +29,29 @@ nginx: access_log: /var/log/nginx-access.log error_log: /var/log/nginx-error.log ssl_protocols: "TLSv1.2 TLSv1.3" + sendfile: "on" + keepalive_timeout: 65 + gzip_vary: "on" + gzip_types: + - text/plain + - text/css + - text/xml + - text/javascript + - application/javascript + - application/x-javascript + - application/json + - application/xml + - application/xml+rss + - application/xhtml+xml + - application/x-font-ttf + - application/x-font-opentype + - image/svg+xml + - image/x-icon + proxy_buffer_size: 512k + proxy_buffers: "8 256k" + client_body_buffer_size: 512k + fastcgi_buffer_size: 512k + fastcgi_buffers: "8 256k" # You can inject custom directives into the main nginx.conf file here by providing them as a list of strings. #custom_directives: [] # Group prefix. Useful for grouping by environments. diff --git a/roles/debian/nginx/README.md b/roles/debian/nginx/README.md index 0241cbbcd..08130a46c 100644 --- a/roles/debian/nginx/README.md +++ b/roles/debian/nginx/README.md @@ -29,6 +29,29 @@ nginx: access_log: /var/log/nginx-access.log error_log: /var/log/nginx-error.log ssl_protocols: "TLSv1.2 TLSv1.3" + sendfile: "on" + keepalive_timeout: 65 + gzip_vary: "on" + gzip_types: + - text/plain + - text/css + - text/xml + - text/javascript + - application/javascript + - application/x-javascript + - application/json + - application/xml + - application/xml+rss + - application/xhtml+xml + - application/x-font-ttf + - application/x-font-opentype + - image/svg+xml + - image/x-icon + proxy_buffer_size: 512k + proxy_buffers: "8 256k" + client_body_buffer_size: 512k + fastcgi_buffer_size: 512k + fastcgi_buffers: "8 256k" # You can inject custom directives into the main nginx.conf file here by providing them as a list of strings. #custom_directives: [] # Group prefix. Useful for grouping by environments. diff --git a/roles/debian/nginx/defaults/main.yml b/roles/debian/nginx/defaults/main.yml index f5288d2e1..f348f9eab 100644 --- a/roles/debian/nginx/defaults/main.yml +++ b/roles/debian/nginx/defaults/main.yml @@ -17,6 +17,29 @@ nginx: access_log: /var/log/nginx-access.log error_log: /var/log/nginx-error.log ssl_protocols: "TLSv1.2 TLSv1.3" + sendfile: "on" + keepalive_timeout: 65 + gzip_vary: "on" + gzip_types: + - text/plain + - text/css + - text/xml + - text/javascript + - application/javascript + - application/x-javascript + - application/json + - application/xml + - application/xml+rss + - application/xhtml+xml + - application/x-font-ttf + - application/x-font-opentype + - image/svg+xml + - image/x-icon + proxy_buffer_size: 512k + proxy_buffers: "8 256k" + client_body_buffer_size: 512k + fastcgi_buffer_size: 512k + fastcgi_buffers: "8 256k" # You can inject custom directives into the main nginx.conf file here by providing them as a list of strings. #custom_directives: [] # Group prefix. Useful for grouping by environments. diff --git a/roles/debian/nginx/tasks/main.yml b/roles/debian/nginx/tasks/main.yml index 60196bc99..65f2ae662 100644 --- a/roles/debian/nginx/tasks/main.yml +++ b/roles/debian/nginx/tasks/main.yml @@ -36,6 +36,7 @@ owner: root group: root mode: 0644 + force: true - name: Ensure passwords directory exists. ansible.builtin.file: @@ -89,6 +90,7 @@ ansible.builtin.template: src: cloudwatch-main.json.j2 dest: /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.d/nginx-main.json + force: true when: - _nginx_cloudwatch_dir.stat.isdir is defined and _nginx_cloudwatch_dir.stat.isdir diff --git a/roles/debian/nginx/templates/_common.j2 b/roles/debian/nginx/templates/_common.j2 index 1df746267..bfc0e92fc 100644 --- a/roles/debian/nginx/templates/_common.j2 +++ b/roles/debian/nginx/templates/_common.j2 @@ -5,30 +5,19 @@ gzip_proxied any; gzip_static on; gzip_http_version 1.0; gzip_disable "MSIE [1-6]\."; -gzip_vary on; +gzip_vary {{ nginx.http.gzip_vary }}; gzip_comp_level 6; gzip_types - text/plain - text/css - text/xml - text/javascript - application/javascript - application/x-javascript - application/json - application/xml - application/xml+rss - application/xhtml+xml - application/x-font-ttf - application/x-font-opentype - image/svg+xml - image/x-icon; +{% for gzip_type in nginx.http.gzip_types %} + {{ gzip_type }}{% if loop.last %};{% endif %} +{% endfor %} gzip_buffers 16 8k; gzip_min_length 512; -proxy_buffer_size 512k; -proxy_buffers 8 256k; -client_body_buffer_size 512k; -fastcgi_buffer_size 512k ; -fastcgi_buffers 8 256k ; +proxy_buffer_size {{ nginx.http.proxy_buffer_size }}; +proxy_buffers {{ nginx.http.proxy_buffers }}; +client_body_buffer_size {{ nginx.http.client_body_buffer_size }}; +fastcgi_buffer_size {{ nginx.http.fastcgi_buffer_size }} ; +fastcgi_buffers {{ nginx.http.fastcgi_buffers }} ; client_max_body_size {{ nginx.client_max_body_size }} ; # Disable content sniffing, since it's an attack vector. add_header X-Content-Type-Options nosniff; \ No newline at end of file diff --git a/roles/debian/nginx/templates/_common_cloudfront.j2 b/roles/debian/nginx/templates/_common_cloudfront.j2 index d3f395088..f448699e0 100644 --- a/roles/debian/nginx/templates/_common_cloudfront.j2 +++ b/roles/debian/nginx/templates/_common_cloudfront.j2 @@ -1,11 +1,11 @@ ### {{ ansible_managed }} gzip off; -proxy_buffer_size 512k; -proxy_buffers 8 256k; -client_body_buffer_size 512k; -fastcgi_buffer_size 512k ; -fastcgi_buffers 8 256k ; +proxy_buffer_size {{ nginx.http.proxy_buffer_size }}; +proxy_buffers {{ nginx.http.proxy_buffers }}; +client_body_buffer_size {{ nginx.http.client_body_buffer_size }}; +fastcgi_buffer_size {{ nginx.http.fastcgi_buffer_size }} ; +fastcgi_buffers {{ nginx.http.fastcgi_buffers }} ; client_max_body_size {{ nginx.client_max_body_size }} ; # Disable content sniffing, since it's an attack vector. add_header X-Content-Type-Options nosniff; \ No newline at end of file diff --git a/roles/debian/nginx/templates/nginx.conf.j2 b/roles/debian/nginx/templates/nginx.conf.j2 index 251e0dff5..f64cad774 100644 --- a/roles/debian/nginx/templates/nginx.conf.j2 +++ b/roles/debian/nginx/templates/nginx.conf.j2 @@ -14,10 +14,10 @@ http { # Basic Settings ## - sendfile on; + sendfile {{ nginx.http.sendfile }}; tcp_nopush on; tcp_nodelay on; - keepalive_timeout 65; + keepalive_timeout {{ nginx.http.keepalive_timeout }}; types_hash_max_size 2048; server_tokens off; From a993f955e8a9edbb36d3c320bd81372767ead4aa Mon Sep 17 00:00:00 2001 From: Greg Harvey Date: Wed, 3 Apr 2024 18:35:55 +0200 Subject: [PATCH 3/4] Allowing more variables to be set for PHP-FPM and the cli. --- docs/_Sidebar.md | 3 + docs/roles/debian/php-cli.md | 45 +++++++++++++ docs/roles/debian/php-common.md | 19 ++++++ docs/roles/debian/php-fpm.md | 67 +++++++++++++++++++ docs/roles/debian/php_xdebug.md | 2 +- roles/debian/php-cli/README.md | 45 +++++++++++++ roles/debian/php-cli/defaults/main.yml | 1 + roles/debian/php-cli/templates/php.cli.ini.j2 | 2 +- roles/debian/php-common/README.md | 19 ++++++ roles/debian/php-fpm/README.md | 67 +++++++++++++++++++ roles/debian/php-fpm/defaults/main.yml | 30 ++++++--- roles/debian/php-fpm/templates/php.fpm.ini.j2 | 6 +- .../php-fpm/templates/www.conf-fixedport.j2 | 10 ++- roles/debian/php-fpm/templates/www.conf.j2 | 11 ++- roles/debian/php_xdebug/README.md | 2 +- 15 files changed, 311 insertions(+), 18 deletions(-) create mode 100644 docs/roles/debian/php-cli.md create mode 100644 docs/roles/debian/php-common.md create mode 100644 docs/roles/debian/php-fpm.md create mode 100644 roles/debian/php-cli/README.md create mode 100644 roles/debian/php-common/README.md create mode 100644 roles/debian/php-fpm/README.md diff --git a/docs/_Sidebar.md b/docs/_Sidebar.md index 7e75973d1..fe73f6915 100644 --- a/docs/_Sidebar.md +++ b/docs/_Sidebar.md @@ -64,7 +64,10 @@ - [OpenVPN](/roles/debian/openvpn) - [OSSEC](/roles/debian/ossec) - [Packer](/roles/debian/packer) + - [PHP terminal client](/roles/debian/php-cli) + - [PHP common components](/roles/debian/php-common) - [PHP Composer](/roles/debian/php_composer) + - [PHP-FPM](/roles/debian/php-fpm) - [phpMyAdmin](/roles/debian/phpmyadmin) - [PHP XDebug](/roles/debian/php_xdebug) - [Postfix](/roles/debian/postfix) diff --git a/docs/roles/debian/php-cli.md b/docs/roles/debian/php-cli.md new file mode 100644 index 000000000..d8a9c8636 --- /dev/null +++ b/docs/roles/debian/php-cli.md @@ -0,0 +1,45 @@ +# PHP terminal client + +Installs and configures terminal client for PHP. + + + + + +## Default variables +```yaml +--- +php: + cli: + expose_php: "{% if _env_type == 'prod' %}Off{% else %}On{% endif %}" + error_reporting: "{% if _env_type == 'prod' %}E_ALL & ~E_DEPRECATED & ~E_STRICT{% else %}E_ALL{% endif %}" + display_errors: "{% if _env_type == 'prod' %}Off{% else %}On{% endif %}" + display_startup_errors: "{% if _env_type == 'prod' %}Off{% else %}On{% endif %}" + html_errors: "{% if _env_type == 'prod' %}Off{% else %}On{% endif %}" + engine: "On" + short_open_tag: "Off" + max_execution_time: 120 + max_input_time: 60 + max_input_nesting_level: 64 + max_input_vars: 1000 + memory_limit: -1 + log_errors_max_len: 1024 + ignore_repeated_errors: "Off" + ignore_repeated_source: "Off" + post_max_size: 200M + upload_max_filesize: 200M + max_file_uploads: 20 + date_timezone: "Europe/London" + gc_maxlifetime: 1440 + zend_assertions: -1 + overrides: {} + opcache: + enable: 1 + enable_cli: 0 + memory_consumption: 128 + max_accelerated_files: 2000 + validate_timestamps: 1 + +``` + + diff --git a/docs/roles/debian/php-common.md b/docs/roles/debian/php-common.md new file mode 100644 index 000000000..a0c7a71e3 --- /dev/null +++ b/docs/roles/debian/php-common.md @@ -0,0 +1,19 @@ +# PHP common components + +Installs and configures PHP core and required components. + + + + + +## Default variables +```yaml +--- +php: + version: + - 8.1 # see https://www.php.net/supported-versions.php + apt_origin: "origin=deb.sury.org,codename=${distro_codename}" # used by apt_unattended_upgrades + +``` + + diff --git a/docs/roles/debian/php-fpm.md b/docs/roles/debian/php-fpm.md new file mode 100644 index 000000000..b9c0edbd7 --- /dev/null +++ b/docs/roles/debian/php-fpm.md @@ -0,0 +1,67 @@ +# PHP-FPM + +Installs and configures the PHP-FPM flavour of FastCGI. + + + + + +## Default variables +```yaml +--- +php: + # see php-common for default version + fpm: + # FPM settings - official documentation is here: https://www.php.net/manual/en/install.fpm.configuration.php + unix_socket: false # set to true to use a unix socket, you must also update nginx and cachetool if you do + server_ip: "127.0.0.1" + tcp_port: "" # leave empty to automate port selection - port will be "90{{ version | replace('.','') }}" - e.g. 9081 for PHP 8.1 + pool_user: "{{ user_deploy.username }}" + pool_group: "{{ user_deploy.username }}" # if using unix socket this should be the web server user + pm: dynamic # can also be static, see https://tideways.com/profiler/blog/an-introduction-to-php-fpm-tuning + default_socket_timeout: 60 + max_children: 5 + start_servers: 2 + min_spare_servers: 1 + max_spare_servers: 3 + process_idle_timeout: 10s + max_requests: 500 + request_terminate_timeout: 0 + rlimit_core: 0 # Possible Values: 'unlimited' or an integer greater or equal to 0; Default Value: 0 + slow_log: true + request_slowlog_timeout: 0 + slowlog_file_directory: "/home/{{ user_deploy.username }}" + # PHP ini file settings + expose_php: "{% if _env_type == 'prod' %}Off{% else %}On{% endif %}" + error_reporting: "{% if _env_type == 'prod' %}E_ALL & ~E_DEPRECATED & ~E_STRICT{% else %}E_ALL{% endif %}" + display_errors: "{% if _env_type == 'prod' %}Off{% else %}On{% endif %}" + display_startup_errors: "{% if _env_type == 'prod' %}Off{% else %}On{% endif %}" + html_errors: "{% if _env_type == 'prod' %}Off{% else %}On{% endif %}" + engine: "On" + short_open_tag: "Off" + max_execution_time: 120 + max_input_time: 60 + max_input_nesting_level: 64 + max_input_vars: 1000 + memory_limit: 256M + log_errors_max_len: 1024 + ignore_repeated_errors: "Off" + ignore_repeated_source: "Off" + post_max_size: 200M + upload_max_filesize: 200M + max_file_uploads: 20 + date_timezone: "Europe/London" + gc_maxlifetime: 1440 + cookie_lifetime: 0 + zend_assertions: -1 + session_cookie_secure: "Off" + opcache: + enable: 1 + enable_cli: 0 + memory_consumption: 128 + max_accelerated_files: 2000 + validate_timestamps: 1 + +``` + + diff --git a/docs/roles/debian/php_xdebug.md b/docs/roles/debian/php_xdebug.md index 01429f1fe..f44ff859d 100644 --- a/docs/roles/debian/php_xdebug.md +++ b/docs/roles/debian/php_xdebug.md @@ -1,6 +1,6 @@ # PHP XDebug -Installs and configure XDebug extension for PHP +Installs and configures XDebug extension for PHP. diff --git a/roles/debian/php-cli/README.md b/roles/debian/php-cli/README.md new file mode 100644 index 000000000..d8a9c8636 --- /dev/null +++ b/roles/debian/php-cli/README.md @@ -0,0 +1,45 @@ +# PHP terminal client + +Installs and configures terminal client for PHP. + + + + + +## Default variables +```yaml +--- +php: + cli: + expose_php: "{% if _env_type == 'prod' %}Off{% else %}On{% endif %}" + error_reporting: "{% if _env_type == 'prod' %}E_ALL & ~E_DEPRECATED & ~E_STRICT{% else %}E_ALL{% endif %}" + display_errors: "{% if _env_type == 'prod' %}Off{% else %}On{% endif %}" + display_startup_errors: "{% if _env_type == 'prod' %}Off{% else %}On{% endif %}" + html_errors: "{% if _env_type == 'prod' %}Off{% else %}On{% endif %}" + engine: "On" + short_open_tag: "Off" + max_execution_time: 120 + max_input_time: 60 + max_input_nesting_level: 64 + max_input_vars: 1000 + memory_limit: -1 + log_errors_max_len: 1024 + ignore_repeated_errors: "Off" + ignore_repeated_source: "Off" + post_max_size: 200M + upload_max_filesize: 200M + max_file_uploads: 20 + date_timezone: "Europe/London" + gc_maxlifetime: 1440 + zend_assertions: -1 + overrides: {} + opcache: + enable: 1 + enable_cli: 0 + memory_consumption: 128 + max_accelerated_files: 2000 + validate_timestamps: 1 + +``` + + diff --git a/roles/debian/php-cli/defaults/main.yml b/roles/debian/php-cli/defaults/main.yml index 2e7efbeaa..797be3626 100644 --- a/roles/debian/php-cli/defaults/main.yml +++ b/roles/debian/php-cli/defaults/main.yml @@ -21,6 +21,7 @@ php: max_file_uploads: 20 date_timezone: "Europe/London" gc_maxlifetime: 1440 + zend_assertions: -1 overrides: {} opcache: enable: 1 diff --git a/roles/debian/php-cli/templates/php.cli.ini.j2 b/roles/debian/php-cli/templates/php.cli.ini.j2 index abdcaba6c..19230f2c4 100644 --- a/roles/debian/php-cli/templates/php.cli.ini.j2 +++ b/roles/debian/php-cli/templates/php.cli.ini.j2 @@ -1526,7 +1526,7 @@ url_rewriter.tags = "a=href,area=href,frame=src,input=src,form=fakeentry" ; Development Value: 1 ; Production Value: -1 ; http://php.net/zend.assertions -zend.assertions = -1 +zend.assertions = {{ php.cli.zend_assertions }} ; Assert(expr); active by default. ; http://php.net/assert.active diff --git a/roles/debian/php-common/README.md b/roles/debian/php-common/README.md new file mode 100644 index 000000000..a0c7a71e3 --- /dev/null +++ b/roles/debian/php-common/README.md @@ -0,0 +1,19 @@ +# PHP common components + +Installs and configures PHP core and required components. + + + + + +## Default variables +```yaml +--- +php: + version: + - 8.1 # see https://www.php.net/supported-versions.php + apt_origin: "origin=deb.sury.org,codename=${distro_codename}" # used by apt_unattended_upgrades + +``` + + diff --git a/roles/debian/php-fpm/README.md b/roles/debian/php-fpm/README.md new file mode 100644 index 000000000..b9c0edbd7 --- /dev/null +++ b/roles/debian/php-fpm/README.md @@ -0,0 +1,67 @@ +# PHP-FPM + +Installs and configures the PHP-FPM flavour of FastCGI. + + + + + +## Default variables +```yaml +--- +php: + # see php-common for default version + fpm: + # FPM settings - official documentation is here: https://www.php.net/manual/en/install.fpm.configuration.php + unix_socket: false # set to true to use a unix socket, you must also update nginx and cachetool if you do + server_ip: "127.0.0.1" + tcp_port: "" # leave empty to automate port selection - port will be "90{{ version | replace('.','') }}" - e.g. 9081 for PHP 8.1 + pool_user: "{{ user_deploy.username }}" + pool_group: "{{ user_deploy.username }}" # if using unix socket this should be the web server user + pm: dynamic # can also be static, see https://tideways.com/profiler/blog/an-introduction-to-php-fpm-tuning + default_socket_timeout: 60 + max_children: 5 + start_servers: 2 + min_spare_servers: 1 + max_spare_servers: 3 + process_idle_timeout: 10s + max_requests: 500 + request_terminate_timeout: 0 + rlimit_core: 0 # Possible Values: 'unlimited' or an integer greater or equal to 0; Default Value: 0 + slow_log: true + request_slowlog_timeout: 0 + slowlog_file_directory: "/home/{{ user_deploy.username }}" + # PHP ini file settings + expose_php: "{% if _env_type == 'prod' %}Off{% else %}On{% endif %}" + error_reporting: "{% if _env_type == 'prod' %}E_ALL & ~E_DEPRECATED & ~E_STRICT{% else %}E_ALL{% endif %}" + display_errors: "{% if _env_type == 'prod' %}Off{% else %}On{% endif %}" + display_startup_errors: "{% if _env_type == 'prod' %}Off{% else %}On{% endif %}" + html_errors: "{% if _env_type == 'prod' %}Off{% else %}On{% endif %}" + engine: "On" + short_open_tag: "Off" + max_execution_time: 120 + max_input_time: 60 + max_input_nesting_level: 64 + max_input_vars: 1000 + memory_limit: 256M + log_errors_max_len: 1024 + ignore_repeated_errors: "Off" + ignore_repeated_source: "Off" + post_max_size: 200M + upload_max_filesize: 200M + max_file_uploads: 20 + date_timezone: "Europe/London" + gc_maxlifetime: 1440 + cookie_lifetime: 0 + zend_assertions: -1 + session_cookie_secure: "Off" + opcache: + enable: 1 + enable_cli: 0 + memory_consumption: 128 + max_accelerated_files: 2000 + validate_timestamps: 1 + +``` + + diff --git a/roles/debian/php-fpm/defaults/main.yml b/roles/debian/php-fpm/defaults/main.yml index 909b34e3a..ab3590a16 100644 --- a/roles/debian/php-fpm/defaults/main.yml +++ b/roles/debian/php-fpm/defaults/main.yml @@ -2,8 +2,26 @@ php: # see php-common for default version fpm: + # FPM settings - official documentation is here: https://www.php.net/manual/en/install.fpm.configuration.php unix_socket: false # set to true to use a unix socket, you must also update nginx and cachetool if you do + server_ip: "127.0.0.1" tcp_port: "" # leave empty to automate port selection - port will be "90{{ version | replace('.','') }}" - e.g. 9081 for PHP 8.1 + pool_user: "{{ user_deploy.username }}" + pool_group: "{{ user_deploy.username }}" # if using unix socket this should be the web server user + pm: dynamic # can also be static, see https://tideways.com/profiler/blog/an-introduction-to-php-fpm-tuning + default_socket_timeout: 60 + max_children: 5 + start_servers: 2 + min_spare_servers: 1 + max_spare_servers: 3 + process_idle_timeout: 10s + max_requests: 500 + request_terminate_timeout: 0 + rlimit_core: 0 # Possible Values: 'unlimited' or an integer greater or equal to 0; Default Value: 0 + slow_log: true + request_slowlog_timeout: 0 + slowlog_file_directory: "/home/{{ user_deploy.username }}" + # PHP ini file settings expose_php: "{% if _env_type == 'prod' %}Off{% else %}On{% endif %}" error_reporting: "{% if _env_type == 'prod' %}E_ALL & ~E_DEPRECATED & ~E_STRICT{% else %}E_ALL{% endif %}" display_errors: "{% if _env_type == 'prod' %}Off{% else %}On{% endif %}" @@ -23,16 +41,10 @@ php: upload_max_filesize: 200M max_file_uploads: 20 date_timezone: "Europe/London" - pool_user: "{{ user_deploy.username }}" - pool_group: "{{ user_deploy.username }}" # if using unix socket this should be the web server user - default_socket_timeout: 60 - max_children: 5 - start_servers: 2 - min_spare_servers: 1 - max_spare_servers: 3 - process_idle_timeout: 10s - max_requests: 500 gc_maxlifetime: 1440 + cookie_lifetime: 0 + zend_assertions: -1 + session_cookie_secure: "Off" opcache: enable: 1 enable_cli: 0 diff --git a/roles/debian/php-fpm/templates/php.fpm.ini.j2 b/roles/debian/php-fpm/templates/php.fpm.ini.j2 index b4d1185d9..c6a1a0361 100644 --- a/roles/debian/php-fpm/templates/php.fpm.ini.j2 +++ b/roles/debian/php-fpm/templates/php.fpm.ini.j2 @@ -1318,7 +1318,7 @@ session.use_strict_mode = 0 session.use_cookies = 1 ; http://php.net/session.cookie-secure -session.cookie_secure = Off +session.cookie_secure = {{ php.fpm.session_cookie_secure }} ; This option forces PHP to fetch and use a cookie for storing and maintaining ; the session id. We encourage this operation as it's very helpful in combating @@ -1337,7 +1337,7 @@ session.auto_start = 0 ; Lifetime in seconds of cookie or, if 0, until browser is restarted. ; http://php.net/session.cookie-lifetime -session.cookie_lifetime = 0 +session.cookie_lifetime = {{ php.fpm.cookie_lifetime }} ; The path for which the cookie is valid. ; http://php.net/session.cookie-path @@ -1526,7 +1526,7 @@ url_rewriter.tags = "a=href,area=href,frame=src,input=src,form=fakeentry" ; Development Value: 1 ; Production Value: -1 ; http://php.net/zend.assertions -zend.assertions = -1 +zend.assertions = {{ php.fpm.zend_assertions }} ; Assert(expr); active by default. ; http://php.net/assert.active diff --git a/roles/debian/php-fpm/templates/www.conf-fixedport.j2 b/roles/debian/php-fpm/templates/www.conf-fixedport.j2 index 7d986a2b5..b8a0a8e7a 100755 --- a/roles/debian/php-fpm/templates/www.conf-fixedport.j2 +++ b/roles/debian/php-fpm/templates/www.conf-fixedport.j2 @@ -1,7 +1,8 @@ [www] user = {{ php.fpm.pool_user }} group = {{ php.fpm.pool_group }} -listen = 127.0.0.1:{{ php.fpm.tcp_port }} +listen = {{ php.fpm.server_ip }}:{{ php.fpm.tcp_port }} + listen.owner = {{ php.fpm.pool_user }} listen.group = {{ php.fpm.pool_group }} pm = dynamic @@ -11,3 +12,10 @@ pm.min_spare_servers = {{ php.fpm.min_spare_servers }} pm.max_spare_servers = {{ php.fpm.max_spare_servers }} pm.process_idle_timeout = {{ php.fpm.process_idle_timeout }} pm.max_requests = {{ php.fpm.max_requests }} + +request_terminate_timeout = {{ php.fpm.request_terminate_timeout }} +rlimit_core = {{ php.fpm.rlimit_core }} +{% if php.fpm.slow_log %} +request_slowlog_timeout = {{ php.fpm.request_slowlog_timeout }} +slowlog = {{ php.fpm.slowlog_file_directory }}/php{{ php.version[0] }}-fpm.slow.log +{% endif %} diff --git a/roles/debian/php-fpm/templates/www.conf.j2 b/roles/debian/php-fpm/templates/www.conf.j2 index fb10d2865..7f5d4eeb5 100755 --- a/roles/debian/php-fpm/templates/www.conf.j2 +++ b/roles/debian/php-fpm/templates/www.conf.j2 @@ -1,14 +1,21 @@ [www] user = {{ php.fpm.pool_user }} group = {{ php.fpm.pool_group }} -listen = {% if php.fpm.unix_socket %}'/var/run/php{{ version | replace('.','') }}-fpm.sock'{% else %}127.0.0.1:90{{ version | replace('.','') }}{% endif %} +listen = {% if php.fpm.unix_socket %}'/var/run/php{{ version | replace('.','') }}-fpm.sock'{% else %}{{ php.fpm.server_ip }}:90{{ version | replace('.','') }}{% endif %} listen.owner = {{ php.fpm.pool_user }} listen.group = {{ php.fpm.pool_group }} -pm = dynamic +pm = {{ php.fpm.pm }} pm.max_children = {{ php.fpm.max_children }} pm.start_servers = {{ php.fpm.start_servers }} pm.min_spare_servers = {{ php.fpm.min_spare_servers }} pm.max_spare_servers = {{ php.fpm.max_spare_servers }} pm.process_idle_timeout = {{ php.fpm.process_idle_timeout }} pm.max_requests = {{ php.fpm.max_requests }} + +request_terminate_timeout = {{ php.fpm.request_terminate_timeout }} +rlimit_core = {{ php.fpm.rlimit_core }} +{% if php.fpm.slow_log %} +request_slowlog_timeout = {{ php.fpm.request_slowlog_timeout }} +slowlog = {{ php.fpm.slowlog_file_directory }}/php{{ version }}-fpm.slow.log +{% endif %} diff --git a/roles/debian/php_xdebug/README.md b/roles/debian/php_xdebug/README.md index 01429f1fe..f44ff859d 100644 --- a/roles/debian/php_xdebug/README.md +++ b/roles/debian/php_xdebug/README.md @@ -1,6 +1,6 @@ # PHP XDebug -Installs and configure XDebug extension for PHP +Installs and configures XDebug extension for PHP. From 61e148da6c0e2f370e388671eadd366a4cff8512 Mon Sep 17 00:00:00 2001 From: Greg Harvey Date: Wed, 3 Apr 2024 19:45:17 +0200 Subject: [PATCH 4/4] Adding template line-break for NGINX _common config for style. --- roles/debian/nginx/templates/_common.j2 | 1 + 1 file changed, 1 insertion(+) diff --git a/roles/debian/nginx/templates/_common.j2 b/roles/debian/nginx/templates/_common.j2 index bfc0e92fc..79b1b114c 100644 --- a/roles/debian/nginx/templates/_common.j2 +++ b/roles/debian/nginx/templates/_common.j2 @@ -10,6 +10,7 @@ gzip_comp_level 6; gzip_types {% for gzip_type in nginx.http.gzip_types %} {{ gzip_type }}{% if loop.last %};{% endif %} + {% endfor %} gzip_buffers 16 8k; gzip_min_length 512;