OneLinersCommand workbench
Guides
Security / Services & Applications

Configure a production PHP INI baseline

Separate CLI and FPM settings, hide unsafe disclosure, bound resources, secure sessions, centralize errors, and verify effective values through the web SAPI.

40 min8 stepsChanges system stateRevision 2
Save or explore
Save to collectionCreate a collection in the sidebar first.
0 of 8 steps completed
Goal

Replace copied php.ini snippets with an auditable, application-scoped production configuration.

Supported environments
  • PHP 8.2, 8.3, 8.4, 8.5
Prerequisites
  • Supported host and recovery access Use a supported distribution, keep an independent root-capable session, and record the current package repositories before changing the PHP runtime.cat /etc/os-release && uname -m
  • Application compatibility Confirm the application, framework, extensions, and deployment tooling explicitly support the target PHP branch.
  • Configuration backup Archive the active PHP, web-server, and application configuration before packages, pools, or handlers change.
Operating boundary

OneLiners never runs these steps or stores secrets. Review placeholders, versions, current state, and change-control requirements before using a command.

Full guide

What you will build

System
  • A late-loading, application-owned FPM INI override that separates production web settings from CLI defaults.
  • Bound memory, execution, input, upload and session behavior with private error logging and reduced runtime disclosure.
  • A protected web-SAPI verification endpoint and rollback archive that prove the effective values actually used by requests.
Observable outcome
  • Production responses do not expose stack traces, paths or PHP version headers, while operators retain actionable private diagnostics.
  • Resource and session limits are explicit, internally consistent and verified through the correct FPM pool rather than inferred from CLI.

Architecture

How the parts fit together

PHP builds an effective configuration from the SAPI's primary php.ini and ordered scan-directory fragments. A dedicated late-loading FPM fragment owns application policy without editing vendor files. FPM validates and reloads that candidate, and a protected health endpoint returns only an allowlist of effective directive values. Private session storage and error logs sit outside the public root. The archived prior tree plus effective-value snapshot supports a precise rollback.

FPM INI scan treeComposes packaged defaults and the application-owned production override in deterministic order.
Resource limitsBound request memory, time, input variables and body/upload sizes using measured workload needs.
Session and error pathsKeep writable runtime state and diagnostics private and attributable.
Web-SAPI health checkProves effective values in the actual request path without publishing phpinfo.
  1. Inventory CLI and FPM configuration roots and archive files plus effective before-state.
  2. Write one documented override for disclosure, errors, limits, sessions and URL behavior.
  3. Validate and reload the intended FPM service, then query only allowlisted effective values through the protected application path.
  4. Exercise controlled error, session, upload and normal requests; rollback the override if behavior regresses.

Assumptions

  • The exact FPM binary, service, pool and INI scan directories are known and a canary request path is available.
  • Application owners have measured normal memory, execution, upload, input-variable and session requirements.
  • Private log/session paths exist with correct ownership, rotation and capacity, outside the public root.

Key concepts

INI scan order
The ordered fragment loading that lets later directives replace earlier packaged or global values.
effective value
The final directive seen by one SAPI after all relevant configuration layers are loaded.
error disclosure
Rendering diagnostics to clients, which is different from privately logging them for operators.
resource budget
A coordinated set of PHP, FPM, proxy and application limits sized from measured workload behavior.

Before you copy

Values used in this guide

{{app}}

Short application identifier used in service, pool, directory, and configuration names.

Example: billing
{{appGroup}}

Operating-system group that owns application-readable or shared runtime paths.

Example: billing
{{appUser}}

Non-login operating-system identity used by the application workers.

Example: billing
{{domain}}

Fully qualified public or internal hostname served by this configuration.

Example: billing.example.com
{{phpVersion}}

Exact PHP major and minor branch used by the target runtime.

Example: 8.3

Security and production boundaries

  • Never expose phpinfo in production; it reveals paths, modules, environment data and configuration useful to attackers.
  • Disabling display_errors must be paired with protected logs and alerting, not with loss of operational evidence.
  • Do not paste universal disable_functions lists: they are incomplete security boundaries and can break supported workloads.

Stop before continuing if

  • Stop if CLI and FPM paths remain ambiguous, the candidate contains unknown copied directives, or log/session paths are publicly readable.
  • Do not reload when limits are inconsistent across proxy/PHP/application or representative workload evidence is absent.
01

instruction

Identify every active configuration tree

read-only

