Skip to main contentSkip to navigation
[email protected]
Client AreaSupport
Hosting Mammoth
HostingMammothYour Data, Our Responsibility
Home
Solutions
Hosting Services
Store
Pricing
About
Blog
API
Contact

Stay Ahead of the Curve

Get the latest insights on cybersecurity, AI innovations, and enterprise data solutions delivered to your inbox.

Hosting Mammoth
HostingMammothEnterprise Solutions

Enterprise-grade data solutions. Hosting, recovery, cybersecurity, and AI-powered services for businesses worldwide.

[email protected]
Sun - Fri, 9:00am - 5:00pm

Services

  • Cloud Hosting
  • Data Recovery
  • Cybersecurity
  • Legal Support
  • MSP Services
  • Web Development
  • AI Services
  • Free Server Migration

Hosting

  • VPS Hosting (NVMe SSD)
  • VDS Hosting (NVMe)
  • Storage VPS (High SSD)
  • GPU Servers
  • Managed Services
  • Cloud Firewall
  • Load Balancer
  • One-Click Apps
  • n8n Hosting
  • Object Storage
  • FAQ

Company

  • Store
  • Pricing
  • About Us
  • Locations
  • Blog
  • Testimonials
  • Contact
  • Affiliate Program
  • White-Label
  • Terms of Service
  • Privacy Policy
  • Browser Cookies
  • SLA

Support

  • Client Area
  • Submit Ticket
  • Knowledge Base
  • Server Status
  • API Documentation

© 2026 Hosting Mammoth. All rights reserved.

Knowledge Base
Getting StartedAccount ManagementVPS HostingGPU ServersStorage VPSCloud FirewallLoad BalancerServer ManagementBilling & PaymentsSupport & TicketsAffiliate ProgramReseller ProgramMarketplace & Appsn8n HostingManaged ServicesServer MigrationAPI & DevelopersSecurityTroubleshootingGlossaryInstall Guides
  1. Home
  2. /
  3. Support
  4. /
  5. Install Guides
  6. /
  7. How To Install Apache Ubuntu
GUIDEInstall Guides

How to Install Apache on Ubuntu 24.04 — Web Server Setup

19 min read

How to Install Apache on Ubuntu 24.04 — Web Server Setup

Quick Summary

This guide walks you through installing and configuring the Apache HTTP Server (apache2) on Ubuntu 24.04 LTS. By the end, you will have a hardened, production-ready web server with virtual hosts, HTTPS via Let's Encrypt, HTTP/2, caching, compression, and a tuned MPM event worker — all behind a properly configured UFW firewall.

Already comfortable with Apache? Jump to Install Apache via apt or Create Your First Virtual Host.

Table of Contents

  • What is Apache?
  • Apache vs Nginx — Which Should You Use?
  • Prerequisites
  • Install Apache via apt
  • Verify the Installation
  • Configure the UFW Firewall
  • Apache Directory Structure
  • Enable Essential Modules
  • Create Your First Virtual Host
  • Secure Your Site with Let's Encrypt SSL
  • Enable HTTP/2
  • Using .htaccess for URL Rewrites
  • Switch to the Event MPM for Better Performance
  • Install ModSecurity (Optional WAF)
  • Reverse Proxy to a Backend App
  • Compression with mod_deflate
  • Caching Static Assets
  • Security Hardening
  • Log Rotation
  • Troubleshooting
  • FAQ
  • Next Steps

What is Apache?

Apache HTTP Server, commonly called just "Apache" or "httpd", is the oldest widely used open-source web server on the internet. It was first released in 1995 by the Apache Software Foundation, and for more than a decade it powered the majority of public websites. Even in 2026, Apache still runs a substantial share of the web — especially WordPress sites, legacy LAMP stacks, and shared hosting platforms.

At its core, Apache is a process-based HTTP server that listens on ports 80 and 443, parses incoming HTTP requests, and returns responses. What made Apache successful is its modular architecture: almost every piece of functionality — SSL, URL rewriting, compression, authentication, caching, proxying — is implemented as a loadable module. You enable only what you need and leave the rest disabled.

