Apache HTTP Server
Apache HTTP Server (commonly referred to as “Apache”) is one of the most widely used web servers in the world. It is maintained by the Apache Software Foundation and offers robust, flexible, and highly configurable capabilities for serving static and dynamic content. Over the decades, Apache has become a cornerstone of the modern web, powering websites of all sizes, from personal blogs to large enterprise systems. This guide explores Apache’s architecture, configuration files, modules, and common tasks. ASCII diagrams provide insight into request flows and how Apache interacts with operating system resources and other services.
Core Architecture and Concepts
Process Models (MPMs)
Apache’s architecture revolves around “Multi-Processing Modules” (MPMs) that define how it manages child processes or threads to handle incoming requests. Common MPMs include:
- Prefork: Spawns multiple child processes, each handling one request at a time using a single thread. Historically favored for compatibility with non-thread-safe modules (like certain older PHP modules).
- Worker: Uses a pool of child processes, each containing multiple threads, which can handle more requests concurrently with fewer system processes.
- Event: Similar to Worker but optimizes keep-alive connections by assigning them to dedicated threads, potentially reducing thread blocking.
A simplified diagram of how Apache might handle connections using the Worker MPM:
+----------------+ (Incoming Connections)
| Internet | ------------+
| (Clients) | |
+--------+-------+ |
| |
v v
+-----------+ +-----------+ +-----------+
| Apache | | Apache | | Apache |
| Parent |... | Child1 |.. | Child2 |...
| Process | +-----+-----+ +-----+-----+
+-----------+ | |
(Thread 1,2,...n) (Thread 1,2,...n)
In this diagram, the main Apache parent process spawns child processes (in Worker/Event MPM) that each manage a pool of threads. Each thread can handle one client connection at a time.
Installation and Directory Structure
Installation
How you install Apache depends on your OS:
- Debian/Ubuntu:
sudo apt-get update sudo apt-get install apache2 - CentOS/Red Hat:
sudo yum install httpd - macOS (Homebrew):
brew install httpd
Once installed, Apache typically runs as a service (e.g., apache2.service or httpd.service). You can start, stop, or restart it via your distribution’s service manager (systemctl, service, etc.).
Key Directories and Files
Although file paths vary across distributions, a general layout might look like this:
/etc/apache2/ (Debian/Ubuntu) or /etc/httpd/ (Red Hat/CentOS)
├── apache2.conf or httpd.conf (Main config file)
├── mods-available/ or modules.d/
├── mods-enabled/
├── sites-available/
├── sites-enabled/
└── conf.d/ (Additional config fragments)
- httpd.conf / apache2.conf: Primary configuration file.
- sites-available/ and sites-enabled/: Where virtual host configurations are stored (Debian/Ubuntu style).
- mods-available/ and mods-enabled/: Scripts or configuration files that load modules.
- conf.d/: Additional global configuration snippets.
Core Configuration Files
Main Configuration (httpd.conf or apache2.conf)
This file sets up fundamental directives like ServerRoot, ServerAdmin, ServerName, MPM settings, and includes references to other config files. For example:
ServerRoot "/etc/httpd"
ServerAdmin admin@example.com
ServerName www.example.com
Listen 80
LoadModule mpm_event_module modules/mod_mpm_event.so
LoadModule rewrite_module modules/mod_rewrite.so
# ...
Include conf.modules.d/*.conf
Include conf.d/*.confVirtual Hosts
Virtual hosts allow Apache to serve different websites or applications from a single server instance by matching domain names or IP addresses. A common pattern on Debian-based systems is to have site-specific config files in sites-available/, then symlink them into sites-enabled/. A simple mywebsite.conf might look like:
<VirtualHost *:80>
ServerName mywebsite.com
ServerAlias www.mywebsite.com
DocumentRoot /var/www/mywebsite
<Directory /var/www/mywebsite>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
ErrorLog /var/log/apache2/mywebsite_error.log
CustomLog /var/log/apache2/mywebsite_access.log combined
</VirtualHost>Then enable it (Debian/Ubuntu style) via:
sudo a2ensite mywebsite
sudo systemctl reload apache2On Red Hat-based systems, you manually include it in httpd.conf or place it in conf.d/, ensuring NameVirtualHost *:80 is set if needed (for older versions).
Modules (mods-available / mods-enabled)
Apache’s functionality can be extended with modules such as mod_rewrite (URL rewriting), mod_ssl (SSL/TLS), mod_proxy (reverse proxy), etc.
On Debian-based systems, commands like a2enmod and a2dismod enable or disable modules. On Red Hat-based systems, you typically edit httpd.conf or a related file to load them (e.g., LoadModule rewrite_module modules/mod_rewrite.so).
Serving Static Files
Apache can serve static assets like HTML, CSS, images, and more. By default, the DocumentRoot directive designates the root directory for static content. For instance, if DocumentRoot is /var/www/html, then requests to http://server/index.html map to /var/www/html/index.html.
<VirtualHost *:80>
DocumentRoot /var/www/html
<Directory "/var/www/html">
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
</Directory>
</VirtualHost>Dynamic Content with Modules
mod_php or PHP-FPM
To serve PHP pages, Apache traditionally used mod_php which runs PHP code within the Apache worker processes. However, a more modern approach is using mod_proxy_fcgi with PHP-FPM:
<VirtualHost *:80>
ServerName phpexample.com
DocumentRoot /var/www/phpapp
<FilesMatch \.php$>
SetHandler "proxy:unix:/run/php/php7.4-fpm.sock|fcgi://localhost/"
</FilesMatch>
</VirtualHost>In this case, .php requests are forwarded through a FastCGI socket managed by PHP-FPM. This separation can offer better security and performance than older mod_php approaches.
mod_wsgi (Python)
For Python-based applications (e.g., Django or Flask), mod_wsgi is commonly used:
<VirtualHost *:80>
ServerName pythonapp.com
WSGIDaemonProcess myapp python-path=/var/www/myapp
WSGIScriptAlias / /var/www/myapp/myapp/wsgi.py process-group=myapp
<Directory /var/www/myapp/myapp>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
</VirtualHost>mod_jk or AJP for Java (Tomcat)
When integrating with Tomcat, you might use the AJP connector and mod_jk. The configuration references a workers.properties file specifying the Tomcat backend.
Reverse Proxy and Load Balancing
Apache’s mod_proxy can forward requests to another server or service, acting as a reverse proxy. For example:
<VirtualHost *:80>
ServerName proxyexample.com
ProxyPreserveHost On
ProxyRequests Off
<Location />
ProxyPass http://127.0.0.1:3000/
ProxyPassReverse http://127.0.0.1:3000/
</Location>
</VirtualHost>Requests to http://proxyexample.com/ are internally proxied to a local service on port 3000. For load balancing multiple backends, use mod_proxy_balancer:
<Proxy balancer://mycluster>
BalancerMember http://192.168.0.10:3000
BalancerMember http://192.168.0.11:3000
</Proxy>
<VirtualHost *:80>
ProxyPreserveHost On
<Location /api/>
ProxyPass balancer://mycluster/
ProxyPassReverse balancer://mycluster/
</Location>
</VirtualHost>Apache can distribute requests among those two servers using the default (round-robin) or other algorithms.
SSL/TLS Configuration with mod_ssl
Enable HTTPS to secure traffic. On many systems, mod_ssl is included but may need enabling (a2enmod ssl on Debian/Ubuntu). Then configure a virtual host on port 443:
<VirtualHost *:443>
ServerName secure.example.com
SSLEngine on
SSLCertificateFile /etc/ssl/certs/example.crt
SSLCertificateKeyFile /etc/ssl/private/example.key
DocumentRoot /var/www/secure
<Directory "/var/www/secure">
Require all granted
</Directory>
</VirtualHost>You can enforce HTTP to HTTPS redirection:
<VirtualHost *:80>
ServerName secure.example.com
Redirect / https://secure.example.com/
</VirtualHost>Logging and Monitoring
Apache logs requests and errors in typically two separate files:
- Access Log: By default, stored in
/var/log/apache2/access.logor/var/log/httpd/access_log. Captures each request line, status code, bytes sent, user agent, etc. - Error Log:
/var/log/apache2/error.logor/var/log/httpd/error_logfor errors, warnings, and diagnostic messages.
You can customize the log format using the LogFormat directive:
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
CustomLog /var/log/apache2/access.log combinedMonitoring solutions like GoAccess, AWStats, or Elastic Stack can parse and visualize these logs, revealing traffic volumes, response codes, and performance bottlenecks.
Performance Tuning
MPM Settings
For the worker or event MPM, you might configure:
<IfModule mpm_worker_module>
StartServers 2
MinSpareThreads 25
MaxSpareThreads 75
ThreadLimit 64
ThreadsPerChild 25
MaxRequestWorkers 150
MaxConnectionsPerChild 0
</IfModule>The MaxRequestWorkers sets the total threads available. Adjust these for your application’s concurrency needs.
KeepAlive
Keep-alive allows multiple requests over a single TCP connection, reducing overhead. You can tweak:
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 5Compression
Use mod_deflate to compress text-based responses:
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css application/javascript
</IfModule>Caching Headers and mod_expires
Set caching headers for static content:
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType text/css "access plus 7 days"
ExpiresByType application/javascript "access plus 7 days"
ExpiresByType image/png "access plus 30 days"
</IfModule>Security Hardening
- Disable Unused Modules: Turn off modules you don’t need (e.g.,
mod_autoindexif you don’t want directory listings). - Hide Apache Version: Set
ServerTokens ProdandServerSignature Offto not reveal internal version details. - Use Strong TLS Ciphers: Adjust
SSLCipherSuiteandSSLProtocolto avoid outdated cryptography. - Restrict .htaccess: If possible, manage config at the server or virtual host level instead of allowing arbitrary
.htaccessoverrides. - WAF: Consider adding a Web Application Firewall module, like ModSecurity, to block malicious traffic.
Common Administrative Tasks
Starting and Stopping
Use your system’s service manager:
sudo systemctl start apache2 # Debian/Ubuntu
sudo systemctl enable apache2
sudo systemctl stop httpd # Red Hat/CentOSReloading Configuration
To apply config changes without dropping active connections abruptly:
sudo systemctl reload apache2 # or httpdChecking Configuration
Apache has a built-in config test:
apachectl configtestor
httpd -tIt reports syntax errors and other issues before you reload or restart.
Example Architecture Diagram
Internet
|
(Requests on Port 80/443)
|
v
+-------------------+ +-----------------------+
| Apache | | Additional Modules: |
| (HTTP/HTTPS) |----->| - mod_security |
| [VirtualHosts] | | - mod_rewrite |
| [mod_proxy, etc.] | | - mod_ssl |
+---------+---------+ +-----------------------+
| Reverse Proxy or Localhost
| for dynamic web apps
v
+--------------------+
| Backend Service | (PHP-FPM, Tomcat, Python WSGI, etc.)
+--------------------+
|
v
[Database, Other APIs]
In this diagram, Apache listens on ports 80 or 443. Static files are served directly, while dynamic requests are routed to backend services (PHP-FPM, Tomcat, etc.) or proxied to external APIs.