Record CLI and FPM loaded files and scan directories; edit the web SAPI deliberately instead of assuming php.ini is shared.

Why this step matters

Identify every active configuration tree is a separate checkpoint because it establishes one auditable part of replace copied php.ini snippets with an auditable, application-scoped production configuration. Performing it independently keeps a failed prerequisite, syntax error, or compatibility mismatch from being hidden by later actions.

What to understand

Record CLI and FPM loaded files and scan directories; edit the web SAPI deliberately instead of assuming php.ini is shared. Read the complete command or configuration before execution, replace the documented placeholders, and compare the target host with the supported environments listed at the beginning of this tutorial.

Capture the before-state and the exact output in the change record. If this step modifies a file or service, validate the candidate with its native checker before any reload; a successful process exit alone does not prove that the application uses the intended value.

Use a representative staging or canary host first. Repeat the stated checkpoint immediately, because proceeding with ambiguous evidence makes the later end-to-end verification and rollback materially harder.

System changes

  • This step may affect the files, packages, identities, services, or runtime policy named in “Identify every active configuration tree”. The scope must remain limited to the selected application and supported host.

Syntax explained

php
Invokes the principal tool or configuration operation for “Identify every active configuration tree”; confirm that it resolves to the expected packaged executable or file before using elevated privileges.
{{…}}
Marks an operator-supplied value. Replace every placeholder deliberately; do not paste untrusted text or leave braces in the production command.
|
Passes standard output to the next read-only inspection stage; review each stage separately if the combined result is surprising.
Command
Fill variables0/1 ready

Values stay on this page and are never sent or saved.

php --ini; php-fpm{{phpVersion}} -i | grep -E '^(Loaded Configuration|Scan this dir)'
Example output / evidence
CLI and FPM paths are explicit.

Checkpoint: Checkpoint: Identify every active configuration tree

Continue whenCLI and FPM paths are explicit. Treat this concrete evidence as the minimum success signal and also confirm that unrelated services and the previous healthy path remain unchanged.

Stop whenStop before the next step when php reports an error, the output differs materially from the example, an unexpected package/service/path is affected, or the required before-state and rollback artifact are missing.

If this step fails

The command for “Identify every active configuration tree” fails, produces no useful evidence, or the expected service/configuration state is absent.

Likely causeA placeholder targets the wrong environment, the installed version uses another path or unit name, permissions are insufficient, or an earlier prerequisite was not satisfied.

Safe checks
  • command -v php 2>/dev/null || true
  • systemctl --failed --no-pager 2>/dev/null || true
  • journalctl -p warning -n 50 --no-pager 2>/dev/null || true

ResolutionDo not improvise a privileged workaround. Re-read the environment and variable table, inspect the official source for the installed version, restore the candidate file if necessary, and repeat only this checkpoint.

Security notes

  • Keep secrets out of shell history, process arguments, screenshots, logs, and tutorial placeholders. Elevate only the narrow command that requires it and preserve package signature and TLS verification.

Alternatives

  • When the host layout or software version differs, use the vendor-supported equivalent in a disposable staging environment and document the mapping before touching production.

Stop conditions

  • Stop if the action broadens network exposure, permissions, package sources, writable paths, or service privileges beyond the tutorial's declared architecture.
02

instruction

Archive configuration and effective settings

caution

Store the current files plus php -i output so individual directive regressions can be compared.

Why this step matters

Archive configuration and effective settings is a separate checkpoint because it establishes one auditable part of replace copied php.ini snippets with an auditable, application-scoped production configuration. Performing it independently keeps a failed prerequisite, syntax error, or compatibility mismatch from being hidden by later actions.

What to understand

Store the current files plus php -i output so individual directive regressions can be compared. Read the complete command or configuration before execution, replace the documented placeholders, and compare the target host with the supported environments listed at the beginning of this tutorial.

Capture the before-state and the exact output in the change record. If this step modifies a file or service, validate the candidate with its native checker before any reload; a successful process exit alone does not prove that the application uses the intended value.

Use a representative staging or canary host first. Repeat the stated checkpoint immediately, because proceeding with ambiguous evidence makes the later end-to-end verification and rollback materially harder.

System changes

  • This step may affect the files, packages, identities, services, or runtime policy named in “Archive configuration and effective settings”. The scope must remain limited to the selected application and supported host.

Syntax explained

