How to Install Apache HTTPD on CentOS Stream

Apache HTTP Server (httpd) powers websites from personal blogs to enterprise applications. This guide walks you through installing Apache on CentOS Stream, configuring virtual hosts for multiple domains, securing traffic with Let’s Encrypt SSL certificates, and applying SELinux policies for production use. You will configure firewall rules, set up automatic certificate renewal, and verify each step with hands-on commands.

This guide covers CentOS Stream 9 and CentOS Stream 10. All commands work identically on both versions unless otherwise noted. CentOS Stream 8 reached end-of-life in May 2024 and is no longer supported.

Update CentOS Stream Before Installation

Before proceeding with the Apache installation on your CentOS Stream machine, we must verify that our system is fully up-to-date. This is more than just a precautionary measure. Updating your system helps prevent compatibility issues and significantly enhances its stability, security, and performance.

Run the following command to update all packages:

sudo dnf upgrade --refresh

Specifically, this command refreshes the package metadata and installs the latest updates and security patches. Wait for the update to complete before proceeding with the Apache installation.

Install Apache HTTPD via DNF Command

Next, the second step is to install Apache, or HTTPD, on your CentOS Stream system. This is a straightforward process, courtesy of the powerful DNF package manager. The DNF, or Dandified Yum, package manager simplifies installing, updating, and managing software packages.

To begin the installation of Apache (HTTPD), run the following command in your terminal:

sudo dnf install httpd

After installation completes, verify Apache is installed correctly by checking the version:

httpd -v
Server version: Apache/2.4.62 (CentOS Stream)
Server built:   Nov  6 2025 00:00:00

CentOS Stream 10 ships Apache 2.4.63, while CentOS Stream 9 includes Apache 2.4.62. Both versions support the same configuration syntax shown in this guide.

Enable Apache HTTPD at Boot

Once you have installed Apache, enable the service to start automatically at boot. This ensures your web server is available immediately after system restarts.

If the Apache (HTTPD) service is not active or set to run by default, use these commands in your terminal to start the service and ensure it runs on system boot:

sudo systemctl start httpd
sudo systemctl enable httpd

For instance, the first command, sudo systemctl start httpd, starts the Apache (HTTPD) service immediately, whereas the second command, sudo systemctl enable httpd, configures the service to start automatically upon system boot. By running these two commands, you ensure that Apache (HTTPD) remains accessible and ready to serve web requests whenever your system starts.

As an alternative, you can condense the two previous steps into one single command:

sudo systemctl enable httpd --now

The –now option in the command sudo systemctl enable httpd –now simultaneously starts the Apache (HTTPD) service and configures it to launch on the system boot automatically. This single command unifies the two separate commands from the previous steps, making the process more streamlined and efficient.

Verify Apache HTTPD Service Status

Finally, we should verify the successful implementation and functioning of Apache (HTTPD) by utilizing the following systemctl command:

systemctl status httpd

This command displays the real-time status of the Apache (HTTPD) service, including any errors or messages. If properly configured, you should see output indicating the service is active and running:

● httpd.service - The Apache HTTP Server
     Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; preset: disabled)
     Active: active (running) since ...
   Main PID: 1234 (httpd)
     Status: "Total requests: 0; Idle/Busy workers 100/0;..."
      Tasks: 213 (limit: 22775)
     Memory: 25.0M
        CPU: 100ms
     CGroup: /system.slice/httpd.service

Typically, if the output shows “active (running)” in green, your Apache server is functioning correctly and ready to serve requests.

Configure FirewallD Rules

Following the installation of Apache (HTTPD) on CentOS Stream, you must configure firewall rules to allow HTTP and HTTPS traffic on ports 80 and 443 respectively.

If firewall-cmd is not installed on your system (common in minimal installations), install it first with sudo dnf install firewalld and enable it with sudo systemctl enable firewalld --now.

Configure the firewall rules using the firewall-cmd tool, CentOS Stream’s default firewall management utility. The following steps cover the essential port configurations for your web server.

