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_ip
  • http://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:

  1. prefork - Traditional, process-based (best for non-thread-safe applications)
  2. worker - Hybrid multi-process, multi-threaded (better performance)
  3. 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.