tar
Invokes the principal tool or configuration operation for “Archive configuration and effective settings”; confirm that it resolves to the expected packaged executable or file before using elevated privileges.
{{…}}
Marks an operator-supplied value. Replace every placeholder deliberately; do not paste untrusted text or leave braces in the production command.
Command
Fill variables0/1 ready

Values stay on this page and are never sent or saved.

sudo tar -czf /root/php-ini-before-$(date +%F-%H%M).tgz /etc/php/{{phpVersion}}; php -i > /tmp/php-cli-before.txt
Example output / evidence
The configuration archive and effective CLI snapshot exist.

Checkpoint: Checkpoint: Archive configuration and effective settings

Continue whenThe configuration archive and effective CLI snapshot exist. Treat this concrete evidence as the minimum success signal and also confirm that unrelated services and the previous healthy path remain unchanged.

Stop whenStop before the next step when tar reports an error, the output differs materially from the example, an unexpected package/service/path is affected, or the required before-state and rollback artifact are missing.

If this step fails

The command for “Archive configuration and effective settings” fails, produces no useful evidence, or the expected service/configuration state is absent.

Likely causeA placeholder targets the wrong environment, the installed version uses another path or unit name, permissions are insufficient, or an earlier prerequisite was not satisfied.

Safe checks
  • command -v tar 2>/dev/null || true
  • systemctl --failed --no-pager 2>/dev/null || true
  • journalctl -p warning -n 50 --no-pager 2>/dev/null || true

ResolutionDo not improvise a privileged workaround. Re-read the environment and variable table, inspect the official source for the installed version, restore the candidate file if necessary, and repeat only this checkpoint.

Security notes

  • Keep secrets out of shell history, process arguments, screenshots, logs, and tutorial placeholders. Elevate only the narrow command that requires it and preserve package signature and TLS verification.

Alternatives

  • When the host layout or software version differs, use the vendor-supported equivalent in a disposable staging environment and document the mapping before touching production.

Stop conditions

  • Stop if the action broadens network exposure, permissions, package sources, writable paths, or service privileges beyond the tutorial's declared architecture.
03

config

Create an application-owned override file

caution

Use a late-loading conf.d file instead of editing the packaged php.ini, and document every non-default directive.

Why this step matters

Create an application-owned override file is a separate checkpoint because it establishes one auditable part of replace copied php.ini snippets with an auditable, application-scoped production configuration. Performing it independently keeps a failed prerequisite, syntax error, or compatibility mismatch from being hidden by later actions.

What to understand

Use a late-loading conf.d file instead of editing the packaged php.ini, and document every non-default directive. Read the complete command or configuration before execution, replace the documented placeholders, and compare the target host with the supported environments listed at the beginning of this tutorial.

Capture the before-state and the exact output in the change record. If this step modifies a file or service, validate the candidate with its native checker before any reload; a successful process exit alone does not prove that the application uses the intended value.

Use a representative staging or canary host first. Repeat the stated checkpoint immediately, because proceeding with ambiguous evidence makes the later end-to-end verification and rollback materially harder.

System changes

  • This step may affect the files, packages, identities, services, or runtime policy named in “Create an application-owned override file”. The scope must remain limited to the selected application and supported host.

Syntax explained

install
Invokes the principal tool or configuration operation for “Create an application-owned override file”; confirm that it resolves to the expected packaged executable or file before using elevated privileges.
{{…}}
Marks an operator-supplied value. Replace every placeholder deliberately; do not paste untrusted text or leave braces in the production command.
/etc/php/{{phpVersion}}/fpm/conf.d/99-{{app}}-production.ini
Is the persistent configuration boundary changed by this step. Keep an attributable backup and validate the consumer before reload.
File /etc/php/{{phpVersion}}/fpm/conf.d/99-{{app}}-production.ini
Configuration
Fill variables0/2 ready

Values stay on this page and are never sent or saved.

sudo install -m 0644 /dev/null /etc/php/{{phpVersion}}/fpm/conf.d/99-{{app}}-production.ini; sudoedit /etc/php/{{phpVersion}}/fpm/conf.d/99-{{app}}-production.ini
Example output / evidence
A dedicated FPM override file exists.

Checkpoint: Checkpoint: Create an application-owned override file

Continue whenA dedicated FPM override file exists. Treat this concrete evidence as the minimum success signal and also confirm that unrelated services and the previous healthy path remain unchanged.

Stop whenStop before the next step when install reports an error, the output differs materially from the example, an unexpected package/service/path is affected, or the required before-state and rollback artifact are missing.