Apache's other defining feature is the .htaccess file. Any directory served by Apache can contain a .htaccess file with directives that override the server configuration for that directory. This is why Apache dominates shared hosting: a customer can configure redirects, authentication, and caching without root access to the server. No other mainstream web server supports per-directory configuration quite like Apache.

On Ubuntu the package is called apache2, and the Debian/Ubuntu maintainers provide a particularly clean directory layout (sites-available, sites-enabled, mods-available, mods-enabled) with helper commands like a2ensite, a2enmod, and a2enconf that make managing complex configurations straightforward.

Apache vs Nginx — Which Should You Use?

Before you install Apache, make sure it is the right tool. The two dominant web servers on Linux are Apache and Nginx, and each has genuine strengths.

Apache is the right choice when:

  • You run PHP applications (WordPress, Joomla, Drupal, Magento, Moodle). The mod_php and PHP-FPM integrations on Apache are mature and well documented.
  • You need .htaccess support. Applications like WordPress ship with .htaccess files that assume Apache. Porting them to Nginx requires translating every rule into server config.
  • You host multiple tenants who need per-directory configuration without root.
  • You use complex authentication schemes — LDAP, Kerberos, client certificates. Apache's mod_auth_* ecosystem is unmatched.
  • You have a legacy stack and Apache is what your team already knows.
Nginx is the right choice when:

  • You serve static files, images, or large downloads at high concurrency. Nginx's event-driven model uses less memory per connection.
  • You need a reverse proxy or load balancer in front of Node.js, Python, Go, or Rails applications.
  • You terminate SSL for tens of thousands of concurrent connections.
  • You value a single config file over per-directory overrides.
In practice many production setups use both — Nginx as the front-facing reverse proxy and static file server, with Apache behind it handling PHP and .htaccess rules. With modern Apache (MPM event + HTTP/2 + mod_http2), the performance gap has narrowed significantly. For most single-VPS workloads, either server will perform well. Pick the one whose configuration model matches your applications.

Prerequisites

Before starting, make sure you have:

  • A VPS running Ubuntu 24.04 LTS with at least 1 GB RAM (2 GB recommended for production)
  • Root or a user with sudo privileges
  • A domain name with an A record pointing to your VPS (required for SSL)
  • Ports 80 (HTTP) and 443 (HTTPS) reachable from the internet
Update the package index and upgrade installed packages first:

bash
sudo apt update && sudo apt upgrade -y

Install Apache via apt

Ubuntu's official apache2 package is always a good choice — it is backported, security-patched, and integrates with systemd, logrotate, and the Debian module helpers.

bash
sudo apt install apache2 -y

This installs the Apache 2.4.x binary, the default MPM (prefork on most fresh installs), and a minimal set of enabled modules. The installer also starts the service and enables it on boot.

Confirm the installed version:

bash
apache2 -v

You should see output similar to:

text
Server version: Apache/2.4.58 (Ubuntu)
Server built:   2026-01-15T10:23:17

Verify the Installation

Check that the service is running:

bash
sudo systemctl status apache2

You should see active (running) in green. If it is not running, start it:

bash
sudo systemctl start apache2
sudo systemctl enable apache2

Now test that Apache is serving pages. Open a browser and navigate to your VPS IP:

text
http://YOUR_SERVER_IP/

You should see the default "Apache2 Ubuntu Default Page" — a purple banner with links to documentation and configuration hints. If you see this page, Apache is installed correctly.

From the command line you can also run:

bash
curl -I http://localhost/

You should get back HTTP/1.1 200 OK with a Server: Apache/2.4.58 (Ubuntu) header.

Configure the UFW Firewall

Ubuntu 24.04 ships with UFW (Uncomplicated Firewall). If you have not configured it yet, open Apache's ports now.

Check available application profiles:

bash
sudo ufw app list

