Quick reference for installation, management, configuration directives, and security of Apache HTTP Server (latest stable 2.4.63, 23 Jan 2025)
Open-source, modular, process-based HTTP server powering 30 %+ of the web. Latest LTS branch is 2.4.x; most recent GA release is 2.4.63
(2025-01-23).
Configuration root (Unix-likes): /etc/apache2/
(Deb / Ubuntu) or /etc/httpd/
(RHEL / Fedora).
# install
sudo apt update
sudo apt install apache2
# upgrade to newest 2.4.x from PPA
sudo add-apt-repository ppa:ondrej/apache2
sudo apt full-upgrade
sudo dnf install httpd
sudo systemctl enable --now httpd
brew install httpd
sudo brew services start httpd
# systemd (Linux ≥ systemd)
sudo systemctl start|stop|restart|reload httpd # RHEL/Fedora
sudo systemctl start|stop|restart|reload apache2 # Debian/Ubuntu
# graceful reload (no connection drop)
sudo apachectl graceful
# test configuration syntax
sudo apachectl -t
# real-time config dump
sudo apachectl -S
/etc/apache2/ # main configs (Deb/Ubuntu)
/etc/apache2/apache2.conf
|-- sites-available/ # vhost files ➜ enabled via a2ensite
|-- sites-enabled/ # symlinks to enabled vhosts
|-- mods-available/ # all modules (.load + .conf)
|-- mods-enabled/ # enabled module symlinks
/var/www/html # default DocumentRoot
/var/log/apache2/ # access & error logs
Listen 80
Listen 443 https
ServerName www.example.com
ServerAlias example.com
DocumentRoot "/var/www/example/public"
<Directory "/var/www/example/public">
Options Indexes FollowSymLinks
AllowOverride All # enable .htaccess
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/example.error.log
CustomLog ${APACHE_LOG_DIR}/example.access.log combined
LoadModule rewrite_module modules/mod_rewrite.so
<IfModule mod_headers.c>
Header set X-Frame-Options "SAMEORIGIN"
</IfModule>
# /etc/apache2/sites-available/example.conf
<VirtualHost *:80>
ServerName www.example.com
ServerAlias example.com
DocumentRoot /var/www/example/public
ErrorLog ${APACHE_LOG_DIR}/example.error.log
CustomLog ${APACHE_LOG_DIR}/example.access.log combined
</VirtualHost>
Enable & reload:
sudo a2ensite example.conf
sudo systemctl reload apache2
sudo a2enmod ssl
sudo a2enconf ssl-params # optional hardening snippet
# simple vhost
<VirtualHost *:443>
ServerName www.secure-site.com
DocumentRoot /var/www/secure
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/secure-site/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/secure-site/privkey.pem
</VirtualHost>
Use Certbot
for automated Let’s Encrypt certificates.
<Directory "/var/www/api">
Require all granted
<LimitExcept GET POST HEAD>
Require ip 192.0.2.0/24
</LimitExcept>
</Directory>
<Location "/upload">
AllowMethods POST OPTIONS
</Location>
# send DELETE requests to a CGI cleanup script
Action del-handler /cgi-bin/delete.cgi
<Location "/files">
SetHandler del-handler
</Location>
# GET
curl -v https://example.com/
# POST JSON
curl -X POST -H "Content-Type: application/json" -d '{"title":"demo"}' \
https://example.com/api/write
# PUT (replace resource)
curl -T ./file.txt https://example.com/storage/file.txt
# DELETE
curl -X DELETE https://example.com/storage/file.txt
RewriteEngine On
# force HTTPS
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# pretty-print blog posts
RewriteRule ^blog/([0-9]+)/([a-z-]+)/?$ /blog.php?id=$1&slug=$2 [L,QSA]
# create user file
sudo htpasswd -c /etc/apache2/.htpasswd alice
# restrict a directory
<Directory "/var/www/secure">
AuthType Basic
AuthName "Secure Zone"
AuthUserFile /etc/apache2/.htpasswd
Require valid-user
</Directory>
<Directory "/var/www/admin">
Require ip 203.0.113.10 203.0.113.11
</Directory>
# choose Event MPM for high concurrency
sudo a2dismod mpm_prefork
sudo a2enmod mpm_event
# keep-alive tuning
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 5
# gzip responses
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/css application/json
</IfModule>
# cache static assets (mod_expires)
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/png "access plus 1 year"
</IfModule>
# highly-detailed combined log
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
# pipe to rotatelogs for daily rotation
CustomLog "|/usr/sbin/rotatelogs /var/log/apache2/access.%Y%m%d 86400" combined
# elevate error verbosity
LogLevel warn # debug | info | notice | warn | error | crit
# list enabled modules
apachectl -M | sort
# enable/disable
sudo a2enmod rewrite headers
sudo a2dismod status
# enable a vhost
sudo a2ensite blog.conf
sudo a2dissite 000-default.conf
sudo systemctl reload apache2
Options -Indexes
– disable directory listingErrorDocument 404 /errors/404.html
AddType application/json .map
Redirect 302 /old https://example.com/new
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains"
ServerTokens Prod
& ServerSignature Off
– hide version strings.mod_security3
(WAF) & mod_evasive
for basic DDoS mitigation.User www-data
, Group www-data
), isolate vhosts with mpm-itk or PHP-FPM pools.