If this step fails

The command for “Create an application-owned override file” fails, produces no useful evidence, or the expected service/configuration state is absent.

Likely causeA placeholder targets the wrong environment, the installed version uses another path or unit name, permissions are insufficient, or an earlier prerequisite was not satisfied.

Safe checks
  • command -v install 2>/dev/null || true
  • systemctl --failed --no-pager 2>/dev/null || true
  • journalctl -p warning -n 50 --no-pager 2>/dev/null || true

ResolutionDo not improvise a privileged workaround. Re-read the environment and variable table, inspect the official source for the installed version, restore the candidate file if necessary, and repeat only this checkpoint.

Security notes

  • Keep secrets out of shell history, process arguments, screenshots, logs, and tutorial placeholders. Elevate only the narrow command that requires it and preserve package signature and TLS verification.

Alternatives

  • When the host layout or software version differs, use the vendor-supported equivalent in a disposable staging environment and document the mapping before touching production.

Stop conditions

  • Stop if the action broadens network exposure, permissions, package sources, writable paths, or service privileges beyond the tutorial's declared architecture.
04

config

Disable error disclosure and preserve diagnostics

caution

Set display_errors and display_startup_errors off, log_errors on, a private error_log, and an explicit error_reporting mask.

Why this step matters

Disable error disclosure and preserve diagnostics is a separate checkpoint because it establishes one auditable part of replace copied php.ini snippets with an auditable, application-scoped production configuration. Performing it independently keeps a failed prerequisite, syntax error, or compatibility mismatch from being hidden by later actions.

What to understand

Set display_errors and display_startup_errors off, log_errors on, a private error_log, and an explicit error_reporting mask. Read the complete command or configuration before execution, replace the documented placeholders, and compare the target host with the supported environments listed at the beginning of this tutorial.

Capture the before-state and the exact output in the change record. If this step modifies a file or service, validate the candidate with its native checker before any reload; a successful process exit alone does not prove that the application uses the intended value.

Use a representative staging or canary host first. Repeat the stated checkpoint immediately, because proceeding with ambiguous evidence makes the later end-to-end verification and rollback materially harder.

System changes

  • This step may affect the files, packages, identities, services, or runtime policy named in “Disable error disclosure and preserve diagnostics”. The scope must remain limited to the selected application and supported host.

Syntax explained

grep
Invokes the principal tool or configuration operation for “Disable error disclosure and preserve diagnostics”; confirm that it resolves to the expected packaged executable or file before using elevated privileges.
{{…}}
Marks an operator-supplied value. Replace every placeholder deliberately; do not paste untrusted text or leave braces in the production command.
|
Passes standard output to the next read-only inspection stage; review each stage separately if the combined result is surprising.
configuration file
Is the persistent configuration boundary changed by this step. Keep an attributable backup and validate the consumer before reload.
Configuration
Fill variables0/2 ready

Values stay on this page and are never sent or saved.

sudo grep -E '^(display_errors|display_startup_errors|log_errors|error_log|error_reporting)' /etc/php/{{phpVersion}}/fpm/conf.d/99-{{app}}-production.ini
Example output / evidence
Errors are logged privately and not rendered to clients.

Checkpoint: Checkpoint: Disable error disclosure and preserve diagnostics

Continue whenErrors are logged privately and not rendered to clients. Treat this concrete evidence as the minimum success signal and also confirm that unrelated services and the previous healthy path remain unchanged.

Stop whenStop before the next step when grep reports an error, the output differs materially from the example, an unexpected package/service/path is affected, or the required before-state and rollback artifact are missing.

If this step fails

The command for “Disable error disclosure and preserve diagnostics” fails, produces no useful evidence, or the expected service/configuration state is absent.

Likely causeA placeholder targets the wrong environment, the installed version uses another path or unit name, permissions are insufficient, or an earlier prerequisite was not satisfied.

Safe checks
  • command -v grep 2>/dev/null || true
  • systemctl --failed --no-pager 2>/dev/null || true
  • journalctl -p warning -n 50 --no-pager 2>/dev/null || true

ResolutionDo not improvise a privileged workaround. Re-read the environment and variable table, inspect the official source for the installed version, restore the candidate file if necessary, and repeat only this checkpoint.

Security notes

  • Keep secrets out of shell history, process arguments, screenshots, logs, and tutorial placeholders. Elevate only the narrow command that requires it and preserve package signature and TLS verification.

