Apache HTTP Server has powered websites since 1995 and remains a solid choice — especially when you rely on .htaccess files, as many PHP applications and shared-hosting migrations do. Here’s how to install and configure it on Ubuntu.

1. Install Apache

sudo apt update
sudo apt install -y apache2

The package is called apache2 on Ubuntu and Debian (it’s httpd on AlmaLinux and Rocky). The service starts right away:

systemctl status apache2 --no-pager
apache2 -v

2. Allow web traffic through UFW

sudo ufw allow 'Apache Full'   # 80 and 443
sudo ufw status

Visit http://YOUR_SERVER_IP and you’ll see the “Apache2 Default Page”.

3. Configuration layout

Path Purpose
/etc/apache2/apache2.conf Main configuration
/etc/apache2/ports.conf Ports Apache listens on
/etc/apache2/sites-available/ Virtual host files
/etc/apache2/sites-enabled/ Symlinks to active sites
/etc/apache2/mods-available/, mods-enabled/ Modules
/etc/apache2/conf-available/, conf-enabled/ Extra global config snippets
/var/www/html Default document root
/var/log/apache2/ access.log, error.log

Ubuntu provides helper commands to manage the symlinks:

sudo a2ensite example.com.conf    # enable a site
sudo a2dissite 000-default.conf   # disable the default site
sudo a2enmod rewrite              # enable a module
sudo a2dismod status              # disable a module
sudo a2enconf security            # enable a config snippet

4. Create a virtual host

sudo mkdir -p /var/www/example.com/public_html
echo '<h1>example.com on Apache</h1>' | sudo tee /var/www/example.com/public_html/index.html
sudo chown -R www-data:www-data /var/www/example.com

/etc/apache2/sites-available/example.com.conf:

<VirtualHost *:80>
    ServerName example.com
    ServerAlias www.example.com
    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>

AllowOverride All lets .htaccess files in that directory change settings — needed by WordPress, Laravel and most PHP apps. -Indexes stops Apache from listing directory contents.

Enable and test:

sudo a2ensite example.com.conf
sudo apache2ctl configtest
sudo systemctl reload apache2

Syntax OK from configtest means the config parses. Details on running several domains: Apache virtual hosts.

5. Common modules

sudo a2enmod rewrite headers expires ssl http2
sudo systemctl restart apache2
  • rewrite — URL rewriting (pretty permalinks).
  • headers / expires — security and caching headers.
  • ssl — HTTPS.
  • http2 — HTTP/2 (works with the event MPM).

6. PHP: use PHP-FPM with the event MPM

The traditional libapache2-mod-php runs PHP inside every Apache process and forces the older prefork MPM, which uses a lot of memory under load. The modern setup is event MPM + PHP-FPM:

sudo apt install -y php-fpm
sudo a2enmod proxy_fcgi setenvif
sudo a2enconf php*-fpm
sudo systemctl reload apache2

Apache then hands .php requests to PHP-FPM over a socket. More in installing PHP and MySQL.

7. Add HTTPS

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

Certbot creates an SSL virtual host and the HTTP→HTTPS redirect. See Let’s Encrypt with Certbot on Apache.

8. Hide version information

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

ServerTokens Prod
ServerSignature Off

Reload Apache. Response headers will show just Server: Apache instead of the exact version and OS.

Managing Apache

sudo apache2ctl configtest       # always test before reloading
sudo systemctl reload apache2    # graceful reload
sudo systemctl restart apache2   # needed after enabling/disabling modules
sudo apache2ctl -S               # list virtual hosts and which is default
sudo apache2ctl -M               # list loaded modules

Troubleshooting

AH00558: Could not reliably determine the server's fully qualified domain name — a harmless warning. Silence it:

echo 'ServerName localhost' | sudo tee /etc/apache2/conf-available/servername.conf
sudo a2enconf servername && sudo systemctl reload apache2

(98)Address already in use: AH00072: make_sock: could not bind to address [::]:80 — Nginx or another server holds port 80. Check with sudo ss -tlnp | grep ':80'.

.htaccess rules ignored — AllowOverride is None for that directory, or mod_rewrite isn’t enabled.

403 Forbidden — missing Require all granted, no index file with -Indexes, or the files aren’t readable by www-data.

Apache or Nginx?

Apache’s strengths are .htaccess and its huge module ecosystem; Nginx is leaner for static files and reverse proxying. Both handle typical sites well. A popular combination is Nginx in front as a reverse proxy with Apache behind it for legacy apps. Read Nginx vs Apache for a fuller comparison, or install Nginx instead.

Our Ubuntu VPS plans ship with a clean Ubuntu install, ready for either web server.

  • Apache
  • Ubuntu
  • Web Server