LinuxIntermediate 12 min Lesson 21 of 24

Apache

The other major web server: how its configuration differs from Nginx, when it is the better choice, and how to run it well.

Linux · Lesson 21 of 24
0/24 done(0%)

What is it? #

Apache is the other web server you will meet on servers, particularly on older systems and in PHP hosting.

Its distinguishing features are modules and .htaccess. Functionality is enabled by loading modules, and directories can carry their own configuration file that Apache reads at request time.

That per-directory configuration is convenient in shared hosting, where users cannot edit the main configuration, and it is a performance cost everywhere else.

Architecturally, Apache traditionally used a process or thread per connection, while Nginx uses an event loop. Modern Apache offers an event-based mode too, but Nginx remains the lighter choice for high-concurrency static serving.

Think of it like this #

A workshop where each room can have its own posted rules, checked every time someone walks in.

Flexible when many different people use different rooms. Slower than having one set of rules read once at the start of the day.

Simple example #

A server hosts a PHP application that expects Apache and .htaccess rewrite rules, plus a proxied application on another domain.

Code #

TEXT
File layout (Debian/Ubuntu)

/etc/apache2/
├── apache2.conf              main configuration
├── mods-available/           all modules
├── mods-enabled/             symlinks to active modules
├── sites-available/          all virtual hosts
└── sites-enabled/            symlinks to active ones

On RHEL/Rocky it is /etc/httpd/ with conf.d/ instead.
APACHE
# /etc/apache2/sites-available/example.com.conf
<VirtualHost *:80>
    ServerName example.com
    Redirect permanent / https://example.com/
</VirtualHost>

<VirtualHost *:443>
    ServerName example.com
    DocumentRoot /var/www/example.com/public

    SSLEngine on
    SSLCertificateFile    /etc/letsencrypt/live/example.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem

    <Directory /var/www/example.com/public>
        Options -Indexes +FollowSymLinks
        AllowOverride All            # permits .htaccess — set to None if unused
        Require all granted
    </Directory>

    # Proxy an application on another path
    ProxyPreserveHost On
    ProxyPass        /api/ http://127.0.0.1:8000/
    ProxyPassReverse /api/ http://127.0.0.1:8000/
    RequestHeader set X-Forwarded-Proto "https"

    ErrorLog  ${APACHE_LOG_DIR}/example.error.log
    CustomLog ${APACHE_LOG_DIR}/example.access.log combined
</VirtualHost>
BASH
# Modules and sites are managed with helper commands
sudo a2enmod rewrite ssl proxy proxy_http headers
sudo a2ensite example.com
sudo a2dissite 000-default

sudo apachectl configtest        # equivalent of nginx -t
sudo systemctl reload apache2
APACHE
# .htaccess in the document root — read on every request
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [L]        # front controller pattern

<FilesMatch "\.(env|log|sqlite)$">
    Require all denied
</FilesMatch>
TEXT
Apache vs Nginx, honestly

Apache            per-directory .htaccess, huge module ecosystem,
                  deeply integrated with PHP, common in shared hosting

Nginx             lower memory per connection, faster static serving,
                  configuration loaded once, the default for new deployments

Both are capable. Choose Apache when .htaccess or a specific module is
required; choose Nginx for new high-concurrency deployments.

How it works #

a2enmod and a2ensite create symlinks from the available directory to the enabled one. It is the same pattern as Nginx's sites-enabled, with helper commands.

Modules must be explicitly enabled. Using ProxyPass without a2enmod proxy proxy_http produces a configuration error, which is a frequent first-time stumble.

AllowOverride All permits .htaccess files. Setting it to None where you do not need them is a genuine performance improvement, because Apache otherwise checks for .htaccess in every directory along the path on every request.

Options -Indexes disables directory listings. Leaving them enabled exposes the contents of any directory without an index file, which regularly leaks files people did not intend to publish.

The rewrite rules implement the front controller pattern used by most PHP frameworks: if the requested path is not a real file or directory, hand it to index.php.

The FilesMatch block denies access to sensitive file types. This matters because Apache serves the document root directly, and an .env file inside it would otherwise be downloadable.

apachectl configtest validates before reload, exactly like nginx -t, and the same discipline applies.

Real-world use #

Apache remains common in PHP hosting, older enterprise systems and anywhere .htaccess flexibility is needed. WordPress and many PHP applications ship .htaccess files by default.

A frequent arrangement is Nginx in front handling TLS and static files, proxying to Apache with PHP behind it, combining the strengths of both.

The classic security incident is an exposed .env or .git directory inside the document root. Keeping application code outside the document root and serving only a public directory prevents it entirely.

Performance tuning centres on the multi-processing module. The event MPM handles far more concurrent connections than the older prefork module, which allocates a process per connection.

For new projects, Nginx is the usual default, but being able to read and modify Apache configuration is necessary in any environment with existing systems.

Common mistakes #

  • Forgetting to enable a required module before using its directives.
  • Leaving AllowOverride All when no .htaccess is used, costing performance.
  • Leaving directory indexes enabled and exposing file listings.
  • Placing application code and .env files inside the document root.
  • Reloading without running configtest first.

Practice #

Write a VirtualHost that redirects HTTP to HTTPS, serves a public directory, denies access to dotfiles and .env, and proxies one path to a local application. Enable the modules it needs, run configtest, and confirm the proxy passes the correct forwarded headers.

Quick quiz

  1. 1. What does `a2enmod` do?

  2. 2. Why set AllowOverride None where .htaccess is not used?

  3. 3. What does `Options -Indexes` prevent?

  4. 4. What is the equivalent of `nginx -t` in Apache?

  5. 5. Why keep application code outside the document root?

Summary

  • Apache uses modules and VirtualHosts, enabled by symlink helpers.
  • .htaccess gives per-directory configuration at a per-request cost.
  • Disable directory indexes and keep code outside the document root.
  • Validate with apachectl configtest before reloading.
  • Nginx is the usual default for new deployments; Apache remains common in PHP hosting.