Alternatives

  • When the host layout or software version differs, use the vendor-supported equivalent in a disposable staging environment and document the mapping before touching production.

Stop conditions

  • Stop if the action broadens network exposure, permissions, package sources, writable paths, or service privileges beyond the tutorial's declared architecture.
05

config

Bound memory, execution, input, and uploads

caution

Set application-specific limits based on measured requests and ensure post_max_size exceeds upload_max_filesize.

Why this step matters

Bound memory, execution, input, and uploads is a separate checkpoint because it establishes one auditable part of replace copied php.ini snippets with an auditable, application-scoped production configuration. Performing it independently keeps a failed prerequisite, syntax error, or compatibility mismatch from being hidden by later actions.

What to understand

Set application-specific limits based on measured requests and ensure post_max_size exceeds upload_max_filesize. Read the complete command or configuration before execution, replace the documented placeholders, and compare the target host with the supported environments listed at the beginning of this tutorial.

Capture the before-state and the exact output in the change record. If this step modifies a file or service, validate the candidate with its native checker before any reload; a successful process exit alone does not prove that the application uses the intended value.

Use a representative staging or canary host first. Repeat the stated checkpoint immediately, because proceeding with ambiguous evidence makes the later end-to-end verification and rollback materially harder.

System changes

  • This step may affect the files, packages, identities, services, or runtime policy named in “Bound memory, execution, input, and uploads”. The scope must remain limited to the selected application and supported host.

Syntax explained

grep
Invokes the principal tool or configuration operation for “Bound memory, execution, input, and uploads”; confirm that it resolves to the expected packaged executable or file before using elevated privileges.
{{…}}
Marks an operator-supplied value. Replace every placeholder deliberately; do not paste untrusted text or leave braces in the production command.
|
Passes standard output to the next read-only inspection stage; review each stage separately if the combined result is surprising.
configuration file
Is the persistent configuration boundary changed by this step. Keep an attributable backup and validate the consumer before reload.
Configuration
Fill variables0/2 ready

Values stay on this page and are never sent or saved.

sudo grep -E '^(memory_limit|max_execution_time|max_input_time|max_input_vars|post_max_size|upload_max_filesize)' /etc/php/{{phpVersion}}/fpm/conf.d/99-{{app}}-production.ini
Example output / evidence
All resource limits are finite and internally consistent.

Checkpoint: Checkpoint: Bound memory, execution, input, and uploads

Continue whenAll resource limits are finite and internally consistent. Treat this concrete evidence as the minimum success signal and also confirm that unrelated services and the previous healthy path remain unchanged.

Stop whenStop before the next step when grep reports an error, the output differs materially from the example, an unexpected package/service/path is affected, or the required before-state and rollback artifact are missing.

If this step fails

The command for “Bound memory, execution, input, and uploads” fails, produces no useful evidence, or the expected service/configuration state is absent.

Likely causeA placeholder targets the wrong environment, the installed version uses another path or unit name, permissions are insufficient, or an earlier prerequisite was not satisfied.

Safe checks
  • command -v grep 2>/dev/null || true
  • systemctl --failed --no-pager 2>/dev/null || true
  • journalctl -p warning -n 50 --no-pager 2>/dev/null || true

ResolutionDo not improvise a privileged workaround. Re-read the environment and variable table, inspect the official source for the installed version, restore the candidate file if necessary, and repeat only this checkpoint.

Security notes

  • Keep secrets out of shell history, process arguments, screenshots, logs, and tutorial placeholders. Elevate only the narrow command that requires it and preserve package signature and TLS verification.

Alternatives

  • When the host layout or software version differs, use the vendor-supported equivalent in a disposable staging environment and document the mapping before touching production.

Stop conditions

  • Stop if the action broadens network exposure, permissions, package sources, writable paths, or service privileges beyond the tutorial's declared architecture.
06

config

Harden PHP session cookies and storage

caution

Use a private session path and enable strict mode, HttpOnly, Secure, SameSite, strong IDs, and cookie-only sessions for HTTPS applications.

Why this step matters

Harden PHP session cookies and storage is a separate checkpoint because it establishes one auditable part of replace copied php.ini snippets with an auditable, application-scoped production configuration. Performing it independently keeps a failed prerequisite, syntax error, or compatibility mismatch from being hidden by later actions.

What to understand

