Skip to main content

Cloudsoft Zone Build, deploy and scale with practical guides to PHP, Node.js, React, DevOps and AI automation. Explore the guides

Cloudsoft Zone
CakePHPDevOpsPHPResource guide

CakePHP 5 production deployment checklist: security, performance and releases

A practical checklist for running CakePHP 5.4 in production: debug and secrets, App.fullBaseUrl and host-header checks, webroot as document root, HTTPS, CSRF and security headers, caching, a deploy script and monitoring.

Cloudsoft Zone

Updated 8 min read

Long aisle between white enclosed server cabinets in a brightly lit data centre
Photograph: PiDatacenters / CC BY-SA 4.0, via Wikimedia Commons
In this article

Most CakePHP security incidents and slow production sites have ordinary causes: debug mode left on, the project root exposed instead of webroot/, a guessable salt, missing HTTPS enforcement, or a cold metadata cache after every deploy. None of these are framework bugs. They are configuration steps that are easy to skip when a release is late.

This checklist collects the production steps from the CakePHP 5 book and the current cakephp/app skeleton into one list you can run before every first launch and review on each release. It targets CakePHP 5.4 on PHP 8.2 or later and was checked against the official documentation on 7 October 2026. Hosting-specific steps (server provisioning, TLS certificates, backups) are outside its scope, but the items here apply on any VPS, container platform or managed PHP host.

Technician holding a laptop while working at an open server rack in a data centre
A repeatable checklist matters more than heroics on release day. Photo: Derrick Coetzee, CC0.

1. Configuration and secrets

The book recommends putting configuration that is shared across environments in config/app.php, and environment-specific values in config/app_local.php or environment variables. The skeleton already reads the important values from the environment:

  • [ ] debug is false. The skeleton's config/app.php reads DEBUG with a default of false, but config/app_local.example.php defaults it to true. Make sure production does not inherit the local file's default.
  • [ ] SECURITY_SALT is set to a long random value that is unique to this environment and stored outside the repository. The salt is used in security hashing and as the encryption key.
  • [ ] APP_FULL_BASE_URL is set (for App.fullBaseUrl), including the scheme, for example https://www.example.com.
  • [ ] Database credentials come from DATABASE_URL or a server-only app_local.php, and the database user has only the privileges the application needs.
  • [ ] config/app_local.php and any .env file are excluded from version control and from build artefacts.
PHP
// config/app_local.php on the server (values come from the environment)
use function Cake\Core\env;

return [
    'debug' => filter_var(env('DEBUG', false), FILTER_VALIDATE_BOOLEAN),
    'Security' => [
        'salt' => env('SECURITY_SALT'),
    ],
    'Datasources' => [
        'default' => [
            'url' => env('DATABASE_URL'),
        ],
    ],
];

Why debug matters so much: according to the deployment guide, turning it off disables debug(), pr() and dd() output, replaces detailed error pages and stack traces with generic ones, hides PHP warnings, and extends the core cache duration from 10 seconds to 365 days.

Why App.fullBaseUrl is now required

The configuration guide advises setting App.fullBaseUrl manually if you are concerned about Host header manipulation, and it is needed to build absolute URLs from the command line, for example in emails sent by a cron job. The current 5.x skeleton goes further: its App\Middleware\HostHeaderMiddleware throws an error in production when App.fullBaseUrl is not configured, and rejects requests whose Host header does not match it. If you built your application from an older skeleton, consider adding the same check.

2. Web server and file permissions

  • [ ] The document root is webroot/, not the project root. The deployment guide calls this an important step: it makes application code and configuration files unreachable by URL and prevents files outside webroot/ from being executed.
  • [ ] The web server's PHP version matches the CLI PHP version, and both are 8.2 or later with mbstring, intl, pdo (plus the right PDO driver) and simplexml.
  • [ ] tmp/ and logs/, including subdirectories, are writable by the web server user and the user that runs bin/cake. The installation guide shows ACL- and chmod-based ways to do this.
  • [ ] The built-in bin/cake server is not used; the book says it is for development only.

3. HTTPS, CSRF and security headers

