How To Install the Apache Web Server on Ubuntu
Source: DigitalOcean
By Erin Glass and Manikandan Kurup The Apache HTTP Server, or Apache, is one of the most widely used web servers in the world. Since its release in 1995, it has remained popular because it is open source, reliable, and easy to customize. Even in 2025, Apache continues to be a dependable choice for hosting websites and applications on Linux servers such as Ubuntu. Apache uses a modular design that allows you to enable only the features you need, such as SSL encryption, caching, or URL rewriting. On Ubuntu 24.04, Apache is included with the event MPM as the default processing module, offering improved performance for busy servers. In this tutorial, you will install Apache on an Ubuntu server, configure the firewall, set up virtual hosts, enable HTTPS with Let’s Encrypt, and learn how to manage and troubleshoot the service. This guide follows an HTTPS-first approach, helping you configure SSL early so your Apache server is secure and ready for production use. Simplify deploying applications to servers with DigitalOcean App Platform. Deploy directly from GitHub in minutes. Before you begin this guide, you should have a regular, non-root user with sudo privileges configured on your server. Additionally, you will need to enable a basic firewall to block non-essential ports. You can learn how to configure a regular user account and set up a firewall for your server by following our Initial server setup guide for Ubuntu. Once you have created a non-root user with sudo privileges, log in as that user to begin. Note: This guide has been tested on Ubuntu 24.04 LTS, the latest stable release at the time of writing. The commands and steps will also work on other recent Ubuntu versions, such as 22.04 LTS. However, it is recommended to use the latest stable version to ensure compatibility, security, and access to updated software packages. Apache is included in Ubuntu’s default package repositories, so you can install it using standard package management tools. Let’s start by updating your server’s local package index to make sure you’re installing the latest available version. Once the update is complete, install the apache2 package: When prompted, confirm the installation. The package manager will install Apache along with all required dependencies. After installation, you can verify that Apache was installed correctly and check the version currently running on your system: You’ll see output similar to this: Ubuntu may ship the prefork MPM by default if libapache2-mod-php is installed, because mod_php is not thread safe. To confirm which MPM (Multi-Processing Module) your system is using, run: That confirms that Apache is installed and configured with the default event-based processing model. If you want to switch to the event MPM (recommended when using PHP-FPM instead of mod_php), run: Note: mpm_event works best with PHP-FPM (php-fpm package). It does not work with mod_php because mod_php requires the prefork MPM. Tip: You can extend Apache’s functionality by installing additional modules. For example, use sudo apt install apache2-utils for common administrative tools or sudo apt install libapache2-mod-security2 to enable a web application firewall for added security. Before testing Apache, you’ll need to adjust your firewall to allow web traffic. If you followed the Initial Server Setup for Ubuntu guide, you should already have UFW (Uncomplicated Firewall) configured to restrict access to only essential services like SSH. When Apache is installed, it automatically registers a few application profiles with UFW that define which ports to open for different traffic types. To view these profiles, run: You should see output similar to this: Each profile allows different levels of access: Since most websites today use HTTPS by default, it’s best to enable the Apache Full profile to allow both HTTP and HTTPS connections: Next, verify that the rule was added successfully: You should see output similar to this: This confirms that Apache is now allowed through the firewall for both IPv4 and IPv6 traffic. Note: If your servers are running on DigitalOcean, you can optionally use DigitalOcean Cloud Firewalls instead of the UFW firewall. We recommend using only one firewall at a time to avoid conflicting rules that may be difficult to debug. After installation, Apache starts automatically. Let’s verify that it’s running and serving web pages correctly. Apache on Ubuntu is managed by systemd, which controls how services start, stop, and restart. To check whether Apache is active, run: You should see output similar to this: If you see Active: active (running), Apache is up and running. If Apache isn’t active, you can start it manually with: You can confirm Apache is serving web content by visiting your server’s public IP address. First, find your server’s IP address: This command will return one or more IP addresses. You can also get your public IPv4 address using: Copy the IPv4 address and enter it in your browser’s address bar: If Apache is working correctly, you’ll see the default Apache welcome page, which confirms your web server is running and serving requests from /var/www/html. If you’ve already configured a domain name for your server, you can also test access using your domain: Make sure your DNS records are correctly pointed to your server’s public IP. DNS changes can take a few minutes to propagate depending on your registrar. Most modern Ubuntu servers, including those on DigitalOcean, come with IPv6 enabled by default. To check whether Apache is listening on both IPv4 and IPv6 addresses, run: You should see both of these lines if IPv6 is enabled: To test locally over IPv6, open this address in your browser: Or, if your server has a public IPv6 address, use that address in brackets: Tip: If you’re testing on a remote cloud instance, make sure your provider’s networking setup supports both IPv4 and IPv6. On DigitalOcean, you can verify this under Networking -> IP Addresses in your control panel. Now that Apache is installed and running, it’s helpful to know how to control the service. Ubuntu uses systemd to manage background services, including Apache. This means you can use the systemctl command to start, stop, restart, and check the status of the web server. To stop the web server, run: To start Apache again, run: If you’ve made configuration changes and need to apply them, you can restart the service: Restarting stops and then restarts Apache, which briefly interrupts any active connections. For configuration updates that don’t require a full restart, you can instead reload the service to apply changes gracefully: Reloading tells Apache to re-read its configuration files without closing existing connections. This is useful when you’re updating virtual hosts, enabling modules, or changing log settings. By default, Apache is set to start automatically when your system boots. You can confirm this behavior by checking its enablement status: To disable Apache from starting automatically on boot: This control is useful for testing environments or servers where you only want Apache running on demand. At any time, you can view the current status of the Apache service: This command displays whether the service is running, its uptime, and recent log entries. You’ll also see the Main PID, which identifies the process Apache is using to serve requests. For a simple confirmation without full log output, you can use: If it returns active, Apache is running as expected. Apache keeps detailed logs that can help you monitor performance and diagnose issues. These logs are stored in /var/log/apache2/ by default: To view the most recent entries in the error log, use: For a broader look at Apache’s activity through systemd’s journal, use the modern log viewer: You can also view only the latest events: And to follow logs in real time: Using journalctl is often the best way to view live logs and service messages in modern Ubuntu systems, since it combines traditional logging with system-level information. Tip: For production servers, consider setting up log rotation and retention policies using logrotate, which is installed by default on Ubuntu. This prevents log files from growing too large and ensures older logs are archived automatically. When using the Apache web server, you can configure virtual hosts (similar to server blocks in Nginx) to define separate configurations for each website hosted on the same server. Virtual hosts make it easy to serve different domains or subdomains from a single machine, each with its own document root, log files, and configuration options. In this example, we’ll set up a domain called example.com, but you should replace this with your actual domain name. If you’re setting up a new domain with DigitalOcean, refer to our Networking Documentation for steps on creating DNS records that point to your server. Apache on Ubuntu includes one default site that serves content from /var/www/html. While this works for a single website, it’s better to create a separate directory for each domain you host. This structure keeps files organized and prevents conflicts when managing multiple sites. Create a new directory for your domain under /var/www: Assign ownership of the directory to your current user to make it easier to edit web files: By default, Ubuntu sets a umask value that assigns secure permissions, but you can verify the correct settings using: This gives the owner full read/write/execute access, while allowing others to read and execute files, the standard for web content. Now, let’s create a simple test page that will confirm your virtual host works correctly: Add the following HTML content: Save and close the file when finished. Apache’s virtual host configuration files are stored in the /etc/apache2/sites-available/ directory. These files define how Apache should respond to incoming HTTP requests for a given domain. Let’s create a new configuration file for your domain: Insert the following configuration block: Here’s what each directive does: Save and close the file. This configuration will handle all requests to http://example.com. Now that your configuration files are ready, you can enable your site using the a2ensite command: To prevent the default site from serving unintended traffic, disable it: Before applying any changes, always test your Apache configuration for syntax errors: You should see this output: If there are no syntax errors, reload Apache to apply the configuration changes: This command gracefully reloads the service, applying new settings without disconnecting existing users. You can confirm that both virtual hosts are active by listing the enabled sites: You’ll see an output that includes your domain and the associated configuration file paths. Now, open your browser and visit your site: If everything is set up correctly, you should see the sample page you created earlier. Using HTTPS has become the standard for all modern websites, not only to secure user data but also to improve search rankings and user trust. The easiest way to obtain and manage free SSL/TLS certificates is through Let’s Encrypt, a certificate authority that provides automated, no-cost certificates. Let’s Encrypt works together with Certbot, a lightweight command-line tool that handles certificate creation, installation, and renewal automatically. In this section, you’ll install Certbot, generate a certificate for your domain, and verify that automatic renewal is configured correctly. Certbot is included in Ubuntu’s default repositories, along with a plugin that integrates directly with Apache. Update your package index and install both packages: Once installed, you can verify Certbot’s version with: With Certbot installed, you can request and install a certificate for your domain in a single step. Replace example.com and www.example.com with your actual domain names: You’ll be asked to provide an email address for renewal notices and agree to the Let’s Encrypt Terms of Service. When prompted, you can also choose whether to redirect HTTP traffic to HTTPS. Selecting “Redirect” is recommended, as it enforces secure connections for all visitors. After the setup completes, Certbot will display a message confirming that the certificate was successfully installed. You can verify your certificate’s expiration date with: The output should list your domain name and indicate that your certificate is valid for 90 days. Let’s Encrypt certificates are valid for 90 days, but Certbot includes a built-in systemd timer that automatically renews them before they expire. You can confirm that the renewal timer is active with: You should see output similar to this: This means that Certbot will automatically check for expiring certificates twice per day and renew them if necessary. Note: If you installed Certbot via snap/distro packaging, the mechanism may be a systemd timer or a cron job. You can check this with systemctl list-timers. To manually test the renewal process without making changes, use: If you see “Congratulations! Your certificate and chain have been saved successfully.”, automatic renewal is working as expected. After your certificate is installed, open your site in a web browser and verify that it loads securely: You should see the padlock icon in the browser’s address bar, indicating that HTTPS is active and the connection is encrypted. You can also verify the configuration using the command line with: A valid response should include: If you see this response, your site is correctly serving HTTPS traffic. Now that Apache is installed, configured, and serving your site, it’s helpful to understand where key files and directories are located. Knowing how Apache’s configuration is organized will make it easier to manage multiple sites, enable modules, and troubleshoot issues later. This is where your website content lives. By default, Apache serves files from /var/www/html, which contains the default Apache landing page you saw after installation. When hosting multiple sites, it’s common to create a dedicated directory for each one, such as: Each virtual host you configure can point to its own directory inside /var/www. This structure keeps your projects organized and allows you to apply permissions or ownership separately per site. This directory contains all of Apache’s configuration files. Most of your administrative work, including enabling sites, changing ports, or managing modules, happens here. The key files and subdirectories include: Apache separates virtual host configurations into two directories: To activate a site, use: This approach makes it easy to manage multiple websites without editing global configuration files. You can quickly enable or disable sites as needed, and Apache will only load configurations that are linked in sites-enabled/. Apache’s functionality is modular, meaning most features, such as SSL, rewrite rules, or compression, are implemented as modules that can be loaded dynamically. You can enable or disable modules using these commands: For example, to enable the rewrite and ssl modules (common for HTTPS sites): After enabling or disabling modules, reload Apache to apply the changes: These directories are similar to the site directories but are used for global configuration snippets that don’t belong to a specific virtual host. For example, a configuration file that sets default security headers or MIME types might live in /etc/apache2/conf-available/, and when enabled, a symbolic link is created in /etc/apache2/conf-enabled/. You can enable or disable these configuration fragments with: Like site configurations, these fragments are only active when linked in conf-enabled/. Apache logs nearly every event, from client requests to errors, in the /var/log/apache2/ directory. Monitoring these logs is one of the best ways to understand how your server is performing and to troubleshoot problems. The two most common log files are: You can view the most recent log entries with: For a broader view across all Apache logs, you can use: This command shows recent service messages collected by systemd, combining traditional logs with service-level events. Tip: On high-traffic sites, log files can grow quickly. Ubuntu includes logrotate, which automatically compresses and rotates Apache logs to prevent them from filling up disk space. You can view its configuration at /etc/logrotate.d/apache2. Once Apache is installed and serving your websites, the next step is securing your web server. Even a correctly configured Apache installation can expose unnecessary information or become vulnerable if not hardened properly. The following best practices will help protect your system against common attacks, reduce information exposure, and keep your web environment stable and up to date. By default, Apache may display the contents of a directory if it does not contain an index file. This can unintentionally expose sensitive information, such as backup files, configuration scripts, or version numbers. To disable directory listing, open your site’s configuration file: Inside the <Directory> block or the virtual host configuration, ensure the Options directive does not include Indexes. For example: Save the file and reload Apache to apply your changes: Now, if a directory does not contain an index.html file, Apache will return a 403 Forbidden error instead of listing its contents. File and directory permissions should always follow the principle of least privilege. You can set these permissions with the following commands: These commands ensure that directories are readable and executable by everyone but writable only by the owner, while files are readable by everyone and writable only by the owner. Avoid granting 777 permissions, as they allow any user on the system to modify web files. Security headers help protect browsers from common web vulnerabilities like cross-site scripting (XSS), clickjacking, and content-type sniffing. If you have not already done so, enable the headers module: Then, open your site’s virtual host configuration file: Inside the <VirtualHost> block, add the following headers: You can also apply a basic Content Security Policy (CSP) to control which resources the browser can load: This policy allows only local scripts and styles to load from the same domain. Save your changes and reload Apache: To confirm that the headers are active, you can test your site with curl: Look for the headers in the response. You can also use securityheaders.com to analyze your configuration. Apache 2.4.58 on Ubuntu 24.04 supports TLS 1.3 by default, provided your OpenSSL version is 1.1.1 or later (check with openssl version). To ensure strong encryption and compatibility, open the SSL configuration file: Verify or update the following settings: These settings disable older, insecure protocols and ciphers. After saving the file, reload Apache: For stricter or more compatible configurations (Modern or Old profiles), you can generate templates at: SSL Configuration Generator. You can also test your site’s SSL configuration using Qualys SSL Labs to verify that it scores at least an “A” rating. Every enabled module increases Apache’s attack surface. To reduce potential vulnerabilities, disable any modules that are not required for your site. List enabled modules with: If you see a module you are not using, disable it with: For example, if your site does not use CGI scripts: After disabling modules, reload Apache: Keep essential modules such as ssl, rewrite, headers, and mpm_event active, as they are commonly used for secure, high-performance websites. Keeping your server updated is one of the most effective ways to prevent vulnerabilities. Security patches are released regularly for both Ubuntu and Apache. To ensure your server always receives updates, enable unattended-upgrades, which installs security updates automatically. Then enable automatic updates: By default, the service runs daily and applies available security updates silently. You can check the status of the timer with: Logs are stored in /var/log/unattended-upgrades/. To apply updates manually at any time, run: To further improve security and server reliability: Even a correctly configured Apache server can occasionally fail to start, reload, or serve web pages. Common issues usually involve syntax errors, missing permissions, or blocked ports. When Apache does not start or reload properly, the first place to look is the service log. Apache integrates with systemd, so logs are managed by the journalctl command. To view recent log entries: This displays Apache-related messages, including startup logs, configuration warnings, and module errors. If you want to see live log updates while restarting or reloading Apache, use: The log output can reveal valuable details such as: Checking logs is often the quickest way to pinpoint why Apache isn’t starting or responding. A common mistake is reloading Apache after editing a configuration file without testing it first. Apache includes a built-in syntax checker that scans all configuration files for errors. If your configuration is valid, you’ll see: If not, the command will show the file and line number containing the issue. For example: This tells you exactly where the problem is located. Once you fix the issue, test again until the syntax passes. Finally, reload Apache to apply the working configuration: Tip: Always run configtest before reloading Apache, especially on production servers. It prevents accidental downtime caused by broken configurations. If your Apache service starts but your site doesn’t load, it may not be listening on the expected ports (80 for HTTP, 443 for HTTPS), or another application could be using those ports. Check which ports Apache is currently listening on: You should see output similar to: This confirms Apache is listening on both HTTP and HTTPS. If no entries appear, check that your virtual hosts and SSL module are enabled: If another process is using port 80 or 443, identify it: This will show which process ID (PID) and program name are bound to the ports. For example: If another web server like Nginx or a development process (for example, Node.js) is using the same port, you can either stop that service or reconfigure one of them to use a different port. If Apache starts correctly but returns a “403 Forbidden” error or fails to load your site, it often means that file permissions or ownership are incorrect. Apache must be able to read the files under your site’s web root, and they must be owned by the right user and group. To fix ownership and permissions, run: You can confirm the permissions using: The output should look like this: If your site uses uploads or caching (like WordPress), you may need to give Apache write access to specific directories: Be cautious not to apply global write access, as it can open serious security risks. If your site works when accessed via its IP address but not through the domain name, it is usually a DNS or propagation issue. First, check that your domain points to the correct server IP: Compare the result with your server’s public IP address: If they don’t match, update your DNS records at your registrar or DNS provider. You can also check global DNS propagation using a tool such as whatsmydns.net. If you recently updated DNS records, remember that propagation can take several hours depending on the TTL (time-to-live) values configured for your domain. If you’re hosting your DNS on DigitalOcean, make sure your A (IPv4) and AAAA (IPv6) records are correctly configured in the Networking -> Domains section of the control panel. Sometimes Apache runs correctly but is inaccessible from the internet because traffic is being blocked by a firewall. Ubuntu uses UFW by default. Check your firewall status: You should see entries like this: If the Apache Full profile is missing, enable it: If you’re running Apache on a cloud provider such as DigitalOcean, confirm that the cloud firewall also allows inbound connections on ports 80 and 443. For example, in the DigitalOcean Control Panel: If you’re using a load balancer or CDN, confirm that it is properly forwarding requests to your Droplet’s IP address and ports. Apache uses virtual hosts to map domain names to specific directories and configurations. A broken or conflicting virtual host file is one of the most common problems beginners face. To list all active virtual hosts, use: This command shows each domain’s configuration file and port. Look for: If you see this warning: Add a global ServerName directive to fix it: If one of your site configurations is broken and prevents Apache from starting, disable it temporarily: Then review the file in /etc/apache2/sites-available/ for issues such as: Once fixed, re-enable the site: Your site should now load correctly. Tip: When troubleshooting Apache, isolate each issue step-by-step. Start by confirming that the service is running, then check the configuration syntax, permissions, ports, and DNS. Apache’s error logs (journalctl and /var/log/apache2/error.log) almost always contain the clues you need. You can install Apache from Ubuntu’s default repositories. Update your package index and install Apache with: Once installed, Apache starts automatically. You can verify it with: Use the systemctl command to control the Apache service: To reload configuration changes without interrupting active connections, use: You can also check if it starts automatically at boot using: Virtual hosts let you host multiple sites on one server. Create a new configuration file in /etc/apache2/sites-available/: Add a basic configuration block: Save the file, enable the site, and reload Apache: If you’re using UFW, list the available application profiles with: Then allow full Apache access (both HTTP and HTTPS): Check your firewall status to confirm: Open your browser and visit your server’s public IP address: You should see the default Apache welcome page. You can also check the service status with: If the page does not load, review the firewall settings and confirm that Apache is active. By default, Apache serves content from /var/www/html. You can replace or modify the index.html file in this directory to change what appears on your site’s home page. When hosting multiple domains, you can create additional directories such as /var/www/example.com. Start by checking for syntax errors: If you see anything other than “Syntax OK,” fix the listed issue. Then review service logs for errors: If ports 80 or 443 are already in use, identify the conflicting service with: Permission issues can also prevent Apache from reading files in /var/www/. Make sure your user and group ownership are correct and that directories are readable. Enable the SSL and headers modules first: You can then install Let’s Encrypt to get a free SSL certificate: Certbot will automatically configure HTTPS and handle renewals. Once installed, you can test renewal with: In this tutorial, you installed and configured the Apache web server on an Ubuntu server. You verified that Apache was running, allowed HTTP and HTTPS traffic through the firewall, and created virtual hosts for both protocols. You secured your site with Let’s Encrypt SSL certificates, applied key security settings, and learned how to manage Apache modules, logs, and configurations. Your server is now fully configured and ready to host production websites. To continue exploring, check out the following articles: Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases. Learn more about our products Open source advocate and lover of education, culture, and community. With over 6 years of experience in tech publishing, Mani has edited and published more than 75 books covering a wide range of data science topics. Known for his strong attention to detail and technical knowledge, Mani specializes in creating clear, concise, and easy-to-understand content tailored for developers. This textbox defaults to using Markdown to format your answer. You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link! Thank you very much for your easy instructions on installing Apache2 server. it still proves that it takes a woman to get things right.
I just switched over from centos 7 to the ubuntu 20.04 server due to vestacp problems and no kind of support for why my add on domains would not work but yet the main admin one would. still baffels me, but i’m a glutten for punishment so thought i would try it out on ubuntu 20.04.
any way thanks for the excellent info and help the enternet needs more like you. Thanks for sharing this information.
Here is a question I have a website(example.com) already running in /var/www/html
can i add another website (newdomain.com) by creating directory /var/www/newdomain.com and use it. Without changing the location of example.com as you know it will take time to transfer from /var/www/html to /var/www/example.com Yes, i’m using Apache Web Server on Ubuntu 20.04 (LTS) x64 Now it’s easy, you can use easy-apache to set up everything for you, all you have to do is copy-paste below lines into your terminal, and enter your domain name when asked, it will also install SSL if you want A very nice piece of Information. Nicely written. Thanks a lot. I was wondering for basic apache server setup. I will remember your name as my teacher. GBY. how do I make my site visible to any other computer? Issue: Error AH00558: Could not reliably determine the server’s fully qualified domain name Solution:
Add a line containing ServerName 127.0.0.1 to the end of the file: ========================================================= Issue: can access the website via IP but not Domain
Solution: Worked great Thank you for the walkthrough!!! Do we need to add /public_html to the directory if we want to add more than one virtual host site? If I add one using the above method it works fine but if I add a second one the second one won’t show up. Just a comment, that could help people. When following your tutorial after doing the configtest of apache I found ERROR AH00558. Since I was starting from scratch from a Desktop 20.04 Ubuntu distribution, I assume that it will happen to anybody doing the same thing. The fix is easy, just add to your tutorial that if they find this error all they need to do is to add this line to their /etc/apache2/apache2.conf file using sudo nano /etc/apache2/apache2.conf, going to the end of the file and adding it, then <Ctrl>S, followed by <Ctrl>X This is one of the best-written tutorials I’ve ever followed. Thanks, Erin! Please complete your information! Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation. Full documentation for every DigitalOcean product. The Wave has everything you need to know about building a business, from raising funding to marketing your product. Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter. New accounts only. By submitting your email you agree to our Privacy Policy Scale up as you grow — whether you're running one virtual machine or ten thousand. Sign up and get $200 in credit for your first 60 days with DigitalOcean.* *This promotional offer applies to new accounts only.