Use a private session path and enable strict mode, HttpOnly, Secure, SameSite, strong IDs, and cookie-only sessions for HTTPS applications. Read the complete command or configuration before execution, replace the documented placeholders, and compare the target host with the supported environments listed at the beginning of this tutorial.

Capture the before-state and the exact output in the change record. If this step modifies a file or service, validate the candidate with its native checker before any reload; a successful process exit alone does not prove that the application uses the intended value.

Use a representative staging or canary host first. Repeat the stated checkpoint immediately, because proceeding with ambiguous evidence makes the later end-to-end verification and rollback materially harder.

System changes

  • This step may affect the files, packages, identities, services, or runtime policy named in “Harden PHP session cookies and storage”. The scope must remain limited to the selected application and supported host.

Syntax explained

install
Invokes the principal tool or configuration operation for “Harden PHP session cookies and storage”; confirm that it resolves to the expected packaged executable or file before using elevated privileges.
{{…}}
Marks an operator-supplied value. Replace every placeholder deliberately; do not paste untrusted text or leave braces in the production command.
configuration file
Is the persistent configuration boundary changed by this step. Keep an attributable backup and validate the consumer before reload.
Configuration
Fill variables0/4 ready

Values stay on this page and are never sent or saved.

sudo install -d -o {{appUser}} -g {{appGroup}} -m 0700 /srv/{{app}}/var/sessions; sudo grep -E '^session\.' /etc/php/{{phpVersion}}/fpm/conf.d/99-{{app}}-production.ini
Example output / evidence
Session storage is private and cookie directives are explicit.

Checkpoint: Checkpoint: Harden PHP session cookies and storage

Continue whenSession storage is private and cookie directives are explicit. Treat this concrete evidence as the minimum success signal and also confirm that unrelated services and the previous healthy path remain unchanged.

Stop whenStop before the next step when install reports an error, the output differs materially from the example, an unexpected package/service/path is affected, or the required before-state and rollback artifact are missing.

If this step fails

The command for “Harden PHP session cookies and storage” fails, produces no useful evidence, or the expected service/configuration state is absent.

Likely causeA placeholder targets the wrong environment, the installed version uses another path or unit name, permissions are insufficient, or an earlier prerequisite was not satisfied.

Safe checks
  • command -v install 2>/dev/null || true
  • systemctl --failed --no-pager 2>/dev/null || true
  • journalctl -p warning -n 50 --no-pager 2>/dev/null || true

ResolutionDo not improvise a privileged workaround. Re-read the environment and variable table, inspect the official source for the installed version, restore the candidate file if necessary, and repeat only this checkpoint.

Security notes

  • Keep secrets out of shell history, process arguments, screenshots, logs, and tutorial placeholders. Elevate only the narrow command that requires it and preserve package signature and TLS verification.

Alternatives

  • When the host layout or software version differs, use the vendor-supported equivalent in a disposable staging environment and document the mapping before touching production.

Stop conditions

  • Stop if the action broadens network exposure, permissions, package sources, writable paths, or service privileges beyond the tutorial's declared architecture.
07

config

Reduce runtime disclosure and risky URL handling

caution

Disable expose_php and allow_url_include; decide allow_url_fopen from application requirements rather than disabling it blindly.

Why this step matters

Reduce runtime disclosure and risky URL handling is a separate checkpoint because it establishes one auditable part of replace copied php.ini snippets with an auditable, application-scoped production configuration. Performing it independently keeps a failed prerequisite, syntax error, or compatibility mismatch from being hidden by later actions.

What to understand

Disable expose_php and allow_url_include; decide allow_url_fopen from application requirements rather than disabling it blindly. Read the complete command or configuration before execution, replace the documented placeholders, and compare the target host with the supported environments listed at the beginning of this tutorial.

Capture the before-state and the exact output in the change record. If this step modifies a file or service, validate the candidate with its native checker before any reload; a successful process exit alone does not prove that the application uses the intended value.

Use a representative staging or canary host first. Repeat the stated checkpoint immediately, because proceeding with ambiguous evidence makes the later end-to-end verification and rollback materially harder.

System changes

  • This step may affect the files, packages, identities, services, or runtime policy named in “Reduce runtime disclosure and risky URL handling”. The scope must remain limited to the selected application and supported host.

Syntax explained

