Capstone: Designing and Hardening a Production Apache Deployment
Apache In Depth
Chapter 10 · Capstone: Designing and Hardening a Production Apache Deployment
Web Servers Fundamentals' own capstone compared three servers across several scenarios. This one is different, by design — the same shape Nginx In Depth's own capstone used: a single, cohesive worked example, layering in each of this course's own eight prior chapters, one at a time, until one complete, production-shaped configuration exists.
The Scenario
One Apache instance hosts two real things: a customer-facing PHP web application at www.example.com, and a small internal API — a separate Node.js service — proxied at api.example.com. Both need HTTPS, sensible performance, and hardening that reflects everything this course has covered.
Step 1 — MPM Choice (Chapter 2)
The PHP application runs on PHP-FPM, not traditional mod_php — per Chapter 2, that's exactly what frees Apache to run Event here instead of being forced onto Prefork, gaining Event's lower per-connection overhead for both the PHP site and the proxied API sharing this same instance.
Step 2 — Locking Down .htaccess (Chapter 3)
Every piece of configuration for both sites lives in version-controlled main config files, not scattered .htaccess overrides — so AllowOverride None applies globally, per Chapter 3's own hardening payoff: this removes the per-request filesystem scan entirely and closes off an entire class of misconfiguration risk from a stray or compromised .htaccess file, with nothing lost since neither site actually needs one.
Step 3 — Core Modules for the PHP App (Chapter 4)
Clean article URLs via mod_rewrite, a baseline security header via mod_headers, and compression for the PHP app's own text-based output via mod_deflate — the three Chapter 4 modules, all falling under the same FileInfo group Step 2 didn't need to grant anywhere else.
Step 4 — Two Domains, One Apache Instance (Chapter 5)
Both domains share the same IP and port, distinguished purely by ServerName — modern name-based hosting over HTTPS, made possible entirely by SNI (Chapter 5), with no separate IP needed per domain the way it would have before SNI existed.
Step 5 — TLS Hardening (Chapter 6)
Applied inside each <VirtualHost *:443> block: the modern combined-chain certificate file, a fail-safe SSLProtocol line, a curated cipher list, and OCSP stapling so clients confirm certificate validity without a live round-trip to the CA — all four directly from Chapter 6.
Step 6 — Proxying the Internal API (Chapter 7)
Inside api.example.com's own <VirtualHost>: a two-member balanced pool using bybusyness, since this API's own endpoints vary widely in response time, and ProxyPreserveHost On so the Node.js service sees the real requested hostname rather than the internal pool address — exactly the gotcha Chapter 7's own warning box covered.
Step 7 — Access Control & mod_security (Chapter 8)
The API's own internal metrics endpoint is IP-restricted to the private network via Require ip — controlling who can reach it. Site-wide, mod_security with the OWASP Core Rule Set starts in DetectionOnly, per Chapter 8's own recommended rollout, rather than risking false-positive outages by enabling On from day one.
Step 8 — Performance, Logging & Pre-Flight Checks (Chapter 9)
KeepAliveTimeout 15 is comfortably affordable specifically because Step 1 chose Event, not Prefork — the same setting would have cost real MaxRequestWorkers capacity under Prefork, per Chapter 2's own math. Caching is scoped to /static/ only, deliberately excluding the PHP app's own logged-in pages, per Chapter 9's own warning about personalized content and cache hit rate. apachectl configtest is the last, non-negotiable step before any of this ever gets reloaded live.
| Capstone Step | Chapter It Draws From |
|---|---|
| Step 1 — MPM choice | Chapter 2 |
| Step 2 — AllowOverride None | Chapter 3 |
| Step 3 — mod_rewrite/headers/deflate | Chapter 4 |
| Step 4 — Name-based hosting via SNI | Chapter 5 |
| Step 5 — TLS hardening | Chapter 6 |
| Step 6 — Proxying & load balancing | Chapter 7 |
| Step 7 — Access control & mod_security | Chapter 8 |
| Step 8 — Performance, caching & logging | Chapter 9 |
apachectl configtest) before every reload, a gradual rollout rather than switching all traffic at once, and real alerting configured on top of whatever monitoring is in place — well beyond mod_status's or balancer-manager's own live snapshots. Treat this chapter's config as a strong, correct starting point, not a substitute for an actual deployment process.
Hands-On Exercises
This capstone applies AllowOverride None globally in Step 2, even though earlier chapters spent real time explaining how .htaccess and AllowOverride's named groups work. Explain why this is not a contradiction, referencing this chapter's own reasoning.
📄 View solutionA new /account/ endpoint is added to the PHP app, showing each logged-in user their own personalized order history. Should it be added to the CacheEnable disk zone the same way /static/ was in Step 8? Explain your answer using this course's own material.
📄 View solutionWrite a short chapter-attribution summary (2-3 sentences) explaining how this capstone's own shape differs from Web Servers Fundamentals' own capstone, and why that difference makes sense given what each course actually covers.
📄 View solutionApache In Depth — 10 of 10 chapters complete. The Web Servers subject now has its comparative foundation, its Nginx deep dive, and its Apache deep dive.
Chapter 10 Quick Reference
- This capstone builds one cohesive production config for two real domains, layering in Chapters 2 through 9 step by step — the same deliberate shape as Nginx In Depth's own capstone, and a different one from Web Servers Fundamentals' own multi-scenario decision framework
- PHP-FPM (not
mod_php) is what makes choosing Event over Prefork possible in Step 1 — a payoff planted all the way back in Chapter 2 - Only non-personalized content belongs in a
mod_cache_diskzone; personalized pages needCache-Control: privaterespected instead, not a cleverly-keyed cache (Chapter 9) - A working config is a foundation, not a complete production rollout —
apachectl configtest, gradual deployment, and real alerting still matter beyond this chapter's own scope