Opening Ports 80 and 443

Open ports 80 and 443 for HTTP and HTTPS traffic. The --permanent flag ensures rules persist after reboot:

sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https

Each command returns success when completed. Using service names (http, https) instead of port numbers makes firewall rules self-documenting.

Reload the firewall to apply the changes:

sudo firewall-cmd --reload

Verify the services are enabled:

sudo firewall-cmd --list-services
cockpit dhcpv6-client http https ssh

Firewall Security Considerations

Opening only the required ports minimizes your attack surface. For production servers, consider additional hardening such as rate limiting and fail2ban to protect against brute-force attacks.

SELinux Note: CentOS Stream enables SELinux by default. If Apache needs to make outbound network connections (e.g., for reverse proxy), run sudo setsebool -P httpd_can_network_connect on. For content in non-standard directories, set the context permanently: sudo semanage fcontext -a -t httpd_sys_content_t "/path/to/content(/.*)?" followed by sudo restorecon -Rv /path/to/content.

Verifying Apache HTTPD Access

Verify Apache is running by opening a web browser and navigating to your server’s address:

http://your_server_ip

Or use localhost if testing locally:

http://localhost

If Apache is configured correctly, you will see the default CentOS Stream HTTP server test page:

Create and Configure a Virtual Host

Virtual hosts allow Apache to serve multiple domains from a single server. Each virtual host has independent configuration for document root, logging, and SSL certificates. This section demonstrates creating a virtual host for example.com—replace this with your actual domain throughout the examples.

Creating and Configuring Directories

Create a directory to store your website files. The directory name typically matches your domain:

sudo mkdir /var/www/example.com

Set appropriate permissions. Keep root ownership and use 755 for directories and 644 for files:

sudo chmod 755 /var/www/example.com

Keep root ownership (root:root) for security. Apache can read files owned by root as long as permissions are set correctly. Only use apache:apache ownership for directories that need write access, such as upload folders or cache directories.

Creating an index.html File

Create a test page to verify your virtual host configuration:

sudo nano /var/www/example.com/index.html

Add the following HTML content:

<html>
  <head>
    <title>Example Domain</title>
  </head>
  <body>
    <h1>Welcome to Example Domain</h1>
    <p>This is a sample page for the domain example.com.</p>
  </body>
</html>

Upon finalizing the content of your index.html file, save the file and exit the text editor. In nano, press Ctrl+O to save, then Ctrl+X to exit.