grep
Invokes the principal tool or configuration operation for “Reduce runtime disclosure and risky URL handling”; confirm that it resolves to the expected packaged executable or file before using elevated privileges.
{{…}}
Marks an operator-supplied value. Replace every placeholder deliberately; do not paste untrusted text or leave braces in the production command.
|
Passes standard output to the next read-only inspection stage; review each stage separately if the combined result is surprising.
configuration file
Is the persistent configuration boundary changed by this step. Keep an attributable backup and validate the consumer before reload.
Configuration
Fill variables0/2 ready

Values stay on this page and are never sent or saved.

sudo grep -E '^(expose_php|allow_url_fopen|allow_url_include|cgi.fix_pathinfo)' /etc/php/{{phpVersion}}/fpm/conf.d/99-{{app}}-production.ini
Example output / evidence
Version disclosure and URL include are disabled.

Checkpoint: Checkpoint: Reduce runtime disclosure and risky URL handling

Continue whenVersion disclosure and URL include are disabled. Treat this concrete evidence as the minimum success signal and also confirm that unrelated services and the previous healthy path remain unchanged.

Stop whenStop before the next step when grep reports an error, the output differs materially from the example, an unexpected package/service/path is affected, or the required before-state and rollback artifact are missing.

If this step fails

The command for “Reduce runtime disclosure and risky URL handling” fails, produces no useful evidence, or the expected service/configuration state is absent.

Likely causeA placeholder targets the wrong environment, the installed version uses another path or unit name, permissions are insufficient, or an earlier prerequisite was not satisfied.

Safe checks
  • command -v grep 2>/dev/null || true
  • systemctl --failed --no-pager 2>/dev/null || true
  • journalctl -p warning -n 50 --no-pager 2>/dev/null || true

ResolutionDo not improvise a privileged workaround. Re-read the environment and variable table, inspect the official source for the installed version, restore the candidate file if necessary, and repeat only this checkpoint.

Security notes

  • Keep secrets out of shell history, process arguments, screenshots, logs, and tutorial placeholders. Elevate only the narrow command that requires it and preserve package signature and TLS verification.

Alternatives

  • When the host layout or software version differs, use the vendor-supported equivalent in a disposable staging environment and document the mapping before touching production.

Stop conditions

  • Stop if the action broadens network exposure, permissions, package sources, writable paths, or service privileges beyond the tutorial's declared architecture.
08

verification

Validate, reload, and inspect effective FPM values

read-only

Run FPM syntax validation, reload, then query a protected application endpoint that reports only an allowlist of directive values.

Why this step matters

Validate, reload, and inspect effective FPM values is a separate checkpoint because it establishes one auditable part of replace copied php.ini snippets with an auditable, application-scoped production configuration. Performing it independently keeps a failed prerequisite, syntax error, or compatibility mismatch from being hidden by later actions.

What to understand

Run FPM syntax validation, reload, then query a protected application endpoint that reports only an allowlist of directive values. Read the complete command or configuration before execution, replace the documented placeholders, and compare the target host with the supported environments listed at the beginning of this tutorial.

Capture the before-state and the exact output in the change record. If this step modifies a file or service, validate the candidate with its native checker before any reload; a successful process exit alone does not prove that the application uses the intended value.

Use a representative staging or canary host first. Repeat the stated checkpoint immediately, because proceeding with ambiguous evidence makes the later end-to-end verification and rollback materially harder.

System changes

  • This step may affect the files, packages, identities, services, or runtime policy named in “Validate, reload, and inspect effective FPM values”. The scope must remain limited to the selected application and supported host.

Syntax explained

php-fpm
Invokes the principal tool or configuration operation for “Validate, reload, and inspect effective FPM values”; confirm that it resolves to the expected packaged executable or file before using elevated privileges.
{{…}}
Marks an operator-supplied value. Replace every placeholder deliberately; do not paste untrusted text or leave braces in the production command.
&&
Runs the following operation only when the previous command succeeds, preventing a reload or state transition after a failed validation.
Command
Fill variables0/2 ready

Values stay on this page and are never sent or saved.

sudo php-fpm{{phpVersion}} -tt && sudo systemctl reload php{{phpVersion}}-fpm; curl --fail --silent https://{{domain}}/internal/php-config-health
Example output / evidence
The web SAPI reports the reviewed values and no secret configuration.

Checkpoint: Checkpoint: Validate, reload, and inspect effective FPM values

Continue whenThe web SAPI reports the reviewed values and no secret configuration. Treat this concrete evidence as the minimum success signal and also confirm that unrelated services and the previous healthy path remain unchanged.