You will see three Apache profiles:

  • Apache — HTTP only (port 80)
  • Apache Secure — HTTPS only (port 443)
  • Apache Full — both HTTP and HTTPS
For a production web server, allow Apache Full and SSH:

bash
sudo ufw allow OpenSSH
sudo ufw allow 'Apache Full'
sudo ufw enable
sudo ufw status

Output should show:

text
Status: active

To Action From -- ------ ---- OpenSSH ALLOW Anywhere Apache Full ALLOW Anywhere

Apache Directory Structure

Ubuntu's Apache layout is organized for clarity. Spend a minute understanding it before you edit anything.

text
/etc/apache2/
├── apache2.conf              # Main configuration file (loads everything else)
├── ports.conf                # Listen directives (which ports Apache binds)
├── envvars                   # Environment variables for the apache2 process
├── magic                     # MIME type magic database
├── conf-available/           # Available snippets (security.conf, charset.conf, ...)
├── conf-enabled/             # Symlinks to enabled snippets
├── mods-available/           # Available modules (ssl.load, rewrite.load, ...)
├── mods-enabled/             # Symlinks to enabled modules
├── sites-available/          # Available virtual hosts (000-default.conf, ...)
└── sites-enabled/            # Symlinks to enabled virtual hosts

Key points:

  • Never edit files in mods-enabled/ or sites-enabled/ directly. They are symlinks. Edit the originals in mods-available/ or sites-available/.
  • Use the a2* helpers to toggle things on and off:
- a2enmod / a2dismod for modules - a2ensite / a2dissite for virtual hosts - a2enconf / a2disconf for config snippets
  • Web content defaults to /var/www/html/, but you can place sites anywhere. Many admins use /var/www/example.com/public/ per domain.
  • Logs live in /var/log/apache2/ — access.log and error.log by default, with per-site logs configurable in each virtual host.

Enable Essential Modules

A fresh install enables a minimal module set. For a modern production web server, turn on the following:

bash
sudo a2enmod ssl
sudo a2enmod rewrite
sudo a2enmod headers
sudo a2enmod proxy
sudo a2enmod proxy_http
sudo a2enmod http2
sudo a2enmod deflate
sudo a2enmod expires
sudo systemctl restart apache2

What each module does:

  • ssl — terminates HTTPS. Required for Let's Encrypt.
  • rewrite — pattern-based URL rewriting. Required by WordPress, Laravel, and most modern frameworks.
  • headers — lets you set, append, and remove HTTP headers (HSTS, CSP, cache-control, etc).
  • proxy + proxy_http — reverse proxy to backend apps over HTTP.
  • http2 — HTTP/2 support for multiplexed connections and header compression.
  • deflate — gzip compression of responses.
  • expires — set Expires headers for browser caching of static assets.
Verify loaded modules:

bash
apache2ctl -M

Create Your First Virtual Host

Virtual hosts let a single Apache instance serve multiple domains. Each domain has its own configuration file in sites-available/.

Create a document root:

bash
sudo mkdir -p /var/www/example.com/public
sudo chown -R $USER:$USER /var/www/example.com
echo '<h1>example.com works</h1>' | sudo tee /var/www/example.com/public/index.html

Create the virtual host config:

bash
sudo nano /etc/apache2/sites-available/example.com.conf

Paste the following (replace example.com with your domain):

apache
<VirtualHost *:80>
    ServerName example.com
    ServerAlias www.example.com
    ServerAdmin [email protected]
    DocumentRoot /var/www/example.com/public

<Directory /var/www/example.com/public> 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>

A few notes on this config:

  • Options -Indexes disables automatic directory listings when no index.html is present.
  • AllowOverride All lets .htaccess files override server config within this directory. If you do not use .htaccess, set this to None for a small performance improvement.
  • Require all granted is the Apache 2.4 access-control directive replacing the old Allow from all.
Enable the site and disable the Ubuntu default:

bash
sudo a2ensite example.com.conf
sudo a2dissite 000-default.conf
sudo apache2ctl configtest
sudo systemctl reload apache2

