Last modified: January 24, 2026

This article is written in: 🇺🇸

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:

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:

CODE_BLOCK_PLACEHOLDER - CentOS/Red Hat:

CODE_BLOCK_PLACEHOLDER - macOS (Homebrew):

sudo apt-get update
  sudo apt-get install apache2

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:

sudo yum install httpd

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:

brew install httpd

Virtual 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:

/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)

Then enable it (Debian/Ubuntu style) via:

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/*.conf

On 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>
    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>

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:

sudo a2ensite mywebsite
sudo systemctl reload apache2

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>
    DocumentRoot /var/www/html
    <Directory "/var/www/html">
        Options Indexes FollowSymLinks
        AllowOverride None
        Require all granted
    </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 phpexample.com
    DocumentRoot /var/www/phpapp

    <FilesMatch \.php$>
        SetHandler "proxy:unix:/run/php/php7.4-fpm.sock|fcgi://localhost/"
    </FilesMatch>
</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:

<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>

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 *: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>

You can enforce HTTP to HTTPS redirection:

<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>

Logging and Monitoring

Apache logs requests and errors in typically two separate files:

You can customize the log format using the LogFormat directive:

<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>

Monitoring 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:

<VirtualHost *:80>
    ServerName secure.example.com
    Redirect / https://secure.example.com/
</VirtualHost>

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:

LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
CustomLog /var/log/apache2/access.log combined

Compression

Use mod_deflate to compress text-based responses:

<IfModule mpm_worker_module>
    StartServers           2
    MinSpareThreads       25
    MaxSpareThreads       75
    ThreadLimit           64
    ThreadsPerChild       25
    MaxRequestWorkers     150
    MaxConnectionsPerChild 0
</IfModule>

Caching Headers and mod_expires

Set caching headers for static content:

KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 5

Security Hardening

  1. Disable Unused Modules: Turn off modules you don’t need (e.g., mod_autoindex if you don’t want directory listings).
  2. Hide Apache Version: Set ServerTokens Prod and ServerSignature Off to not reveal internal version details.
  3. Use Strong TLS Ciphers: Adjust SSLCipherSuite and SSLProtocol to avoid outdated cryptography.
  4. Restrict .htaccess: If possible, manage config at the server or virtual host level instead of allowing arbitrary .htaccess overrides.
  5. 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:

<IfModule mod_deflate.c>
    AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css application/javascript
</IfModule>

Reloading Configuration

To apply config changes without dropping active connections abruptly:

<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>

Checking Configuration

Apache has a built-in config test:

CODE_BLOCK_PLACEHOLDER or

sudo systemctl start apache2   # Debian/Ubuntu
sudo systemctl enable apache2

sudo systemctl stop httpd      # Red Hat/CentOS

It reports syntax errors and other issues before you reload or restart.

Example Architecture Diagram

sudo systemctl reload apache2  # or httpd

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.