CentOS Stream Apache uses /etc/httpd/conf.d/ for configuration files by default. This directory contains essential configs like ssl.conf and module settings. Keep the default IncludeOptional conf.d/*.conf directive enabled to avoid breaking SSL and other packaged configurations.

Create the Virtual Host Configuration File

Create a virtual host configuration file in /etc/httpd/conf.d/:

sudo nano /etc/httpd/conf.d/example.com.conf

Add the following configuration, replacing example.com with your domain:

<VirtualHost *:80>
    ServerName example.com
    ServerAlias www.example.com
    DocumentRoot /var/www/example.com

    ErrorLog /var/log/httpd/example.com-error.log
    CustomLog /var/log/httpd/example.com-access.log combined

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

This configuration includes logging directives, directory permissions, and disables directory listing for security.

Test the configuration for syntax errors before restarting Apache:

sudo apachectl configtest
Syntax OK

If the test passes, the configuration is valid. If errors appear, the output shows the file and line number to fix.

Restart Apache to Load the Virtual Host

Restart Apache to apply the virtual host configuration:

sudo systemctl restart httpd

Open a browser and navigate to http://example.com (or your server’s IP address if testing locally). You should see the test page created earlier.

Additional Commands & Tips

Secure Directories and Files

Setting Secure Permissions

Set secure permissions to prevent unauthorized access. Use 755 for directories and 644 for files:

sudo find /var/www/example.com -type d -exec chmod 755 "{}" \;
sudo find /var/www/example.com -type f -exec chmod 644 "{}" \;

Verify permissions are set correctly:

ls -la /var/www/example.com
total 12
drwxr-xr-x 2 root root 4096 Dec 12 10:00 .
drwxr-xr-x 3 root root 4096 Dec 12 10:00 ..
-rw-r--r-- 1 root root  245 Dec 12 10:00 index.html

Keep files owned by root. Apache can read root-owned files with 644 permissions. Only change ownership to apache:apache for directories that require write access, such as upload folders or application cache directories.

Secure Apache with Let’s Encrypt SSL

Install Certbot and the Apache Plugin

Securing your Apache server with an SSL certificate encrypts traffic between your server and visitors. Let’s Encrypt provides free, automated SSL certificates through the Certbot tool. First, enable the CRB repository and install EPEL, which provides Certbot packages.

Install the DNF configuration manager plugin:

sudo dnf install -y dnf-plugins-core

Enable the CRB (CodeReady Builder) repository:

sudo dnf config-manager --set-enabled crb

Verify CRB is enabled:

dnf repolist | grep crb
crb                           CentOS Stream 9 - CRB

Next, install the EPEL repository. For a detailed guide on EPEL configuration, see our EPEL installation guide for CentOS Stream:

sudo dnf install epel-release -y

With EPEL enabled, install mod_ssl (the Apache SSL module) and Certbot with the Apache plugin:

sudo dnf install mod_ssl certbot python3-certbot-apache -y

Verify Certbot installed correctly by checking the version:

certbot --version
certbot 3.x.x

Run Certbot for Apache

Run the following command in your terminal to generate your SSL certificate using Certbot.

sudo certbot --dry-run --apache --agree-tos --redirect --hsts --staple-ocsp --email you@example.com -d www.example.com

For those new to Let’s Encrypt, you may seek more information on the abbreviation in the command.

  • The “–dry-run” option lets you execute a test run of the certificate generation process without altering the system. This option is valuable for testing.
  • The “–apache” option is to generate a certificate for an Apache web server.
  • The “–agree-tos” option allows you to accept the terms of service from Let’s Encrypt, the certificate authority that provides the SSL certificate.
  • The “–redirect” option automatically redirects all HTTP traffic to HTTPS.
  • The “–hsts” option enables HTTP Strict Transport Security (HSTS). This security feature helps protect against protocol downgrade attacks and cookie hijacking by telling browsers only to access your website over a secure HTTPS connection.
  • The “–staple-ocsp” option enables Online Certificate Status Protocol (OCSP) stapling, which verifies an SSL certificate’s revocation status without contacting the certificate authority.
  • Use the “–email” option to specify the email address you want to associate with the certificate.
  • The “-d” option specifies the domain name for which you will generate the certificate. In this example, the domain name is “www.example.com.”

Alternatively, you can use the following command and follow the step-by-step prompts for a more accessible experience.

sudo certbot certonly --apache

After testing with --dry-run, issue the actual certificate. Include both the apex domain and www subdomain:

sudo certbot --apache --agree-tos --redirect --hsts --staple-ocsp --email you@example.com -d example.com -d www.example.com

Replace you@example.com with your email address and example.com with your domain. Certbot automatically configures Apache to use the certificate and creates renewal hooks.

Certbot automatically creates and manages the SSL configuration in /etc/httpd/conf.d/example.com-le-ssl.conf. Do not manually edit /etc/httpd/conf.d/ssl.conf or add certificate paths—Certbot handles all SSL directives during certificate issuance.

Automating Certificate Renewal

To keep the SSL certificate up-to-date, set up a cron job for automatic renewal. Test the renewal process with a dry run:

sudo certbot renew --dry-run

Certbot from EPEL automatically creates a systemd timer to check and renew certificates. Verify the timer is active:

systemctl list-timers certbot*

You should see the certbot-renew.timer scheduled to run periodically. This timer automatically checks your certificates and renews them before expiration. You can also view all system timers with:

systemctl list-timers --all

Apache HTTPD Management

With Apache successfully set up on your server, here are some essential points to remember for effective management.

View Apache Server Logs

Generally, Apache server logs are stored in the directory at /var/log/httpd/. The default filenames for the access and error logs are access.log and error.log, respectively. However, changing these names in the virtual host configuration file is possible.

Here’s an example of changing the Apache server logs in the virtual host configuration file.

<VirtualHost *:80>
    ServerName www.example.com
    DocumentRoot /var/www/example.com
    
    # Change access log to custom-access.log
    CustomLog /var/log/httpd/custom-access.log combined
    
    # Change error log to custom-error.log
    ErrorLog /var/log/httpd/custom-error.log
</VirtualHost>

In this case, this example changes the access and error logs to custom-access.log and custom-error.log, respectively. You can change the names of the log files to whatever you prefer and update the corresponding path in the virtual host configuration file.

Common Apache Commands

Here are some of the frequently used commands when managing Apache:

Stop Apache webserver:

sudo systemctl stop httpd

Start Apache webserver:

sudo systemctl start httpd

Restart Apache webserver:

sudo systemctl restart httpd

Reload Apache webserver:

sudo systemctl reload httpd

Disable Apache on server boot:

sudo systemctl disable httpd

Enable Apache on server boot:

sudo systemctl enable httpd

Update Apache HTTPD

To keep Apache updated, run the command you typically use to check if your system is up to date.

sudo dnf update --refresh

However, it’s important to make backups or create images of your system before performing any upgrades, as bugs can sometimes occur. The following command will refresh all system packages, including Apache, and prompt you to upgrade.

Remove Apache HTTPD

To uninstall Apache from your system, use the following command.

sudo systemctl disable httpd --now

Now, use the following command to remove Apache altogether.

sudo dnf remove httpd

Warning: The following command permanently deletes all Apache configuration files, virtual host configurations, and SSL certificates stored in /etc/httpd/. Back up any configurations you want to keep before proceeding.

Remove the Apache configuration directory:

sudo rm -rf /etc/httpd/

Finally, remove any orphaned dependencies that were installed with Apache:

sudo dnf autoremove

Verify Apache has been removed:

rpm -q httpd
package httpd is not installed

Troubleshoot Apache HTTPD

If Apache fails to start or serve content, check these common issues.

Configuration Syntax Errors

Test Apache configuration before restarting the service:

sudo apachectl configtest
Syntax OK

If errors appear, the output shows the file and line number containing the problem.

Port 80 Already in Use

If Apache fails to start with “Address already in use”, check what process is using port 80:

sudo ss -tlnp | grep :80
LISTEN 0      511                *:80              *:*    users:(("httpd",pid=1234,fd=4))

The output shows which process (and PID) is listening on port 80. Stop the conflicting service or configure Apache to use a different port.

SELinux Denials

Check for SELinux denials in the audit log:

sudo ausearch -m avc -ts recent | grep httpd

If denials appear, the output shows the blocked action. Common fixes include enabling httpd_can_network_connect for reverse proxy setups (sudo setsebool -P httpd_can_network_connect on) and labeling custom document roots with semanage fcontext followed by restorecon.

Permission Denied on Document Root

Ensure Apache can read your document root:

sudo namei -l /var/www/example.com
f: /var/www/example.com
drwxr-xr-x root root /
drwxr-xr-x root root var
drwxr-xr-x root root www
drwxr-xr-x root root example.com

Every directory in the path must have execute permission (755). If any directory shows drwx------ or lacks the x bit for others, Apache cannot traverse the path. Fix with chmod 755 on the restricted directory.

Conclusion

With Apache HTTP Server and Let’s Encrypt SSL certificates deployed on your CentOS Stream system, your web server is ready for production use. The EPEL-based Certbot installation handles automatic certificate renewals, and systemd ensures Apache starts with your server. To extend this setup into a full LAMP stack, continue with our guide to install PHP on CentOS Stream.

Leave a Comment