How To Install Apache On Linux

How To Install Apache On Linux

Reading time1 min
#Linux#WebServer#OpenSource#Apache#LinuxAdmin#SysAdmin

Mastering Apache Installation on Linux: Practical Guidance for Real Workloads

A secure, performant Apache deployment rarely emerges from a single apt install or dnf install. To support production web services, you must go beyond defaults—starting with baseline hardening, modular configuration, and real traffic optimizations. This walk-through details practical decisions for current Linux distros, assuming Ubuntu 22.04 LTS or RHEL/CentOS 9+—but the patterns apply broadly.


Baseline: Security-First System Preparation

Update packages before touching Apache.
Unpatched systems remain a prime attack vector, especially if they ship legacy OpenSSL or outdated libc.

sudo apt update && sudo apt upgrade -y         # Debian/Ubuntu
sudo dnf upgrade --refresh -y                  # RHEL/CentOS/Fedora

Note: Running the above may surface kernel upgrade prompts—always review before rebooting in production.


Package Installation with Sanity Checks

Install Apache

  • Debian/Ubuntu:

    sudo apt install apache2 -y
    
  • CentOS/RHEL/Fedora:

    sudo dnf install httpd -y
    

Verify binary presence and actual version:

apache2 -v      # On Debian systems
httpd -v        # On RedHat derivatives

Look for output like:

Server version: Apache/2.4.57 (Ubuntu)

If the binary isn’t found, check $PATH or review the install log for package errors (e.g., repository errors, dependency failures).


Service Management: Enablement and Autostart

Systemd orchestration is standard, but unit names differ:

DistributionEnable at BootStart ServiceStatus Check
Debian/Ubuntusudo systemctl enable apache2sudo systemctl start apache2sudo systemctl status apache2
RHEL/CentOS/Fedorasudo systemctl enable httpdsudo systemctl start httpdsudo systemctl status httpd

Expected output:

● apache2.service - The Apache HTTP Server
     Loaded: loaded (/lib/systemd/system/apache2.service; enabled)
     Active: active (running)

Note: Service failures here often stem from misconfigured /etc/hosts or another process locking port 80.


Minimal Virtual Host: Rapid Deployment

Suppose example.com already resolves to this server’s IP—skip local DNS hacking.

Config file locations:

  • Debian/Ubuntu: /etc/apache2/sites-available/
  • CentOS/RHEL: /etc/httpd/conf.d/

Define a Basic Virtual Host

<VirtualHost *:80>
  ServerName example.com
  ServerAdmin admin@example.com
  DocumentRoot /var/www/example.com/public_html

  ErrorLog   ${APACHE_LOG_DIR}/example.com_error.log
  CustomLog  ${APACHE_LOG_DIR}/example.com_access.log combined

  <Directory /var/www/example.com/public_html>
    Options -Indexes +FollowSymLinks
    AllowOverride All
    Require all granted
  </Directory>
</VirtualHost>

Deploy it:

sudo mkdir -p /var/www/example.com/public_html
echo "<h1>OK</h1>" | sudo tee /var/www/example.com/public_html/index.html
sudo chown -R www-data:www-data /var/www/example.com/
sudo chmod -R 750 /var/www/example.com/

On Debian/Ubuntu:

sudo a2ensite example.com.conf
sudo systemctl reload apache2

On CentOS/RHEL:

  • Just placing the .conf in /etc/httpd/conf.d/ and reloading httpd suffices.

Gotcha

For single-site configurations, it’s tempting to hack everything into apache2.conf. Don’t—modular vhost files simplify future migrations and audits.


Basic Performance Tuning

Performance bottlenecks often lurk in default settings—KeepAlive, compression, and MPM parameters are critical.

HTTP KeepAlive (for socket reuse under high concurrency)

Set in either global Apache config or per vhost:

KeepAlive On
MaxKeepAliveRequests 200
KeepAliveTimeout 3

Enable mod_deflate Compression

Reducing transfer payload improves latency for clients with slow links.

On Debian/Ubuntu:

sudo a2enmod deflate
sudo systemctl restart apache2

Configure resource types:

<IfModule mod_deflate.c>
  AddOutputFilterByType DEFLATE text/html text/plain text/css application/javascript application/json
</IfModule>

Browser Caching with mod_expires

Frequent in frontend-heavy applications.

sudo a2enmod expires
sudo systemctl restart apache2

Example snippet:

<IfModule mod_expires.c>
  ExpiresActive On
  ExpiresByType application/javascript "access plus 1 week"
  ExpiresByType image/png "access plus 1 month"
</IfModule>

Note: Overly aggressive expiration can stall new UI deployments (clients keep old JS for days).


MPM: Choosing the Right Model

  • PHP-FPM: Use event or worker, not prefork.
  • Static file servers: event almost always best.

Switching modules (Debian/Ubuntu syntax):

sudo a2dismod mpm_prefork
sudo a2enmod mpm_event
sudo systemctl restart apache2

Tune /etc/apache2/mods-enabled/mpm_event.conf.
Under-provisioning MaxRequestWorkers leads to 503 errors under burst load. Always monitor with:

journalctl -u apache2 | grep 'server reached MaxRequestWorkers'

Hardening Methods Beyond Defaults

Disable Directory Indexing

As above, confirm every virtual host or app root sets:

Options -Indexes

Hide Banner Information

Deploy in root config:

ServerTokens Prod
ServerSignature Off
Header unset X-Powered-By

If the Header directive fails, ensure mod_headers is enabled.

Firewall Rule: Limit Exposure

On Ubuntu:

sudo ufw allow 'Apache Full'   # Enables 80/tcp and 443/tcp
sudo ufw enable                # if not already enabled
  • Check with sudo ufw status.
  • On RHEL/CentOS: configure via firewalld, e.g.,
    sudo firewall-cmd --permanent --add-service=http

Caution: Never open SSH to 0.0.0.0/0 in production.


HTTPS Integration: Let’s Encrypt Automation

Automated TLS, ACME-based, zero cost. Certbot is the de facto tool.

sudo apt install certbot python3-certbot-apache -y
sudo certbot --apache -d example.com -d www.example.com

Certbot injects/reloads SSL configs and sets up renewals via systemd timers.

  • Watch sudo journalctl -u certbot.timer for renewal issues.
  • SSL handshake failures? Review SSLCertificateFile paths and Apache error logs.

Non-obvious tip: Use --dry-run flag during staging.


Real-World Troubleshooting Example

Issue: Apache fails to start post-install with error:

(98)Address already in use: AH00072: make_sock: could not bind to address [::]:80

Root cause: Another web server (often nginx) already listening on port 80.
Resolution: Identify processes via sudo lsof -Pn -i :80.


In Summary

Rapid Apache deployment is easy—reliable, observable, secure deployments are not. Focus on modular configuration, test status output after every change, and make basic hardening your default approach. Monitor access and error logs continuously; sometimes, a single mistyped config blocks all traffic.

Optional: For service chaining, consider reverse proxying via nginx or HAProxy—but that’s outside this scope.


Request coverage of load balancing, HTTP/2, or chroot jailing?
Leave specifics in the feedback channel.