CakePHP ships middleware for each of these; you add it in Application::middleware().

  • [ ] HTTPS is enforced with HttpsEnforcerMiddleware, ideally with HSTS. If a proxy or load balancer terminates TLS, list it in trustProxies so forwarded headers are only trusted from it.
  • [ ] CSRF protection is on for every route that uses cookies or sessions. Use one of CsrfProtectionMiddleware (cookie) or SessionCsrfProtectionMiddleware (session), never both. The skeleton adds the cookie version with httponly enabled; in production also set secure and a samesite value.
  • [ ] Security headers are sent with SecurityHeadersMiddleware: X-Content-Type-Options, X-Frame-Options, Referrer-Policy and, if needed, Permissions-Policy.
  • [ ] A Content Security Policy is considered. CspMiddleware requires the paragonie/csp-builder package and can add script and style nonces to tags created by HtmlHelper. Since 5.4, FormHelper no longer emits inline display:none styles, which makes a strict policy easier.
  • [ ] Form tampering protection is considered: the deployment guide suggests enabling FormProtectionComponent, and every table has validation rules.
PHP
// src/Application.php, inside middleware(), after the error handler
use Cake\Http\Middleware\HttpsEnforcerMiddleware;
use Cake\Http\Middleware\SecurityHeadersMiddleware;

$middlewareQueue->add(new HttpsEnforcerMiddleware([
    'redirect' => true,
    'statusCode' => 301,
    'disableOnDebug' => true,
    'hsts' => [
        'maxAge' => 60 * 60 * 24 * 365,
        'includeSubDomains' => true,
        'preload' => false,
    ],
]));

$securityHeaders = (new SecurityHeadersMiddleware())
    ->setReferrerPolicy()
    ->setXFrameOptions()
    ->noOpen()
    ->noSniff();
$middlewareQueue->add($securityHeaders);

Only enable HSTS preload once every subdomain serves HTTPS correctly; browsers cache the policy for the full maxAge.

Row of open server racks with network patch panels on a raised data-centre floor
Production configuration decides how safely and quickly your application runs. Photo: Carl Lender, CC BY 2.0.

4. Performance

  • [ ] Optimised autoloader. Run composer dump-autoload -o (or composer install --no-dev --optimize-autoloader) on each deploy. The deployment guide notes that class loading can take a large share of processing time.
  • [ ] Plugin assets symlinked. Serving plugin assets through the dispatcher is inefficient; run bin/cake plugin assets symlink (or copy where symlinks are not allowed).
  • [ ] Assertions off. CakePHP uses assert() for development-time type checks. Setting zend.assertions = -1 in php.ini skips them; the book recommends this for applications with good test coverage or static analysis.
  • [ ] A real cache engine. On multi-server deployments, point the default and ORM metadata caches at a shared engine such as Redis or Memcached instead of local files, and enable OPcache in PHP.
  • [ ] Pagination limits. Check that public listings set maxLimit and sortableFields so visitors cannot request huge pages or sort on unindexed columns.

5. The deploy script

The deployment guide lists the tasks to coordinate on every release. A minimal script for a server that pulls from Git looks like this:

Shell
#!/usr/bin/env bash
set -euo pipefail

git fetch --tags
git checkout "$RELEASE_TAG"

# Never "composer update" on a server: install exactly what the lock file says.
composer install --no-dev --optimize-autoloader --no-interaction

bin/cake migrations migrate
bin/cake schema_cache clear
bin/cake schema_cache build --connection default
bin/cake plugin assets symlink
  • [ ] Dependencies are installed with composer install from the committed lock file. The book warns that composer update during a deploy can bring in unexpected versions.
  • [ ] Database migrations run as part of the release, and destructive migrations are reviewed and backed up first.
  • [ ] The ORM schema cache is cleared and rebuilt so the application sees new columns. schema_cache build can rebuild in place without clearing existing data first.
  • [ ] If you deploy by FTP or by copying files, fix file and folder permissions afterwards, as the guide warns.
  • [ ] PHP-FPM is reloaded (or a new container rolled out) so OPcache picks up the new code.

