+
tf
+
--
s3
spring
+
eclipse
_
+
macos
fortran
firebase
+
ts
+
https
+
+
rest
echo
pip
+
โˆ‚
+
vscode
+
backbone
^
+
+
aws
stimulus
+
clion
+
js
erlang
+
ฯ€
+
+
+=
+
numpy
laravel
@
+
rider
fauna
%
babel
+
+
gradle
|>
+
+
+
+
+
+
+
+
xcode
+
+
vb
+
+
preact
+
+
rubymine
+
==
_
stimulus
+
+
+
gradle
riot
+
+
+
scheme
+
saml
+
Back to Blog
๐ŸŒ Web Server Setup with Apache on AlmaLinux: Host Like a Pro
AlmaLinux Apache Web Server

๐ŸŒ Web Server Setup with Apache on AlmaLinux: Host Like a Pro

Published Aug 20, 2025

Master Apache web server configuration on AlmaLinux. Set up virtual hosts, SSL certificates, performance tuning, and security hardening with practical beginner examples.

12 min read
0 views
Table of Contents

๐ŸŒ Web Server Setup with Apache on AlmaLinux: Host Like a Pro

Remember paying $100/month for basic web hosting? ๐Ÿ’ธ Not anymore! With Apache on AlmaLinux, you can host unlimited websites on your own server. I learned this when my hosting bill hit $500/month for 20 sites. Now I run 100+ sites on a single server that costs $50/month. Today Iโ€™m showing you how to set up Apache like a pro - virtual hosts, SSL, caching, the works! Letโ€™s turn your AlmaLinux box into a web hosting powerhouse! ๐Ÿš€

๐Ÿค” Why Apache Still Rules the Web

Nginx is trendy, but Apache is legendary! Hereโ€™s why itโ€™s still king:

  • ๐Ÿ† Most Popular - Powers 30% of the internet
  • ๐Ÿ”ง Super Flexible - .htaccess for easy config
  • ๐ŸŽฏ Module System - Add features without recompiling
  • ๐Ÿ“š Massive Community - Solutions for everything
  • ๐Ÿ”„ PHP Integration - Perfect with mod_php
  • ๐Ÿ›ก๏ธ Battle Tested - 25+ years of reliability

Fun fact: I tried switching to Nginx once. Spent a week converting .htaccess rules. Switched back to Apache in an hour! ๐Ÿ˜…

๐ŸŽฏ What You Need

Before we start serving websites, ensure you have:

  • โœ… AlmaLinux system with public IP
  • โœ… Root or sudo access
  • โœ… Domain name (optional for testing)
  • โœ… 30 minutes to become a web hosting pro
  • โœ… Coffee (web servers run on coffee! โ˜•)

๐Ÿ“ Step 1: Installing and Configuring Apache

Letโ€™s get Apache up and running!

Install Apache

# Install Apache (httpd in RHEL world)
sudo dnf install -y httpd

# Install useful modules
sudo dnf install -y mod_ssl mod_security mod_evasive

# Enable and start Apache
sudo systemctl enable --now httpd

# Check status
sudo systemctl status httpd

# Verify installation
httpd -v

# Check loaded modules
httpd -M

Basic Configuration

# Main config file
sudo nano /etc/httpd/conf/httpd.conf

# Key settings to modify:
ServerRoot "/etc/httpd"
Listen 80

# Server identification
ServerAdmin [email protected]
ServerName server.example.com:80

# Performance settings
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 5

# MPM (Multi-Processing Module) tuning
<IfModule mpm_prefork_module>
    StartServers          8
    MinSpareServers       5
    MaxSpareServers      20
    MaxRequestWorkers   250
    MaxConnectionsPerChild   4000
</IfModule>

# Hide Apache version
ServerTokens Prod
ServerSignature Off

# Default document root
DocumentRoot "/var/www/html"

# Directory permissions
<Directory "/var/www">
    AllowOverride None
    Require all granted
</Directory>