apache2ctl configtest catches syntax errors before you reload. Always run it after editing a config file.

Visit http://example.com/ in a browser and you should see your "example.com works" heading.

Secure Your Site with Let's Encrypt SSL

HTTPS is mandatory in 2026. Certbot automates the entire certificate issuance and renewal process for Let's Encrypt.

Install Certbot with the Apache plugin:

bash
sudo apt install certbot python3-certbot-apache -y

Request and install a certificate:

bash
sudo certbot --apache -d example.com -d www.example.com

Certbot will:

  • Verify you control the domains via HTTP-01 challenge.
  • Obtain certificates from Let's Encrypt.
  • Create /etc/apache2/sites-available/example.com-le-ssl.conf with the HTTPS virtual host.
  • Offer to redirect all HTTP traffic to HTTPS — choose option 2 (redirect).
  • Reload Apache.
  • Certbot also installs a systemd timer that renews certificates automatically. Confirm it is scheduled:

    bash
    sudo systemctl list-timers | grep certbot

    You can dry-run the renewal at any time:

    bash
    sudo certbot renew --dry-run

    Visit https://example.com/ — you should see your site served with a valid SSL certificate.

    Enable HTTP/2

    HTTP/2 dramatically speeds up page loads by multiplexing many requests over a single TCP connection and compressing headers. You already enabled mod_http2 above. Now activate the protocol in your SSL virtual host.

    Edit the SSL config Certbot created:

    bash
    sudo nano /etc/apache2/sites-available/example.com-le-ssl.conf

    Add the Protocols directive inside <VirtualHost *:443>:

    apache
    <VirtualHost *:443>
        ServerName example.com
        ServerAlias www.example.com
        DocumentRoot /var/www/example.com/public

    Protocols h2 http/1.1

    SSLEngine on SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem

    # Strong SSL settings SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1 SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384 SSLHonorCipherOrder off SSLSessionTickets off

    # HSTS (only after you have confirmed HTTPS works) Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains"

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

    ErrorLog ${APACHE_LOG_DIR}/example.com-ssl-error.log CustomLog ${APACHE_LOG_DIR}/example.com-ssl-access.log combined </VirtualHost>

    Reload Apache:

    bash
    sudo apache2ctl configtest && sudo systemctl reload apache2

    Confirm HTTP/2 with curl:

    bash
    curl -I --http2 https://example.com/

    You should see HTTP/2 200.

    Note: HTTP/2 requires the event MPM (see next section) or worker MPM. The default prefork MPM does not support HTTP/2.

    Using .htaccess for URL Rewrites

    Because the virtual host above uses AllowOverride All, you can drop a .htaccess file in your document root to configure redirects, rewrites, and headers without editing server config.

    Example /var/www/example.com/public/.htaccess:

    apache
    # Force HTTPS (redundant if Certbot already redirects, but harmless)
    RewriteEngine On
    RewriteCond %{HTTPS} off
    RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

    Force www (or strip www — pick one)

    RewriteCond %{HTTP_HOST} ^example\.com$ [NC] RewriteRule ^(.*)$ https://www.example.com/$1 [L,R=301]

    Remove trailing slashes from URLs

    RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.+)/$ /$1 [L,R=301]

    Pretty URLs for a PHP app (WordPress-style)

    RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]

    Block access to hidden files (.git, .env, etc)

    RewriteRule "(^|/)\." - [F]

    Custom error pages

    ErrorDocument 404 /404.html ErrorDocument 500 /500.html

    .htaccess takes effect immediately — no Apache reload required. If a rule does not work, check /var/log/apache2/error.log for parse errors.

    Switch to the Event MPM for Better Performance

    Apache's Multi-Processing Module (MPM) determines how it handles concurrent requests. Ubuntu often installs the prefork MPM by default, which spawns one process per connection — simple but memory-hungry and HTTP/2-incompatible.

    For modern workloads, switch to the event MPM, which uses a thread-per-connection model with a dedicated listener thread and scales to thousands of concurrent connections.

    bash
    sudo a2dismod mpm_prefork
    sudo a2enmod mpm_event
    sudo systemctl restart apache2
    Caution: If you use mod_php (the in-process PHP module), it requires mpm_prefork. With mpm_event you must run PHP via PHP-FPM instead:
    >
    bash
    > sudo apt install php php-fpm libapache2-mod-fcgid -y
    > sudo a2enmod proxy_fcgi setenvif > sudo a2enconf php8.3-fpm > sudo systemctl restart apache2 >

    Tune the event MPM in /etc/apache2/mods-available/mpm_event.conf:

    apache
    <IfModule mpm_event_module>
        StartServers             4
        MinSpareThreads          25
        MaxSpareThreads          75
        ThreadLimit              64
        ThreadsPerChild          25
        MaxRequestWorkers        400
        MaxConnectionsPerChild   10000
    </IfModule>

    Rough sizing guide: MaxRequestWorkers should be roughly (available RAM in MB) / (average worker memory in MB). On a 2 GB VPS running a lightweight PHP app, 150 is a reasonable starting point.

    Install ModSecurity (Optional WAF)

    ModSecurity is a web application firewall that inspects incoming requests and blocks known attack patterns (SQL injection, XSS, path traversal). It is optional but highly recommended for public-facing sites.

    bash
    sudo apt install libapache2-mod-security2 -y
    sudo cp /etc/modsecurity/modsecurity.conf-recommended /etc/modsecurity/modsecurity.conf
    sudo sed -i 's/SecRuleEngine DetectionOnly/SecRuleEngine On/' /etc/modsecurity/modsecurity.conf

    Install the OWASP Core Rule Set:

    bash
    sudo apt install modsecurity-crs -y
    sudo systemctl restart apache2

    Test that ModSecurity is blocking attacks:

    bash
    curl "http://example.com/?id=1' OR '1'='1"

    You should get a 403 Forbidden. Check /var/log/apache2/modsec_audit.log for the triggered rule.

    Tune rules as needed — ModSecurity is aggressive by default and often triggers false positives on legitimate admin traffic.

    Reverse Proxy to a Backend App

    Apache makes an excellent reverse proxy in front of Node.js, Python, Go, or Java backends. Create a virtual host that forwards requests to a backend running on localhost:3000:

    apache
    <VirtualHost *:443>
        ServerName app.example.com
        DocumentRoot /var/www/app.example.com/public

    Protocols h2 http/1.1

    SSLEngine on SSLCertificateFile /etc/letsencrypt/live/app.example.com/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/app.example.com/privkey.pem

    # Preserve host + client IP ProxyPreserveHost On ProxyRequests Off RequestHeader set X-Forwarded-Proto "https" RequestHeader set X-Forwarded-Port "443"

    # Proxy everything except /static (served directly) ProxyPass /static ! ProxyPass / http://127.0.0.1:3000/ ProxyPassReverse / http://127.0.0.1:3000/

    ErrorLog ${APACHE_LOG_DIR}/app-error.log CustomLog ${APACHE_LOG_DIR}/app-access.log combined </VirtualHost>

    For WebSocket support (Socket.io, live updates), also enable mod_proxy_wstunnel:

    bash
    sudo a2enmod proxy_wstunnel

    Then add:

    apache
    RewriteEngine On
    RewriteCond %{HTTP:Upgrade} =websocket [NC]
    RewriteRule /(.*)           ws://127.0.0.1:3000/$1 [P,L]

    Compression with mod_deflate

    You enabled mod_deflate earlier. Now configure what gets compressed. Edit /etc/apache2/mods-available/deflate.conf:

    apache
    <IfModule mod_deflate.c>
        <IfModule mod_filter.c>
            AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript
            AddOutputFilterByType DEFLATE application/javascript application/json application/xml
            AddOutputFilterByType DEFLATE application/xhtml+xml application/rss+xml
            AddOutputFilterByType DEFLATE image/svg+xml font/ttf font/otf font/woff font/woff2
        </IfModule>
    </IfModule>

    Do not compress already-compressed formats (JPEG, PNG, WebP, MP4, ZIP) — you waste CPU for no gain.

    Test:

    bash
    curl -H "Accept-Encoding: gzip" -I https://example.com/

    You should see Content-Encoding: gzip in the response.

    Caching Static Assets

    Tell browsers to cache CSS, JS, and images aggressively. Add to your virtual host or .htaccess:

    apache
    <IfModule mod_expires.c>
        ExpiresActive On

    ExpiresByType text/css "access plus 1 year" ExpiresByType application/javascript "access plus 1 year" ExpiresByType image/jpeg "access plus 1 year" ExpiresByType image/png "access plus 1 year" ExpiresByType image/webp "access plus 1 year" ExpiresByType image/svg+xml "access plus 1 year" ExpiresByType font/woff2 "access plus 1 year" ExpiresByType text/html "access plus 10 minutes" </IfModule>

    <IfModule mod_headers.c> <FilesMatch "\.(css|js|jpg|jpeg|png|webp|svg|woff2|ttf|ico)$"> Header set Cache-Control "public, max-age=31536000, immutable" </FilesMatch> </IfModule>

    Use hashed filenames in production (app.a1b2c3.css) so you can cache for a year and bust the cache by changing the filename on deploy.

    Security Hardening

    Apache's default config reveals more than it should. Lock it down.

    Edit /etc/apache2/conf-available/security.conf:

    apache
    # Hide Apache version in Server header and error pages
    ServerTokens Prod
    ServerSignature Off

    Disable TRACE method (prevents cross-site tracing)

    TraceEnable Off

    Prevent clickjacking

    Header always set X-Frame-Options "SAMEORIGIN"

    Prevent MIME-type sniffing

    Header always set X-Content-Type-Options "nosniff"

    Basic referrer policy

    Header always set Referrer-Policy "strict-origin-when-cross-origin"

    Disable directory listing globally

    <Directory /var/www/> Options -Indexes </Directory>

    Reload:

    bash
    sudo systemctl reload apache2

    Additional hardening checklist:

    • Run Apache as the www-data user (default on Ubuntu — do not change).
    • Keep apache2 updated via unattended-upgrades.
    • Disable AllowOverride All where you do not need .htaccess.
    • Set strict file permissions: sudo chown -R www-data:www-data /var/www/example.com && sudo find /var/www/example.com -type d -exec chmod 755 {} \; && sudo find /var/www/example.com -type f -exec chmod 644 {} \;
    • Install fail2ban to block brute-force attempts against your login endpoints.

    Log Rotation

    Ubuntu ships with logrotate pre-configured for Apache. The rules live in /etc/logrotate.d/apache2:

    text
    /var/log/apache2/*.log {
        daily
        missingok
        rotate 14
        compress
        delaycompress
        notifempty
        create 640 root adm
        sharedscripts
        postrotate
            if invoke-rc.d apache2 status > /dev/null 2>&1; then
                invoke-rc.d apache2 reload > /dev/null 2>&1
            fi
        endscript
    }

    This rotates logs daily, keeps 14 days, and gzips old files. For very high-traffic sites, change daily to hourly or rotate to a higher number. Test the config without applying:

    bash
    sudo logrotate -d /etc/logrotate.d/apache2

    Troubleshooting

    "403 Forbidden"

    Usually a file permission problem or a missing Require all granted. Check:

  • Does the directory have an index.html or index.php?
  • Is Options -Indexes preventing listing when no index file exists?
  • Does www-data have read access: sudo -u www-data cat /var/www/example.com/public/index.html?
  • Does the <Directory> block include Require all granted?
  • "500 Internal Server Error"

    Check /var/log/apache2/error.log and the per-site error log. Common causes:

    • Syntax error in .htaccess
    • Missing PHP module (if running PHP)
    • Wrong file permissions on scripts
    • Too-restrictive Options that disable required features

    "Address already in use: AH00072: make_sock: could not bind to address [::]:80"

    Another process is using port 80. Find it:

    bash
    sudo ss -tlnp | grep :80

    Usually this is Nginx or an old Apache instance. Stop it:

    bash
    sudo systemctl stop nginx
    

    or

    sudo pkill -9 httpd sudo systemctl start apache2

    Certbot fails with "Timeout during connect"

    Cloudflare or your firewall is blocking the HTTP-01 challenge. Either:

    • Temporarily pause Cloudflare proxying (grey cloud) and retry.
    • Use the DNS-01 challenge: sudo certbot --dns-cloudflare -d example.com.

    Apache serves the default page instead of your site

    Your virtual host is not being picked up. Check:

    bash
    sudo apache2ctl -S

    This lists all loaded virtual hosts. If yours is missing, you forgot a2ensite or the config has a syntax error (apache2ctl configtest).

    High CPU or memory usage

    • Check the MPM: apache2ctl -V | grep MPM. Switch prefork to event.
    • Lower MaxRequestWorkers if you are OOM-killing processes.
    • Look for slow PHP scripts in access.log with awk '{print $7, $NF}' /var/log/apache2/access.log | sort | uniq -c | sort -rn | head -20.

    FAQ

    Is Apache still relevant in 2026? Yes. It powers roughly a third of active websites, dominates WordPress hosting, and remains the standard for shared hosting. For PHP apps and anything needing .htaccess, Apache is often the better choice.

    Should I use Apache or Nginx? For PHP + .htaccess workloads, Apache. For static files and reverse proxying at scale, Nginx. Many sites run both.

    Can I run Apache and Nginx on the same server? Yes, but not on the same port. A common setup is Nginx on :80/:443 handling SSL and static files, proxying dynamic requests to Apache on :8080 for PHP execution.

    What is the best MPM for Apache? For almost all modern workloads, event. Use prefork only if you must use mod_php and cannot switch to PHP-FPM.

    How do I host multiple domains? Create one file per domain in sites-available/, enable each with a2ensite. Each virtual host can have its own document root, SSL cert, and logs.

    Do I need .htaccess files? Only if you cannot edit the main server config (shared hosting) or you run apps that ship with one (WordPress). Otherwise, moving rules into the virtual host is faster because Apache does not re-read .htaccess on every request.

    How do I enable PHP? Install PHP-FPM (sudo apt install php-fpm) and enable proxy_fcgi + php8.3-fpm config. Avoid mod_php on modern setups.

    How do I increase the upload size? In your PHP-FPM pool (/etc/php/8.3/fpm/php.ini): upload_max_filesize = 100M and post_max_size = 100M. In Apache, also set LimitRequestBody 104857600 in your virtual host.

    Next Steps

    You now have a production-ready Apache web server with HTTPS, HTTP/2, compression, caching, and sensible security defaults. Where to go from here:

    • Install a CMS — Deploy WordPress, Ghost, or Drupal on top of this stack.
    • Add PHP-FPM — Run modern PHP applications with better performance than mod_php.
    • Set up fail2ban — Block brute-force and scanning attempts against your virtual hosts.
    • Configure Cloudflare — Put a CDN in front of Apache for DDoS protection and global caching.
    • Monitor with mod_status — Enable the server-status endpoint for real-time worker metrics.
    • Automate deployments — Ship code with Git hooks, CI/CD, or rsync + systemctl reload apache2.
    For most production workloads a CloudCore Starter VPS (4 vCPU, 8 GB RAM) will comfortably host a handful of PHP sites with room to grow. If you outgrow it, Apache scales vertically just fine — add RAM and raise MaxRequestWorkers.

    Have a question or a configuration that is not covered here? Reach out to our DevOps team and we will help you tune Apache for your specific workload.

    Was this article helpful?

    ← Back to Install GuidesBrowse all categories →

    Still have questions?

    Contact Support →Submit a Ticket