6. Errors, logs and monitoring

  • [ ] Custom error400.php and error500.php templates exist in templates/Error/, and you have checked them with debug off, since debug mode shows the developer error page instead.
  • [ ] API routes return JSON errors (for example with a prefix-specific ErrorController that declares JsonView).
  • [ ] Logs are written somewhere durable and rotated, and sensitive values are kept out of them. CakePHP 5.4 adds LoggedQuery::setRedactor() for query logs and Text::mask() helpers.
  • [ ] DebugKit is a development dependency only and is not loaded in production.
  • [ ] Uptime and error-rate alerts are configured, and someone is named to receive them.

7. Staying supported

  • [ ] The application runs on a supported line. In October 2026 that is CakePHP 5.2 to 5.4; only 5.4 has active support, and 4.x security support ended on 10 September 2026.
  • [ ] composer.json pins "cakephp/cakephp": "5.4.*" so that patch releases arrive automatically but minors only when you choose.
  • [ ] A dependency vulnerability check runs in CI, and patch releases are applied promptly.

Before the first launch only

  • [ ] Generate a new salt for production; never reuse the development or staging value.
  • [ ] Request a known missing URL and confirm you see your custom 404 page, not a stack trace.
  • [ ] Request the site with a different Host header and confirm it is rejected.
  • [ ] Fetch /config/app_local.php and /composer.json by URL and confirm both return 404.
  • [ ] Check response headers in the browser developer tools for HSTS and the security headers you configured.

Summary

A safe CakePHP 5 production setup comes down to a handful of decisions: debug off, secrets and App.fullBaseUrl from the environment, webroot/ as the document root, HTTPS with HSTS, CSRF and security headers, an optimised autoloader and warm caches, and a deploy script that installs from the lock file, migrates and rebuilds the schema cache. Copy the checklists above into your release template and tick them for every launch.

Frequently asked questions

  • What happens when debug is turned off in CakePHP?

    Debug output from debug(), pr() and dd() is disabled, generic error pages replace stack traces, PHP warnings are hidden, and core caches last 365 days instead of 10 seconds.

  • Why does my CakePHP 5 app fail in production with an App.fullBaseUrl error?

    The current cakephp/app skeleton includes a host-header middleware that requires App.fullBaseUrl when debug is off. Set the APP_FULL_BASE_URL environment variable to your site's full URL.

  • What should the document root be for a CakePHP site?

    The application's webroot/ directory, so that code and configuration files cannot be reached through a URL.

  • Do I need to clear any cache after a deploy?

    Yes. After migrations, clear and rebuild the ORM metadata cache with bin/cake schema_cache clear and bin/cake schema_cache build.

Advertise on CloudSoftZone

Your next customer could start right here.

Introduce your tool, product or business to readers exploring technology.

Advertise with us

Explore placements and request a private quote

Sources

  1. Deployment — CakePHP Book (5.x)
  2. Configuration — CakePHP Book (5.x)
  3. HTTPS Enforcer Middleware — CakePHP Book (5.x)
  4. Security Header Middleware — CakePHP Book (5.x)
  5. CSRF Protection — CakePHP Book (5.x)
  6. Content Security Policy Middleware — CakePHP Book (5.x)
  7. Schema Cache Tool — CakePHP Book (5.x)
  8. cakephp/app HostHeaderMiddleware (5.x branch) — CakePHP on GitHub

Written with substantial AI assistance. Facts checked against cited sources. Editorial policy.

Comments

No comments yet. Be the first to join the conversation.

Leave a comment

Every comment is read by a moderator before it appears. Your email address is never published; it is used only to contact you about this comment.

Never published. Used only to contact you about this comment.

Loading the security check…

Comments are moderated before publication.

  • Plush elePHPant toy from Heroku, a version of the PHP community mascot, photographed close up

    Laravel

    Upgrading from Laravel 12 to Laravel 13: a practical guide

    Laravel 12 lost bug-fix support in August 2026. This guide covers the PHP 8.3 requirement, Composer changes, the CSRF middleware rename, cache and session hardening, low-impact changes that often bite, and a safe rollout plan.

    By Cloudsoft Zone