<Directory "/var/www/html">
    Options Indexes FollowSymLinks
    AllowOverride All
    Require all granted
</Directory>

Configure Firewall

# Open HTTP and HTTPS ports
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload

# Verify
sudo firewall-cmd --list-all

๐Ÿ”ง Step 2: Virtual Hosts Configuration

Host multiple websites on one server!

Create Virtual Host

# Create directory structure
sudo mkdir -p /var/www/site1.com/{public_html,logs,ssl}
sudo mkdir -p /var/www/site2.com/{public_html,logs,ssl}

# Set permissions
sudo chown -R apache:apache /var/www/site1.com
sudo chmod -R 755 /var/www/site1.com

# Create test page
cat > /var/www/site1.com/public_html/index.html << 'EOF'
<!DOCTYPE html>
<html>
<head>
    <title>Welcome to Site1.com!</title>
    <style>
        body { font-family: Arial; text-align: center; padding: 50px; }
        h1 { color: #333; }
        .info { background: #f0f0f0; padding: 20px; border-radius: 10px; margin: 20px auto; max-width: 600px; }
    </style>
</head>
<body>
    <h1>๐ŸŽ‰ Site1.com is Live!</h1>
    <div class="info">
        <p>Powered by Apache on AlmaLinux</p>
        <p>Server: <?php echo $_SERVER['SERVER_SOFTWARE']; ?></p>
        <p>Your IP: <?php echo $_SERVER['REMOTE_ADDR']; ?></p>
    </div>
</body>
</html>
EOF

# Create virtual host config
sudo nano /etc/httpd/conf.d/site1.com.conf

<VirtualHost *:80>
    ServerName site1.com
    ServerAlias www.site1.com
    DocumentRoot /var/www/site1.com/public_html
    
    # Logs
    ErrorLog /var/www/site1.com/logs/error.log
    CustomLog /var/www/site1.com/logs/access.log combined
    
    # Directory settings
    <Directory /var/www/site1.com/public_html>
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
    
    # PHP settings (if using PHP)
    <FilesMatch \.php$>
        SetHandler "proxy:unix:/var/run/php-fpm/www.sock|fcgi://localhost"
    </FilesMatch>
    
    # Security headers
    Header always set X-Frame-Options "SAMEORIGIN"
    Header always set X-Content-Type-Options "nosniff"
    Header always set X-XSS-Protection "1; mode=block"
    
    # Compression
    <IfModule mod_deflate.c>
        AddOutputFilterByType DEFLATE text/html text/css text/javascript
    </IfModule>
</VirtualHost>

Test Configuration

# Check syntax
sudo apachectl configtest

# Reload Apache
sudo systemctl reload httpd

# Test locally
curl -H "Host: site1.com" http://localhost

# Add to /etc/hosts for testing
echo "127.0.0.1 site1.com www.site1.com" | sudo tee -a /etc/hosts

๐ŸŒŸ Step 3: SSL/TLS Configuration

Secure your sites with HTTPS!

Install Certbot

# Install Certbot for Let's Encrypt
sudo dnf install -y epel-release
sudo dnf install -y certbot python3-certbot-apache

# Get SSL certificate
sudo certbot --apache -d site1.com -d www.site1.com

# Or manually with standalone
sudo certbot certonly --standalone -d site1.com -d www.site1.com

Manual SSL Configuration

# Create SSL virtual host
sudo nano /etc/httpd/conf.d/site1.com-ssl.conf

<VirtualHost *:443>
    ServerName site1.com
    ServerAlias www.site1.com
    DocumentRoot /var/www/site1.com/public_html
    
    # SSL Configuration
    SSLEngine on
    SSLCertificateFile /etc/letsencrypt/live/site1.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/site1.com/privkey.pem
    
    # Modern SSL settings
    SSLProtocol -all +TLSv1.2 +TLSv1.3
    SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256
    SSLHonorCipherOrder off
    SSLSessionTickets off
    
    # HSTS (optional but recommended)
    Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
    
    # Logs
    ErrorLog /var/www/site1.com/logs/ssl_error.log
    CustomLog /var/www/site1.com/logs/ssl_access.log combined
    
    <Directory /var/www/site1.com/public_html>
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>

# Redirect HTTP to HTTPS
<VirtualHost *:80>
    ServerName site1.com
    ServerAlias www.site1.com
    
    RewriteEngine On
    RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R=301,L]
</VirtualHost>

Auto-Renew Certificates

# Test renewal
sudo certbot renew --dry-run

# Add to crontab
sudo crontab -e
# Add:
0 0,12 * * * /usr/bin/certbot renew --quiet && systemctl reload httpd

โœ… Step 4: Performance Optimization

Make your Apache fly! ๐Ÿš€

Enable Caching

# Install caching module
sudo dnf install -y mod_cache

# Configure caching
sudo nano /etc/httpd/conf.d/cache.conf

# Memory cache
<IfModule mod_cache.c>
    CacheEnable mem /
    MCacheSize 4096
    MCacheMaxObjectCount 1000
    MCacheMinObjectSize 1
    MCacheMaxObjectSize 2048
    
    # Disk cache
    CacheEnable disk /
    CacheRoot /var/cache/httpd/proxy
    CacheDirLevels 2
    CacheDirLength 1
    CacheMaxFileSize 1000000
    
    # Cache static files
    <FilesMatch "\.(jpg|jpeg|png|gif|css|js|ico)$">
        Header set Cache-Control "max-age=604800, public"
    </FilesMatch>
</IfModule>

# Browser caching with .htaccess
cat > /var/www/site1.com/public_html/.htaccess << 'EOF'
# Enable compression
<IfModule mod_deflate.c>
    AddOutputFilterByType DEFLATE text/plain
    AddOutputFilterByType DEFLATE text/html
    AddOutputFilterByType DEFLATE text/xml
    AddOutputFilterByType DEFLATE text/css
    AddOutputFilterByType DEFLATE application/javascript
</IfModule>

# Browser caching
<IfModule mod_expires.c>
    ExpiresActive On
    ExpiresByType image/jpg "access plus 1 year"
    ExpiresByType image/jpeg "access plus 1 year"
    ExpiresByType image/gif "access plus 1 year"
    ExpiresByType image/png "access plus 1 year"
    ExpiresByType text/css "access plus 1 month"
    ExpiresByType application/javascript "access plus 1 month"
</IfModule>
EOF

Enable HTTP/2

# Enable HTTP/2 module
sudo nano /etc/httpd/conf.modules.d/00-mpm.conf

# Comment out prefork, enable event
#LoadModule mpm_prefork_module modules/mod_mpm_prefork.so
LoadModule mpm_event_module modules/mod_mpm_event.so

# Enable HTTP/2
sudo nano /etc/httpd/conf.d/ssl.conf
# Add:
Protocols h2 h2c http/1.1

# Restart Apache
sudo systemctl restart httpd

๐ŸŽฎ Quick Examples

Example 1: WordPress Hosting Setup ๐Ÿ“

#!/bin/bash
# Automated WordPress setup

setup_wordpress() {
    DOMAIN=$1
    DB_NAME=$(echo $DOMAIN | tr . _)
    DB_USER=$DB_NAME
    DB_PASS=$(openssl rand -base64 12)
    
    echo "๐Ÿ“ Setting up WordPress for $DOMAIN"
    
    # Create directory structure
    sudo mkdir -p /var/www/$DOMAIN/{public_html,logs,ssl}
    
    # Download WordPress
    cd /tmp
    wget https://wordpress.org/latest.tar.gz
    tar -xzf latest.tar.gz
    sudo cp -R wordpress/* /var/www/$DOMAIN/public_html/
    
    # Create database
    mysql -u root << EOF
CREATE DATABASE $DB_NAME;
CREATE USER '$DB_USER'@'localhost' IDENTIFIED BY '$DB_PASS';
GRANT ALL ON $DB_NAME.* TO '$DB_USER'@'localhost';
FLUSH PRIVILEGES;
EOF
    
    # Configure WordPress
    cd /var/www/$DOMAIN/public_html
    sudo cp wp-config-sample.php wp-config.php
    sudo sed -i "s/database_name_here/$DB_NAME/" wp-config.php
    sudo sed -i "s/username_here/$DB_USER/" wp-config.php
    sudo sed -i "s/password_here/$DB_PASS/" wp-config.php
    
    # Add salts
    SALTS=$(curl -s https://api.wordpress.org/secret-key/1.1/salt/)
    sudo sed -i "/AUTH_KEY/d" wp-config.php
    sudo sed -i "/SECURE_AUTH_KEY/d" wp-config.php
    sudo sed -i "/LOGGED_IN_KEY/d" wp-config.php
    sudo sed -i "/NONCE_KEY/d" wp-config.php
    echo "$SALTS" | sudo tee -a wp-config.php
    
    # Set permissions
    sudo chown -R apache:apache /var/www/$DOMAIN
    sudo find /var/www/$DOMAIN -type d -exec chmod 755 {} \;
    sudo find /var/www/$DOMAIN -type f -exec chmod 644 {} \;
    
    # Create Apache config
    cat << VHOST | sudo tee /etc/httpd/conf.d/$DOMAIN.conf
<VirtualHost *:80>
    ServerName $DOMAIN
    ServerAlias www.$DOMAIN
    DocumentRoot /var/www/$DOMAIN/public_html
    
    ErrorLog /var/www/$DOMAIN/logs/error.log
    CustomLog /var/www/$DOMAIN/logs/access.log combined
    
    <Directory /var/www/$DOMAIN/public_html>
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
    
    # PHP-FPM
    <FilesMatch \.php$>
        SetHandler "proxy:unix:/var/run/php-fpm/www.sock|fcgi://localhost"
    </FilesMatch>
</VirtualHost>
VHOST
    
    # Get SSL certificate
    sudo certbot --apache -d $DOMAIN -d www.$DOMAIN --non-interactive --agree-tos -m admin@$DOMAIN
    
    # Reload Apache
    sudo systemctl reload httpd
    
    echo "โœ… WordPress installed!"
    echo "๐ŸŒ URL: https://$DOMAIN"
    echo "๐Ÿ“Š Database: $DB_NAME"
    echo "๐Ÿ”‘ DB Password: $DB_PASS"
    echo "๐Ÿ“ Complete setup at https://$DOMAIN/wp-admin/install.php"
}

# Install WordPress for multiple sites
setup_wordpress "blog.example.com"
setup_wordpress "shop.example.com"

Example 2: Load Balancer Configuration โš–๏ธ

#!/bin/bash
# Set up Apache as load balancer

configure_load_balancer() {
    echo "โš–๏ธ Configuring Apache Load Balancer"
    
    # Enable proxy modules
    sudo dnf install -y mod_proxy_html
    
    # Create load balancer config
    cat << 'EOF' | sudo tee /etc/httpd/conf.d/loadbalancer.conf
<VirtualHost *:80>
    ServerName lb.example.com
    
    # Enable proxy
    ProxyRequests Off
    ProxyPreserveHost On
    
    # Load balancing with sticky sessions
    Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED
    
    <Proxy "balancer://mycluster">
        BalancerMember http://192.168.1.101:80 route=server1
        BalancerMember http://192.168.1.102:80 route=server2
        BalancerMember http://192.168.1.103:80 route=server3
        
        ProxySet stickysession=ROUTEID
        ProxySet lbmethod=byrequests
    </Proxy>
    
    # Health check
    <Location "/balancer-manager">
        SetHandler balancer-manager
        Require host localhost
    </Location>
    
    ProxyPass /balancer-manager !
    ProxyPass / balancer://mycluster/
    ProxyPassReverse / balancer://mycluster/
    
    # Logging
    ErrorLog logs/lb_error.log
    CustomLog logs/lb_access.log combined
</VirtualHost>

# With health checks
<VirtualHost *:443>
    ServerName lb.example.com
    
    SSLEngine on
    SSLCertificateFile /etc/pki/tls/certs/server.crt
    SSLCertificateKeyFile /etc/pki/tls/private/server.key
    
    <Proxy "balancer://securecluster">
        BalancerMember https://192.168.1.101:443 route=server1 hcmethod=GET hcuri=/health
        BalancerMember https://192.168.1.102:443 route=server2 hcmethod=GET hcuri=/health
        BalancerMember https://192.168.1.103:443 route=server3 hcmethod=GET hcuri=/health
        
        ProxySet stickysession=ROUTEID
        ProxySet lbmethod=bytraffic
    </Proxy>
    
    ProxyPass / balancer://securecluster/
    ProxyPassReverse / balancer://securecluster/
</VirtualHost>
EOF
    
    sudo systemctl reload httpd
    echo "โœ… Load balancer configured!"
}

configure_load_balancer

Example 3: Security Hardening Script ๐Ÿ”’

#!/bin/bash
# Harden Apache security

harden_apache() {
    echo "๐Ÿ”’ Hardening Apache Security"
    
    # Install mod_security
    sudo dnf install -y mod_security mod_security_crs
    
    # Configure mod_security
    cat << 'EOF' | sudo tee /etc/httpd/conf.d/mod_security.conf
<IfModule mod_security2.c>
    SecRuleEngine On
    SecRequestBodyAccess On
    SecResponseBodyAccess Off
    SecRequestBodyLimit 13107200
    SecRequestBodyInMemoryLimit 131072
    SecAuditEngine RelevantOnly
    SecAuditLogRelevantStatus "^(?:5|4(?!04))"
    SecAuditLogType Serial
    SecAuditLog /var/log/httpd/modsec_audit.log
    
    # Include OWASP rules
    Include /usr/share/mod_modsecurity_crs/activated_rules/*.conf
</IfModule>
EOF
    
    # Configure mod_evasive (DDoS protection)
    cat << 'EOF' | sudo tee /etc/httpd/conf.d/mod_evasive.conf
<IfModule mod_evasive24.c>
    DOSHashTableSize 3097
    DOSPageCount 2
    DOSSiteCount 50
    DOSPageInterval 1
    DOSSiteInterval 1
    DOSBlockingPeriod 10
    DOSEmailNotify [email protected]
    DOSLogDir /var/log/httpd/mod_evasive
</IfModule>
EOF
    
    # Create log directory
    sudo mkdir -p /var/log/httpd/mod_evasive
    sudo chown apache:apache /var/log/httpd/mod_evasive
    
    # Disable dangerous modules
    sudo sed -i 's/LoadModule autoindex_module/#LoadModule autoindex_module/' /etc/httpd/conf.modules.d/00-base.conf
    sudo sed -i 's/LoadModule status_module/#LoadModule status_module/' /etc/httpd/conf.modules.d/00-base.conf
    
    # Security headers
    cat << 'EOF' | sudo tee -a /etc/httpd/conf/httpd.conf

# Security Headers
Header always set X-Frame-Options "SAMEORIGIN"
Header always set X-Content-Type-Options "nosniff"
Header always set X-XSS-Protection "1; mode=block"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set Content-Security-Policy "default-src 'self';"
Header always set Permissions-Policy "geolocation=(), microphone=(), camera=()"

# Hide Apache version
ServerTokens Prod
ServerSignature Off

# Disable TRACE
TraceEnable off

# Prevent clickjacking
Header always append X-Frame-Options DENY

# File upload limits
LimitRequestBody 10485760
EOF
    
    # Restart Apache
    sudo systemctl restart httpd
    
    echo "โœ… Apache hardened!"
}

harden_apache

๐Ÿšจ Fix Common Problems

Problem 1: 403 Forbidden Error โŒ

Canโ€™t access your site?

# Check permissions
ls -la /var/www/site1.com/

# Fix ownership
sudo chown -R apache:apache /var/www/site1.com

# Fix SELinux context
sudo restorecon -Rv /var/www/

# Set SELinux boolean
sudo setsebool -P httpd_can_network_connect 1
sudo setsebool -P httpd_read_user_content 1

Problem 2: Apache Wonโ€™t Start โŒ

Service fails to start?

# Check for errors
sudo journalctl -xe | grep httpd

# Test configuration
sudo apachectl configtest

# Check port conflicts
sudo ss -tulpn | grep :80

# Common fix: Another service using port 80
sudo systemctl stop nginx

Problem 3: SSL Not Working โŒ

HTTPS showing errors?

# Check certificate
openssl x509 -in /path/to/cert.pem -text -noout

# Test SSL
openssl s_client -connect site1.com:443

# Fix certificate permissions
sudo chmod 600 /etc/pki/tls/private/*.key

# Renew certificate
sudo certbot renew --force-renewal

Problem 4: Slow Performance โŒ

Site loading slowly?

# Check Apache status
sudo systemctl status httpd
apachectl status

# Enable status module temporarily
sudo apachectl -M | grep status

# Tune MPM settings
sudo nano /etc/httpd/conf.modules.d/00-mpm.conf

# Monitor connections
watch -n 1 'ss -ant | grep :80 | wc -l'

# Check memory usage
free -h
ps aux | grep httpd | awk '{sum+=$6} END {print sum/1024 " MB"}'

๐Ÿ“‹ Simple Commands Summary

TaskCommand
๐Ÿš€ Start Apachesudo systemctl start httpd
๐Ÿ”„ Reload configsudo systemctl reload httpd
โœ… Test configsudo apachectl configtest
๐Ÿ“Š Check statussudo systemctl status httpd
๐Ÿ“‹ List moduleshttpd -M
๐ŸŒ List vhostsapachectl -S
๐Ÿ“ Error logssudo tail -f /var/log/httpd/error_log
๐Ÿ”’ Get SSLsudo certbot --apache

๐Ÿ’ก Tips for Success

  1. Test Locally First ๐Ÿงช - Use /etc/hosts before DNS
  2. Monitor Logs ๐Ÿ“Š - tail -f is your friend
  3. Use .htaccess Wisely ๐Ÿ“ - Great power, use carefully
  4. Cache Everything ๐Ÿ’พ - Speed matters
  5. Automate Backups ๐Ÿ”„ - Before itโ€™s too late
  6. Document Configs ๐Ÿ“š - Future you will thank you

Funny story: I once spent 3 hours debugging a โ€œbrokenโ€ site. Turns out I was editing the wrong virtual host file. Always double-check your domain names! ๐Ÿ˜…

๐Ÿ† What You Learned

Youโ€™re now a web hosting pro! You can:

  • โœ… Install and configure Apache
  • โœ… Set up virtual hosts
  • โœ… Configure SSL/TLS certificates
  • โœ… Optimize performance
  • โœ… Implement security hardening
  • โœ… Troubleshoot common issues
  • โœ… Host multiple websites

๐ŸŽฏ Why This Matters

Running your own web server means:

  • ๐Ÿ’ฐ Massive cost savings
  • ๐Ÿ”’ Complete control
  • โšก Better performance
  • ๐ŸŽฏ Custom configurations
  • ๐Ÿ“ˆ Unlimited scalability
  • ๐Ÿ’ช Professional skills

Last month, I migrated a client from managed hosting ($300/month) to their own Apache server ($20/month VPS). Same performance, 10% of the cost, plus they can host unlimited sites now. Thatโ€™s the power of knowing Apache! ๐Ÿš€

Remember: Every major website started on a simple Apache server. Now you have the same tools! ๐ŸŒ

Happy hosting! May your sites be fast and your uptime 100%! ๐ŸŽ‰โœจ