A deployment changes more than source files. The PHP runtime, extensions, configuration, Composer dependencies, web server, workers, cache state, database schema, secrets, permissions, and monitoring must agree on one compatible release.
After this lesson, you can build an immutable artifact, separate production diagnostics from user responses, coordinate OPcache and migrations, define a meaningful health check, and write a rollback plan before release pressure begins.
Build from a reviewed commit, install locked production dependencies, and avoid editing application files on the server. Record the commit or release identifier so logs and health output can identify deployed code.
composer install --no-dev --classmap-authoritative --no-interaction
php -l public/index.php
install honors composer.lock; authoritative classmaps trade dynamic discovery for predictable production autoloading when the project supports it.
Log enough context to diagnose a request, but exclude passwords, session identifiers, authorization headers, private uploads, and full payment or identity data.
| Concern | Production Direction |
|---|---|
| display_errors | Off for user responses |
| log_errors | On with protected destination |
| Secrets | Injected outside source control |
| Session cookies | Secure, HttpOnly, appropriate SameSite |
| File permissions | Least privilege; writable storage only where required |
OPcache caches compiled bytecode. If timestamp validation is disabled, a deployment must reset OPcache or restart the relevant PHP workers after atomically activating the new release; otherwise requests may continue executing stale code.
For rolling releases, use expand-and-contract migrations: add backward-compatible schema first, deploy code that works with old and new shapes, migrate data, then remove obsolete columns in a later release.
A liveness endpoint proves the process responds; a readiness check proves the instance can serve traffic. Keep checks fast and avoid causing a dependency outage by probing every downstream service on every request.
<?php
header('Content-Type: application/json; charset=utf-8');
echo json_encode([
'status' => 'ok',
'release' => getenv('APP_RELEASE') ?: 'unknown',
], JSON_THROW_ON_ERROR);
Expose a non-secret release identifier; protect deeper diagnostic endpoints from public access.
0 of 2 checked
Try this next
0 of 2 completed
Explore 500+ free tutorials across 20+ languages and frameworks.