Stop whenStop before the next step when php-fpm reports an error, the output differs materially from the example, an unexpected package/service/path is affected, or the required before-state and rollback artifact are missing.

If this step fails

The command for “Validate, reload, and inspect effective FPM values” fails, produces no useful evidence, or the expected service/configuration state is absent.

Likely causeA placeholder targets the wrong environment, the installed version uses another path or unit name, permissions are insufficient, or an earlier prerequisite was not satisfied.

Safe checks
  • command -v php-fpm 2>/dev/null || true
  • systemctl --failed --no-pager 2>/dev/null || true
  • journalctl -p warning -n 50 --no-pager 2>/dev/null || true

ResolutionDo not improvise a privileged workaround. Re-read the environment and variable table, inspect the official source for the installed version, restore the candidate file if necessary, and repeat only this checkpoint.

Security notes

  • Keep secrets out of shell history, process arguments, screenshots, logs, and tutorial placeholders. Elevate only the narrow command that requires it and preserve package signature and TLS verification.

Alternatives

  • When the host layout or software version differs, use the vendor-supported equivalent in a disposable staging environment and document the mapping before touching production.

Stop conditions

  • Stop if the action broadens network exposure, permissions, package sources, writable paths, or service privileges beyond the tutorial's declared architecture.

Finish line

Verification checklist

Error handlingcurl --silent --show-error -o /tmp/error-body -w '%{http_code}\n' https://{{domain}}/internal/test-error; grep -iE 'stack trace|fatal error|/srv/' /tmp/error-body && exit 1 || trueThe controlled error is logged but sensitive diagnostics are absent from the response.
Session cookiecurl --silent --head https://{{domain}}/login | grep -i '^set-cookie:'The session cookie includes Secure, HttpOnly, and the intended SameSite policy.

Recovery guidance

Common problems and safe checks

The web server returns 502/503 or reports that the FastCGI upstream is unavailable.

Likely causeThe configured socket and the active PHP-FPM pool disagree, the pool failed validation, or Unix socket ownership does not permit the web-server worker to connect.

Safe checks
  • systemctl status 'php*-fpm' --no-pager
  • find /run -maxdepth 3 -type s -name '*php*fpm*' -ls
  • journalctl -u nginx -u apache2 -u php8.3-fpm -p warning -n 80 --no-pager

ResolutionMatch the virtual host to one validated pool socket and explicit owner/group/mode, then reload only after both native configuration tests pass.

CLI reports the intended PHP version but the HTTP application uses another version or INI value.

Likely causeCLI and FPM are separate SAPIs, the virtual host targets another pool, or a later scan-directory file overrides the reviewed setting.

Safe checks
  • php --ini
  • systemctl list-units --type=service '*php*fpm*' --no-pager
  • grep -R -n 'fastcgi_pass\|SetHandler' /etc/nginx /etc/apache2 2>/dev/null

ResolutionTrace the request from hostname through the selected handler and pool to its loaded INI tree; correct that specific boundary rather than changing global CLI alternatives.

Validation passes but a representative request fails after the reload.

Likely causeThe syntax is legal but a path, permission, resource limit, extension, database grant, network dependency, or systemd restriction is incompatible with the real workload.

Safe checks
  • systemctl --failed --no-pager
  • journalctl -p warning --since '-10 min' --no-pager
  • curl --fail --silent --show-error https://example.com/health

ResolutionRemove the host from traffic, compare the before-state, revert the smallest changed layer, and use the preserved logs plus a safe fixture to refine the candidate in staging.

After the procedure

Alternatives and next steps

Consider these alternatives

  • Set pool-specific `php_admin_value` directives for controls that must not be changed by application code.
  • Bake the reviewed fragment into an immutable image and verify the same digest through environments.

Operate it safely

  • Track memory/time/upload percentiles and review the override after application or PHP branch changes.
  • Add automated tests asserting disclosure, session-cookie flags and effective values after every deployment.

Recovery

Rollback

Restore or disable the application override file and reload FPM.

  1. Move 99-{{app}}-production.ini aside, restore the archived prior override, and validate FPM.
  2. Reload FPM and repeat the application, error, and session smoke tests.
  3. Retain the failed override for comparison instead of deleting evidence.

Evidence

Sources and review

Verified 2026-07-25Review due 2026-10-23
PHP core configuration directivesofficialPHP-FPM installation and configurationofficialPHP installation on Unix systemsofficial