Apache Installation and Configuration on Linux: Complete Guide
Introduction
Apache HTTP Server, commonly referred to as Apache, is one of the most popular and widely-used web servers in the world. Developed and maintained by the Apache Software Foundation, it powers millions of websites globally, from small personal blogs to large-scale enterprise applications. Apache's flexibility, robustness, and extensive module ecosystem make it an excellent choice for hosting web applications.
This comprehensive guide will walk you through the complete process of installing and configuring Apache on various Linux distributions, including Ubuntu, Debian, CentOS, Rocky Linux, and AlmaLinux. Whether you're a system administrator setting up a production server or a developer creating a local development environment, this guide covers everything you need to know about Apache installation, configuration, optimization, and security hardening.
Apache offers several key advantages: excellent documentation, a mature and stable codebase, support for .htaccess files for decentralized configuration, compatibility with a vast array of modules, and strong community support. Understanding how to properly install and configure Apache is essential for anyone working with web hosting and server administration.
Prerequisites
Before beginning the Apache installation process, ensure you have the following:
- A Linux server running Ubuntu 20.04/22.04/24.04, Debian 10/11/12, CentOS 7/8, Rocky Linux 8/9, or AlmaLinux 8/9
- Root access or a user account with sudo privileges
- A stable internet connection for downloading packages
- Basic familiarity with the Linux command line interface
- Firewall access (ports 80 for HTTP and 443 for HTTPS)
- At least 512 MB RAM (1 GB or more recommended for production)
- Sufficient disk space (minimum 500 MB free space)
- A registered domain name (optional, but recommended for production environments)
- Basic understanding of DNS configuration (if hosting public websites)
Apache Installation on Ubuntu and Debian
Installing Apache on Ubuntu and Debian-based systems is straightforward using the APT package manager. Follow these steps:
Update Package Repository
First, update your package repository to ensure you're installing the latest available version:
sudo apt update
sudo apt upgrade -y
Install Apache
Install the Apache web server package:
sudo apt install apache2 -y
This command installs Apache along with all necessary dependencies. The installation process automatically creates the Apache user and group, sets up default directories, and installs systemd service files.
Verify Installation
Check that Apache is installed correctly:
apache2 -v
You should see output similar to:
Server version: Apache/2.4.52 (Ubuntu)
Server built: 2024-01-09T14:48:31
Start and Enable Apache
Start the Apache service and enable it to start automatically on system boot:
sudo systemctl start apache2
sudo systemctl enable apache2
Check Service Status
Verify that Apache is running:
sudo systemctl status apache2
You should see "active (running)" in the output.
Apache Installation on CentOS, Rocky Linux, and AlmaLinux
For Red Hat-based distributions, Apache is packaged as "httpd". Here's how to install it:
Update Package Repository
Update your system packages:
sudo yum update -y # For CentOS 7
# OR
sudo dnf update -y # For CentOS 8, Rocky Linux, AlmaLinux
Install Apache (httpd)
Install Apache using yum or dnf:
sudo yum install httpd -y # For CentOS 7
# OR
sudo dnf install httpd -y # For CentOS 8, Rocky Linux, AlmaLinux
Verify Installation
Check the installed version:
httpd -v
Start and Enable Apache
Start the httpd service and enable it to launch on boot:
sudo systemctl start httpd
sudo systemctl enable httpd
Check Service Status
Verify that Apache is running:
sudo systemctl status httpd
Firewall Configuration
To allow web traffic to reach your Apache server, you need to configure your firewall:
Ubuntu and Debian (UFW)
If you're using UFW (Uncomplicated Firewall):
# Allow HTTP
sudo ufw allow 'Apache'
# Or allow specific ports
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
# Enable UFW if not already enabled
sudo ufw enable
# Check status
sudo ufw status
Apache provides three UFW application profiles:
Apache- Opens only port 80 (HTTP)Apache Full- Opens both ports 80 (HTTP) and 443 (HTTPS)Apache Secure- Opens only port 443 (HTTPS)
CentOS, Rocky Linux, and AlmaLinux (firewalld)
If you're using firewalld:
# Allow HTTP and HTTPS
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
# Or allow specific ports
sudo firewall-cmd --permanent --add-port=80/tcp
sudo firewall-cmd --permanent --add-port=443/tcp
# Reload firewall
sudo firewall-cmd --reload
# Verify rules
sudo firewall-cmd --list-all
Testing Apache Installation
After installation, test that Apache is serving content:
Test from Command Line
Use curl to test locally:
curl localhost
You should see HTML output from Apache's default page.
Test from Web Browser
Open a web browser and navigate to:
http://your_server_iphttp://your_domain.com(if DNS is configured)
You should see the Apache default welcome page. On Ubuntu/Debian, it displays "Apache2 Default Page". On CentOS/Rocky/AlmaLinux, it shows the default httpd test page.
Apache Directory Structure
Understanding Apache's directory structure is crucial for effective management:
Ubuntu and Debian Directory Structure
/etc/apache2/
├── apache2.conf # Main configuration file
├── ports.conf # Port listening configuration
├── sites-available/ # Available virtual host configurations
├── sites-enabled/ # Enabled virtual host configurations (symlinks)
├── conf-available/ # Available configuration snippets
├── conf-enabled/ # Enabled configuration snippets (symlinks)
├── mods-available/ # Available modules
└── mods-enabled/ # Enabled modules (symlinks)
/var/www/ # Default document root
└── html/ # Default website files
/var/log/apache2/ # Log files
├── access.log # Access logs
└── error.log # Error logs
CentOS, Rocky Linux, and AlmaLinux Directory Structure
/etc/httpd/
├── conf/
│ └── httpd.conf # Main configuration file
├── conf.d/ # Additional configuration files
├── conf.modules.d/ # Module configuration files
└── logs/ # Symlink to /var/log/httpd/
/var/www/ # Default document root
└── html/ # Default website files
/var/log/httpd/ # Log files
├── access_log # Access logs
└── error_log # Error logs
Basic Apache Configuration
Let's configure essential Apache settings:
Main Configuration File
Ubuntu/Debian (/etc/apache2/apache2.conf)
Key directives to understand:
# Timeout: Maximum time to wait for events
Timeout 300
# KeepAlive: Enable persistent connections
KeepAlive On
# MaxKeepAliveRequests: Max requests per connection
MaxKeepAliveRequests 100
# KeepAliveTimeout: Seconds to wait for next request
KeepAliveTimeout 5
# Server performance settings
<IfModule mpm_prefork_module>
StartServers 5
MinSpareServers 5
MaxSpareServers 10
MaxRequestWorkers 150
MaxConnectionsPerChild 0
</IfModule>
# Default directory permissions
<Directory />
Options FollowSymLinks
AllowOverride None
Require all denied
</Directory>
<Directory /var/www/>
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
</Directory>
CentOS/Rocky/AlmaLinux (/etc/httpd/conf/httpd.conf)
Key directives:
# Server root directory
ServerRoot "/etc/httpd"
# Listen on port 80
Listen 80
# Server admin email
ServerAdmin [email protected]
# Server name
ServerName www.example.com:80
# Document root
DocumentRoot "/var/www/html"
# Directory permissions
<Directory "/var/www/html">
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
</Directory>
# Log files
ErrorLog "logs/error_log"
CustomLog "logs/access_log" combined
Setting ServerName to Prevent Warnings
To eliminate the "Could not reliably determine the server's fully qualified domain name" warning:
Ubuntu/Debian
Create a configuration file:
sudo nano /etc/apache2/conf-available/servername.conf
Add:
ServerName localhost
Enable the configuration:
sudo a2enconf servername
sudo systemctl reload apache2
CentOS/Rocky/AlmaLinux
Edit the main configuration:
sudo nano /etc/httpd/conf/httpd.conf
Add or uncomment:
ServerName localhost
Restart Apache:
sudo systemctl restart httpd
Configuring a Basic Virtual Host
Virtual hosts allow you to host multiple websites on a single server:
Ubuntu/Debian Virtual Host
Create a new virtual host configuration:
sudo nano /etc/apache2/sites-available/example.com.conf
Add the following configuration:
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
ServerAdmin [email protected]
DocumentRoot /var/www/example.com/public_html
<Directory /var/www/example.com/public_html>
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>
Create the document root directory:
sudo mkdir -p /var/www/example.com/public_html
Create a test index file:
sudo nano /var/www/example.com/public_html/index.html
Add:
<!DOCTYPE html>
<html>
<head>
<title>Welcome to Example.com</title>
</head>
<body>
<h1>Success! The example.com virtual host is working!</h1>
</body>
</html>
Set proper permissions:
sudo chown -R www-data:www-data /var/www/example.com
sudo chmod -R 755 /var/www/example.com
Enable the virtual host:
sudo a2ensite example.com.conf
sudo systemctl reload apache2
CentOS/Rocky/AlmaLinux Virtual Host
Create a virtual host configuration:
sudo nano /etc/httpd/conf.d/example.com.conf
Add:
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
ServerAdmin [email protected]
DocumentRoot /var/www/example.com/public_html
<Directory /var/www/example.com/public_html>
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
ErrorLog /var/log/httpd/example.com-error.log
CustomLog /var/log/httpd/example.com-access.log combined
</VirtualHost>
Create directories and files:
sudo mkdir -p /var/www/example.com/public_html
sudo nano /var/www/example.com/public_html/index.html
Set permissions:
sudo chown -R apache:apache /var/www/example.com
sudo chmod -R 755 /var/www/example.com
Restart Apache:
sudo systemctl restart httpd
Apache Modules Management
Apache's functionality can be extended using modules:
Ubuntu/Debian Module Management
List available modules:
ls /etc/apache2/mods-available/
Enable a module:
sudo a2enmod rewrite
sudo a2enmod ssl
sudo a2enmod headers
Disable a module:
sudo a2dismod autoindex
Check enabled modules:
apache2ctl -M
CentOS/Rocky/AlmaLinux Module Management
List available modules:
ls /etc/httpd/modules/
Modules are typically enabled in configuration files. Edit the module configuration:
sudo nano /etc/httpd/conf.modules.d/00-base.conf
To enable a module, uncomment or add:
LoadModule rewrite_module modules/mod_rewrite.so
LoadModule ssl_module modules/mod_ssl.so
LoadModule headers_module modules/mod_headers.so
Check loaded modules:
httpd -M
Essential Apache Modules
Here are commonly used Apache modules:
mod_rewrite
Enables URL rewriting for clean URLs and redirects:
# Ubuntu/Debian
sudo a2enmod rewrite
# CentOS/Rocky/AlmaLinux (usually enabled by default)
# Verify with: httpd -M | grep rewrite
mod_ssl
Enables SSL/TLS support for HTTPS:
# Ubuntu/Debian
sudo a2enmod ssl
# CentOS/Rocky/AlmaLinux
sudo yum install mod_ssl -y # or dnf
mod_headers
Allows control of HTTP headers:
# Ubuntu/Debian
sudo a2enmod headers
# CentOS/Rocky/AlmaLinux (usually enabled by default)
# Verify with: httpd -M | grep headers
mod_deflate
Enables compression for faster page loads:
# Ubuntu/Debian
sudo a2enmod deflate
# CentOS/Rocky/AlmaLinux (usually enabled by default)
# Verify with: httpd -M | grep deflate
Always reload or restart Apache after enabling modules:
# Ubuntu/Debian
sudo systemctl reload apache2
# CentOS/Rocky/AlmaLinux
sudo systemctl restart httpd
Performance Tuning
Optimize Apache for better performance:
MPM (Multi-Processing Module) Selection
Apache offers three MPMs:
- prefork - Traditional, process-based (best for non-thread-safe applications)
- worker - Hybrid multi-process, multi-threaded (better performance)
- event - Similar to worker but optimized for KeepAlive connections (recommended)
Check Current MPM
# Ubuntu/Debian
apache2ctl -V | grep MPM
# CentOS/Rocky/AlmaLinux
httpd -V | grep MPM
Switch to Event MPM (Ubuntu/Debian)
sudo a2dismod mpm_prefork
sudo a2dismod mpm_worker
sudo a2enmod mpm_event
sudo systemctl restart apache2
Configure Event MPM
Edit the MPM configuration:
# Ubuntu/Debian
sudo nano /etc/apache2/mods-available/mpm_event.conf
# CentOS/Rocky/AlmaLinux
sudo nano /etc/httpd/conf.modules.d/00-mpm.conf
Example optimized configuration:
<IfModule mpm_event_module>
StartServers 3
MinSpareThreads 75
MaxSpareThreads 250
ThreadsPerChild 25
MaxRequestWorkers 400
MaxConnectionsPerChild 1000
</IfModule>
Adjust these values based on your server resources:
- StartServers: Number of child processes at startup
- MinSpareThreads: Minimum idle threads
- MaxSpareThreads: Maximum idle threads
- ThreadsPerChild: Threads per child process
- MaxRequestWorkers: Maximum concurrent connections
- MaxConnectionsPerChild: Requests before child process recycling (0 = unlimited)
KeepAlive Optimization
Configure persistent connections:
# Enable KeepAlive
KeepAlive On
# Maximum requests per connection
MaxKeepAliveRequests 100
# Timeout for next request (seconds)
KeepAliveTimeout 5
Lower KeepAliveTimeout values free up resources faster but may reduce performance for clients making multiple requests.
Timeout Settings
Adjust timeout values:
# Maximum time for request (seconds)
Timeout 60
# Enable compression
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/javascript application/json
</IfModule>
Security Hardening
Implement security best practices:
Hide Apache Version Information
Prevent Apache from displaying version and OS information:
# Ubuntu/Debian
sudo nano /etc/apache2/conf-available/security.conf
# CentOS/Rocky/AlmaLinux
sudo nano /etc/httpd/conf/httpd.conf
Add or modify:
ServerTokens Prod
ServerSignature Off
Disable Directory Listing
Prevent directory browsing:
<Directory /var/www/html>
Options -Indexes +FollowSymLinks
AllowOverride None
Require all granted
</Directory>
Limit Request Size
Prevent large request attacks:
# Limit request body size (in bytes)
LimitRequestBody 10485760 # 10MB
Disable Unnecessary Modules
Disable modules you don't use:
# Ubuntu/Debian
sudo a2dismod status
sudo a2dismod autoindex
# CentOS/Rocky/AlmaLinux
# Comment out in /etc/httpd/conf.modules.d/
Configure Security Headers
Add security headers using mod_headers:
# Enable headers module first
sudo a2enmod headers # Ubuntu/Debian
Add to your virtual host or main configuration:
<IfModule mod_headers.c>
# Prevent clickjacking
Header always set X-Frame-Options "SAMEORIGIN"
# Prevent MIME type sniffing
Header always set X-Content-Type-Options "nosniff"
# Enable XSS protection
Header always set X-XSS-Protection "1; mode=block"
# Enforce HTTPS (if using SSL)
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
# Control referrer information
Header always set Referrer-Policy "strict-origin-when-cross-origin"
# Content Security Policy
Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline';"
</IfModule>
Restrict Access by IP
Limit access to specific IP addresses:
<Directory /var/www/html/admin>
Require ip 192.168.1.100
Require ip 10.0.0.0/24
</Directory>
Disable Trace HTTP Method
Prevent cross-site tracing attacks:
TraceEnable Off
Set Proper File Permissions
Ensure proper ownership and permissions:
# Ubuntu/Debian
sudo chown -R www-data:www-data /var/www
sudo find /var/www -type d -exec chmod 755 {} \;
sudo find /var/www -type f -exec chmod 644 {} \;
# CentOS/Rocky/AlmaLinux
sudo chown -R apache:apache /var/www
sudo find /var/www -type d -exec chmod 755 {} \;
sudo find /var/www -type f -exec chmod 644 {} \;
Log Management
Configure and manage Apache logs effectively:
Log File Locations
# Ubuntu/Debian
/var/log/apache2/access.log
/var/log/apache2/error.log
# CentOS/Rocky/AlmaLinux
/var/log/httpd/access_log
/var/log/httpd/error_log
Custom Log Formats
Define custom log formats:
# Combined format (default)
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
# Common format
LogFormat "%h %l %u %t \"%r\" %>s %b" common
# Custom format with response time
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %D" custom
Virtual Host Specific Logs
Configure separate logs for each virtual host:
<VirtualHost *:80>
ServerName example.com
DocumentRoot /var/www/example.com
ErrorLog ${APACHE_LOG_DIR}/example.com-error.log
CustomLog ${APACHE_LOG_DIR}/example.com-access.log combined
</VirtualHost>
View Real-time Logs
Monitor logs in real-time:
# Ubuntu/Debian
sudo tail -f /var/log/apache2/access.log
sudo tail -f /var/log/apache2/error.log
# CentOS/Rocky/AlmaLinux
sudo tail -f /var/log/httpd/access_log
sudo tail -f /var/log/httpd/error_log
Log Rotation
Apache logs are automatically rotated by logrotate. Check the configuration:
# Ubuntu/Debian
cat /etc/logrotate.d/apache2
# CentOS/Rocky/AlmaLinux
cat /etc/logrotate.d/httpd
Verification and Testing
Verify your Apache configuration:
Test Configuration Syntax
Before restarting Apache, test the configuration:
# Ubuntu/Debian
sudo apache2ctl configtest
# CentOS/Rocky/AlmaLinux
sudo httpd -t
You should see "Syntax OK" if there are no errors.
Check Active Connections
View current connections:
# Ubuntu/Debian
sudo apache2ctl status
# CentOS/Rocky/AlmaLinux
sudo httpd -S
Test Performance
Use Apache Bench for basic performance testing:
# Install Apache Bench (if not already installed)
sudo apt install apache2-utils # Ubuntu/Debian
sudo yum install httpd-tools # CentOS/Rocky/AlmaLinux
# Run benchmark (100 requests, 10 concurrent)
ab -n 100 -c 10 http://localhost/
Check Loaded Modules
List all loaded modules:
# Ubuntu/Debian
apache2ctl -M
# CentOS/Rocky/AlmaLinux
httpd -M
Troubleshooting Common Issues
Apache Won't Start
Check the error log:
# Ubuntu/Debian
sudo journalctl -u apache2 -n 50 --no-pager
sudo tail -f /var/log/apache2/error.log
# CentOS/Rocky/AlmaLinux
sudo journalctl -u httpd -n 50 --no-pager
sudo tail -f /var/log/httpd/error_log
Common causes:
- Port 80 already in use
- Configuration syntax errors
- Permission issues
- Missing directories
Port Already in Use
Find which process is using port 80:
sudo netstat -tulpn | grep :80
# or
sudo ss -tulpn | grep :80
# or
sudo lsof -i :80
Configuration Errors
If you see configuration errors:
# Test configuration
sudo apache2ctl configtest # Ubuntu/Debian
sudo httpd -t # CentOS/Rocky/AlmaLinux
Review the specific error message and fix the configuration file.
Permission Denied Errors
Check SELinux context (CentOS/Rocky/AlmaLinux):
# Check SELinux status
getenforce
# Set correct context for web directories
sudo chcon -R -t httpd_sys_content_t /var/www/example.com/
# Or set permanently
sudo semanage fcontext -a -t httpd_sys_content_t "/var/www/example.com(/.*)?"
sudo restorecon -Rv /var/www/example.com/
403 Forbidden Error
Common causes:
- Incorrect file permissions
- Incorrect directory permissions
- .htaccess file issues
- SELinux blocking access
Fix permissions:
sudo chmod 755 /var/www/example.com
sudo chmod 644 /var/www/example.com/public_html/index.html
500 Internal Server Error
Check error logs:
sudo tail -f /var/log/apache2/error.log # Ubuntu/Debian
sudo tail -f /var/log/httpd/error_log # CentOS/Rocky/AlmaLinux
Common causes:
- Syntax errors in .htaccess
- PHP errors
- Module conflicts
- Incorrect file permissions
Best Practices
Follow these Apache best practices:
Regular Updates
Keep Apache updated:
# Ubuntu/Debian
sudo apt update
sudo apt upgrade apache2
# CentOS/Rocky/AlmaLinux
sudo dnf update httpd
Use HTTPS
Always use SSL/TLS certificates for production sites. Consider using Let's Encrypt for free certificates.
Regular Backups
Backup Apache configuration:
# Ubuntu/Debian
sudo tar -czf apache2-config-backup-$(date +%F).tar.gz /etc/apache2/
# CentOS/Rocky/AlmaLinux
sudo tar -czf httpd-config-backup-$(date +%F).tar.gz /etc/httpd/
Monitor Resources
Regularly monitor server resources:
# Check memory usage
free -h
# Check CPU usage
top
# Check disk space
df -h
# Check Apache processes
ps aux | grep apache2 # Ubuntu/Debian
ps aux | grep httpd # CentOS/Rocky/AlmaLinux
Documentation
Document your configuration changes and maintain a changelog for your server.
Testing Environment
Always test configuration changes in a staging environment before applying to production.
Conclusion
Apache HTTP Server remains a robust and reliable choice for web hosting. This guide has covered the complete installation and configuration process, from basic setup to advanced security hardening and performance optimization. By following the steps outlined here, you now have a solid foundation for running Apache on Linux.
Key takeaways from this guide:
- Apache installation varies slightly between Debian-based and Red Hat-based distributions
- Proper virtual host configuration enables hosting multiple websites on a single server
- Security hardening is essential and should include hiding version information, configuring security headers, and setting proper permissions
- Performance tuning through MPM selection and configuration significantly impacts server efficiency
- Regular monitoring, updates, and backups are crucial for maintaining a healthy web server
Remember that Apache configuration is highly flexible and should be tailored to your specific use case. Continue learning about advanced features like mod_security for web application firewall functionality, mod_proxy for reverse proxy setups, and integration with PHP-FPM for improved PHP performance.
For production environments, always implement SSL/TLS encryption, configure regular backups, set up monitoring and alerting, and follow security best practices. Apache's extensive documentation and active community provide excellent resources for troubleshooting and advanced configurations.


