Apache HTTP Server — Complete Configuration Guide
Apache HTTP Server, commonly called Apache, is the world’s most widely used web server. Its modular architecture and powerful .htaccess system make it a flexible choice for hosting websites of any scale.
In this tutorial, you will learn to configure virtual hosts, write mod_rewrite rules in .htaccess files, set up SSL/TLS certificates, enable and configure modules, and tune Apache for performance. DodaTech runs Apache internally for intranet tooling alongside DodaZIP distribution servers.
What You’ll Learn
By the end of this guide, you will deploy Apache with multiple virtual hosts, control directory-level settings with .htaccess, write clean URL rewrite rules, secure sites with HTTPS, and optimize Apache’s worker configuration for your workload.
Why Apache Matters
Apache’s .htaccess system allows per-directory configuration without server access — essential for shared hosting environments. Its module ecosystem (mod_rewrite, mod_proxy, mod_ssl) handles virtually every web serving scenario. Over 30% of all websites still run Apache.
Apache Learning Path
flowchart LR
A[Installation] --> B[Virtual Hosts]
B --> C[.htaccess & mod_rewrite]
C --> D[SSL Configuration]
D --> E[Performance Tuning]
E --> F{You Are Here}
style F fill:#f90,color:#fff
Installation
# Ubuntu / Debian
sudo apt update && sudo apt install apache2 -y
# RHEL / CentOS / Fedora
sudo dnf install httpd -y
# Verify
sudo systemctl start apache2
sudo systemctl enable apache2
curl http://localhostExpected output
<html><body><h1>It works!</h1></body></html>Virtual Hosts
Virtual hosts let Apache serve multiple domains from a single server. Create /etc/apache2/sites-available/example.com.conf:
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/example.com/public
<Directory /var/www/example.com/public>
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/example.com_error.log
CustomLog ${APACHE_LOG_DIR}/example.com_access.log combined
</VirtualHost>Enable the site:
sudo a2ensite example.com.conf
sudo a2dissite 000-default.conf # Disable default
sudo systemctl reload apache2Expected behavior
curl -H "Host: example.com" http://localhost
# Serves content from /var/www/example.com/public.htaccess Files
.htaccess files provide per-directory configuration without editing the main config. Place one in your web root:
# /var/www/example.com/public/.htaccess
# Enable rewrite engine
RewriteEngine On
# Redirect www to non-www
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,L]
# Force HTTPS
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
# Clean URLs: /page/ → /page.html
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/?$ $1.html [L]
# Block directory listing
Options -Indexes
# Block access to sensitive files
<FilesMatch "\.(env|git|sql|md)$">
Require all denied
</FilesMatch>Expected behavior
curl -L http://www.example.com/about/
# Redirects to http://example.com/about/ (non-www, HTTPS)
# Serves /var/www/example.com/public/about.htmlSSL/TLS Configuration
Obtain and configure a Let’s Encrypt certificate:
sudo apt install certbot python3-certbot-apache -y
sudo certbot --apache -d example.com -d www.example.comThe resulting virtual host on port 443:
<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
# Modern TLS configuration
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256
SSLHonorCipherOrder off
SSLSessionTickets off
# HSTS (optional)
Header always set Strict-Transport-Security "max-age=63072000"
</VirtualHost>Testing SSL
curl -I https://example.com
# HTTP/2 200Performance Tuning
Apache’s performance depends on the MPM (Multi-Processing Module) in use:
# /etc/apache2/mods-available/mpm_prefork.conf
# For PHP applications (process-per-request)
<IfModule mpm_prefork_module>
StartServers 5
MinSpareServers 5
MaxSpareServers 10
MaxRequestWorkers 150
MaxConnectionsPerChild 1000
</IfModule># /etc/apache2/mods-available/mpm_event.conf
# For high-concurrency static/proxy workloads
<IfModule mpm_event_module>
StartServers 3
MinSpareThreads 25
MaxSpareThreads 75
ThreadLimit 64
ThreadsPerChild 25
MaxRequestWorkers 400
MaxConnectionsPerChild 10000
</IfModule>Benchmark comparison
# Install ab (Apache Bench)
sudo apt install apache2-utils -y
# Test concurrent connections
ab -n 1000 -c 100 http://localhost/
# Prefork: ~500 req/s
# Event: ~1500 req/s (with KeepAlive enabled)Common Errors
1. 403 Forbidden
The Apache user (www-data) cannot read the web root. Fix permissions: sudo chown -R www-data:www-data /var/www/example.com and chmod 755 /var/www/example.com.
2. 500 Internal Server Error from .htaccess
Often a syntax error in .htaccess. Check Apache’s error log: sudo tail -f /var/log/apache2/error.log. Remove the file and reload to restore access.
3. mod_rewrite Not Working
AllowOverride All must be set in the <Directory> block of the virtual host. Without it, .htaccess with RewriteEngine On is ignored.
4. SSL Handshake Failed
The certificate chain is incomplete. Certbot’s fullchain.pem includes intermediate certificates. If using a self-signed cert, the browser warns but the connection works.
5. Name-based Virtual Host Not Matching
Ensure ServerName is set correctly and the DNS points to your server. Use apachectl -S to list all configured virtual hosts and their names.
6. Apache Not Starting After Config Change
A syntax error in config files. Check with sudo apachectl configtest. Fix errors and reload.
7. High Memory Usage Under Load
The prefork MPM creates a new process per connection. Switch to mpm_event for better memory efficiency, or increase MaxRequestWorkers carefully to avoid swap.
Practice Questions
1. What is the difference between <VirtualHost> and .htaccess?
<VirtualHost> is a server-level configuration block. .htaccess provides per-directory overrides without server access. Virtual hosts are faster; .htaccess is checked per request.
2. What does RewriteCond %{REQUEST_FILENAME} !-f do?
It checks that the requested filename is not a real file. Used with the next RewriteRule to redirect non-file requests to a handler (like index.html for SPAs).
3. How do you enable a module in Apache on Ubuntu?
sudo a2enmod module_name (e.g., sudo a2enmod rewrite) followed by sudo systemctl reload apache2.
4. What is the purpose of Options -Indexes?
It disables directory listing. When a user visits a directory without an index file, Apache returns 403 Forbidden instead of listing the directory contents.
5. Challenge: Create a maintenance mode page
Use mod_rewrite in .htaccess to redirect all traffic (except your IP) to a maintenance.html page:
RewriteEngine On
RewriteCond %{REMOTE_ADDR} !^203\.0\.113\.1
RewriteCond %{REQUEST_URI} !/maintenance\.html$
RewriteRule ^(.*)$ /maintenance.html [R=503,L]Mini Project: Multi-Site Apache Setup
Deploy two websites on a single Apache server:
- Install Apache and enable
mod_rewriteandmod_ssl - Create two virtual hosts:
app1.example.comserving a static site from/var/www/app1app2.example.comproxying to port 3000 (ProxyPass / http://localhost:3000/)
- Configure SSL for both with Certbot
- Add
.htaccesstoapp1that blocks.envfiles and enables clean URLs - Benchmark both with
aband compare the static vs proxied performance
# Test both sites
curl -I http://app1.example.com
curl -I http://app2.example.comThis setup mirrors how DodaTech’s internal tooling infrastructure runs multiple services behind Apache.
FAQ
Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro