Apache HTTP Server powers a huge share of the world's websites, and it remains one of the simplest web servers to get running on a fresh Linux box. In this guide you will install Apache on Ubuntu 24.04 from scratch, open it through the firewall, verify it serves pages correctly, and set up your first virtual host so you can host your own domain. This tutorial is for anyone with a new Ubuntu 24.04 VPS or local machine who wants a production-ready Apache setup — no prior Apache experience needed.
What you will end up with: Apache 2.4 serving the default welcome page on port 80, firewall rules that allow HTTP/HTTPS traffic, and a working virtual host you can point a domain at.
Prerequisites
- A server or VM running Ubuntu 24.04 LTS (this guide also works on 22.04 with no changes).
- A non-root user with sudo privileges. If you are logged in as root, drop the
sudoprefix from the commands. - Internet access so
aptcan reach the Ubuntu package repositories. - Optionally, a domain name pointed at your server's IP address if you want to test a virtual host by name.
Step 1 — Update your package index
Always refresh the package lists before installing anything. This guarantees you pull the latest available Apache build and its dependencies.
sudo apt update && sudo apt upgrade -y
apt update downloads the newest package lists from Ubuntu's repositories, while apt upgrade -y installs available updates without asking for confirmation. On a fresh cloud image this can take a few minutes.
Step 2 — Install Apache
Apache is shipped in Ubuntu's default repositories, so a single command installs it along with its default modules:
sudo apt install apache2 -y
This installs the apache2 package (Apache 2.4 on Ubuntu 24.04), the default multi-processing module (mpm_event), and the standard set of modules. The installer also enables and starts the service automatically. Confirm the installed version:
apache2 -v
You should see output similar to Server version: Apache/2.4.58 (Ubuntu).
Step 3 — Enable and verify the Apache service
Check that Apache started and is set to launch on boot:
sudo systemctl enable --now apache2
--now starts the service immediately while enable makes it persistent across reboots. Verify its state:
sudo systemctl status apache2
Look for Active: active (running) in green. If it shows anything else, check the log at /var/log/apache2/error.log for the reason.
Step 4 — Allow Apache through the firewall
Ubuntu servers commonly run UFW (Uncomplicated Firewall). Apache registers ready-made application profiles with it. List them:
sudo ufw app list
You will see three Apache profiles: Apache (port 80), Apache Secure (port 443), and Apache Full (both ports). Since you will likely want HTTPS later, allow both:
sudo ufw allow 'Apache Full'
Then enable UFW if it is not already running, and check the status:
sudo ufw enable
sudo ufw status
ufw status should now show Apache Full as ALLOW on IPv4 and IPv6. If you use a different firewall (for example, cloud provider security groups on AWS/DigitalOcean), open TCP ports 80 and 443 there instead.
Step 5 — Test that Apache is serving pages
First find your server's public IP address:
hostname -I | awk '{print $1}'
hostname -I lists all local IPs; the first one is usually your main address. Now request the default page directly from the server:
curl -I http://localhost
A HTTP/1.1 200 OK header confirms Apache is responding. Finally, open http://YOUR_SERVER_IP in a browser — you should see the Apache2 Ubuntu Default Page. If the page does not load in the browser but curl works locally, a firewall or security group is blocking port 80; revisit Step 4.
Step 6 — Learn the important Apache files and directories
Before customizing anything, know where Apache keeps things on Ubuntu:
/etc/apache2/— main configuration directory./etc/apache2/apache2.conf— the primary configuration file./etc/apache2/sites-available/— virtual host definitions (per-site)./etc/apache2/sites-enabled/— symlinks to the sites that are actually active./etc/apache2/mods-available/andmods-enabled/— same idea for modules./var/www/html/— the default document root (the page you saw in the browser lives at/var/www/html/index.html)./var/log/apache2/— access and error logs.
You never edit files inside sites-enabled or mods-enabled directly — you edit the -available copy and flip it on with a2ensite / a2enmod.
Step 7 — Create your first virtual host
A virtual host lets Apache serve multiple websites from one server. Let us set one up for example.com (replace it with your real domain everywhere below). First, create the document root and a simple index page:
sudo mkdir -p /var/www/example.com
echo '<h1>Hello from example.com</h1>' | sudo tee /var/www/example.com/index.html
mkdir -p creates the directory (including parents if needed), and tee writes the HTML while running with sudo so file permissions stay root-owned.
Now create the virtual host configuration file:
sudo nano /etc/apache2/sites-available/example.com.conf
Paste in the following block:
<VirtualHost *:80>
ServerName example.com
ServerAlias www.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>
ServerName is the primary domain, ServerAlias covers the www variant, and DocumentRoot tells Apache which folder to serve. The two log lines give this site its own dedicated logs, which makes debugging far easier.
Enable the new site, disable the default one, and reload Apache:
sudo a2ensite example.com.conf
sudo a2dissite 000-default.conf
sudo systemctl reload apache2
a2ensite creates the symlink in sites-enabled; reload applies the change without dropping active connections. Test it:
curl -H "Host: example.com" http://localhost
You should get back <h1>Hello from example.com</h1>. If your domain's DNS already points at this server, browsing to http://example.com shows the same page.
Step 8 — Enable useful modules (rewrite)
Many applications (WordPress, Laravel, clean-URL frameworks) need mod_rewrite. Enable it and allow .htaccess overrides in your virtual host:
sudo a2enmod rewrite
This flips the module on. Then add an AllowOverride directive to your site's config so .htaccess files are honored:
<Directory /var/www/example.com>
AllowOverride All
</Directory>
Place that block inside your <VirtualHost *:80> section, then test the configuration syntax and reload:
sudo apache2ctl configtest
sudo systemctl reload apache2
apache2ctl configtest reports Syntax OK when your configuration is valid. Run it before every reload — it catches typos before they take a site down.
Step 9 — Harden the basic configuration
Two small tweaks reduce the information Apache leaks to potential attackers. Edit the security configuration:
sudo nano /etc/apache2/conf-available/security.conf
Make sure these two lines are present and set as shown:
ServerTokens Prod
ServerSignature Off
ServerTokens Prod trims the Server response header down to just "Apache" instead of broadcasting the exact version and OS, while ServerSignature Off removes the Apache version footer from error pages. Apply with a reload:
sudo systemctl reload apache2
Step 10 — Verify the full setup
Run through this checklist to confirm everything works:
- Service running:
sudo systemctl is-active apache2should printactive. - Listening on port 80:
sudo ss -tlnp | grep :80should show Apache listening. - Serves pages locally:
curl -I http://localhostreturns200 OK. - Reachable from outside: open
http://YOUR_SERVER_IPin a browser (or your domain if DNS is set). - No config errors:
sudo apache2ctl configtestprintsSyntax OK.
Check the logs whenever something misbehaves — they are the fastest path to the answer:
sudo tail -f /var/log/apache2/error.log
sudo tail -f /var/log/apache2/access.log
Common issues & fixes
1. "Address already in use: could not bind to address 0.0.0.0:80"
Another program (often Nginx) is holding port 80. Find it with sudo ss -tulpn | grep :80, then either stop that service (sudo systemctl stop nginx) or move Apache to a different port in /etc/apache2/ports.conf.
2. Browser shows "connection refused" but curl works locally
Port 80 is blocked before traffic reaches Apache. Re-run sudo ufw allow 'Apache Full' and verify with sudo ufw status. On cloud VPS providers, also check the provider's firewall/security group panel.
3. "Forbidden — You don't have permission to access /"
This is almost always a file-permission problem. The Apache user www-data needs read access to your document root:
sudo chown -R www-data:www-data /var/www/example.com
sudo chmod -R 755 /var/www/example.com
4. Apache fails to reload after editing a config
Run sudo apache2ctl configtest first — it names the file and line number with the syntax error. Fix it, then reload again.
5. .htaccess rules are ignored
You skipped the AllowOverride All directory block from Step 8, or mod_rewrite is not enabled. Add both and reload Apache.
Conclusion
You now have Apache 2.4 installed on Ubuntu 24.04, open through the firewall, verified end to end, and serving your first virtual host with mod_rewrite ready for real applications. The natural next steps are adding HTTPS with a free Let's Encrypt certificate and tuning the MPM settings for your server's RAM — both of which turn this solid default install into a production-grade web server.
If setting up or tuning Apache for a client project feels like a distraction from building your product, XpertBees handles server setup, hardening, and ongoing maintenance for businesses — reach out and we will take the infrastructure off your plate.



