A production checklist for PHP behind Cloudflare and Apache

A release checklist for the complete request path: DNS, Cloudflare, TLS, Apache rewrites, PHP runtime, trusted proxy headers, caching, security boundaries, and rollback.

PHPCloudflareApacheDeploymentSecurityCaching
Production request path through DNS, Cloudflare, Apache, PHP, and MySQL

A PHP release behind Cloudflare and Apache crosses several independent systems before application code runs. DNS chooses a destination, Cloudflare may terminate the public connection and apply edge rules, Apache selects a virtual host and rewrites the path, PHP executes under a configured runtime, and the application reaches its database and external services. A green check from one layer does not prove the whole path is correct.

This checklist is designed for a production deployment or migration where clean URLs, HTTPS, client IPs, cache behavior, private files, and background application features matter. It favors small verifiable steps and a defined rollback over changing DNS, SSL, rewrite rules, and application code at the same time.

Record the current state before the release

Capture the active DNS records, Cloudflare proxy status, SSL mode, important edge rules, origin address, Apache virtual-host configuration, PHP version and extensions, document root, application URL, writable paths, scheduled jobs, and database target. Store this operational record privately. It should describe secret names and locations without copying secret values.

Confirm who controls the registrar, Cloudflare zone, host, database, and deployment process. A rollback is not real if the person performing the release cannot restore the previous DNS value, certificate configuration, application package, or database state. Take a source and database backup appropriate to the change, then verify that each artifact is readable and non-empty.

Verify DNS without assuming the proxy

Check the authoritative nameservers and the exact A, AAAA, and CNAME records for every supported hostname. An old IPv6 record can send part of the traffic to a different server even when IPv4 looks correct. Preserve mail-related MX, SPF, DKIM, DMARC, and verification records when changing website DNS.

Know whether each web record is proxied. A proxied record returns Cloudflare addresses to public clients, while a DNS-only record exposes the origin directly. During diagnosis, do not switch the entire zone to DNS-only without considering origin exposure, certificate behavior, and security controls. Use a narrow authorized origin test when possible.

Treat public TLS and origin TLS separately

The browser establishes one TLS connection to Cloudflare, and Cloudflare establishes another connection to the origin when proxying HTTPS. Both require deliberate configuration. Confirm that the edge certificate covers every public hostname. At the origin, use a valid certificate for the requested host and prefer a strict validation mode once the origin certificate is correct.

A redirect loop often appears when the application believes the origin request is HTTP while the visitor used HTTPS at the edge. Configure trusted proxy handling so the application recognizes the forwarded scheme only when the request came from the authorized proxy network. Do not trust arbitrary forwarded headers from any direct client.

Follow HTTP redirects with a client that displays each hop. The intended result is normally one canonical HTTPS hostname and path. Repeated transitions between HTTP and HTTPS, or between www and the apex hostname, show that multiple layers are enforcing conflicting canonical rules.

Check the Apache application boundary

Confirm the virtual host points to the intended document root and permits the application’s override policy if it depends on an .htaccess file. Verify that mod_rewrite is enabled and test the actual clean routes, not only a direct index.php request. A PHP homepage can work while every detail route returns a server 404.

Review rewrite ordering. Canonical redirects should run only for direct client requests and should not redirect an internal rewrite back to itself. Public routes must be evaluated before a broad catch-all such as a configurable admin segment. Missing paths should reach the application’s 404 response with the correct HTTP status.

Test denial rules from outside the server. Environment files, configuration, source data, database tools, logs, tests, vendor internals, private documentation, and backup archives should not be downloadable. Directory listing should be disabled. Do not assume a dot-prefixed filename is protected automatically by every Apache configuration or upstream cache.

Validate the PHP runtime used by the web server

The command-line PHP version may differ from the version running under Apache or PHP-FPM. Use a temporary protected diagnostic or server control panel to confirm the web runtime, then remove it. Check required extensions, timezone, memory and upload limits, session storage, error logging, and process ownership.

Production should log errors privately and avoid displaying stack traces, file paths, SQL, or credentials to visitors. Confirm that required writable directories are narrowly scoped and that application source is not generally writable by the web process. If Composer dependencies are installed on the server, use optimized production settings and omit development packages.

Preserve the real client IP safely

When Cloudflare proxies a request, Apache sees a Cloudflare address as its network peer. Application rate limits and audit logs may need the visitor address, but the corresponding header is trustworthy only when the immediate peer is an approved Cloudflare network. Configure the web server or application to restore client addresses from documented proxy ranges and retain enough protected context to investigate abuse.

Test both proxied traffic and any authorized direct-origin diagnostic. A public origin that accepts a client-IP header from everyone lets an attacker choose the identity used by logs and rate limits. Restrict direct access where possible and never use an unvalidated forwarding header as an authentication decision.

Design cache rules around data ownership

Versioned CSS, JavaScript, fonts, and images can use long immutable browser caching because a changed file receives a changed URL. HTML, database-backed pages, APIs, and authentication routes need revalidation or an explicit shorter policy. Never apply a “cache everything” rule across an admin area, contact submission, personalized response, or write endpoint.

Cloudflare cache rules, Apache headers, application headers, and a service worker can all affect the same URL. List them in evaluation order. Confirm that cache keys separate representations that differ by authentication or request headers, and that a service worker does not retain no-store admin responses.

When the application publishes new projects or articles, verify how page caches, API caches, sitemaps, and offline manifests discover the change. Purging the entire zone after every edit hides unclear invalidation boundaries; it should not become the normal content workflow.

Release in a reversible order

  1. Verify source and database backups and record the current release identifier.
  2. Upload the new package outside the active path or use the host’s atomic release mechanism.
  3. Install production dependencies and build versioned assets.
  4. Run reviewed database migrations before code depends on the new schema, or use a compatible two-stage migration.
  5. Apply private environment configuration without packaging it into the public archive.
  6. Activate the release and verify local origin health.
  7. Verify proxied public routes, headers, cache behavior, APIs, and write workflows.
  8. Keep the previous application package and database recovery path until the monitoring window passes.

Test representative production paths

  • Root, canonical redirects, clean fixed routes, detail routes, and an unknown route.
  • Static CSS, JavaScript, fonts, images, compression, and immutable versions.
  • Login or admin denial, session cookie flags, CSRF-protected writes, and no-store responses.
  • Database-backed lists, detail pages, search, sitemap, robots policy, and structured data.
  • Contact or another write workflow with validation, rate limits, delivery failure, and replay protection.
  • Service-worker registration, cache version activation, and a warmed offline path if the product promises it.
  • Mobile layout, keyboard navigation, focus states, and reduced motion.

Monitor evidence, not only uptime

A 200 response from the homepage can hide a failed database connection, broken queue, wrong client IP, stale cache, rejected webhook, or inaccessible media path. During the release window, inspect protected PHP errors, Apache errors, database fallback logs, external delivery failures, and application health indicators that correspond to the changed workflows.

Record the final DNS, SSL, origin, cache, and release state after verification. If rollback is required, restore one coherent known state rather than combining old application code with a new incompatible schema. A disciplined release leaves the next investigation easier than the last one.

Discuss a project