2026年11月12日

2026年11月12日

Install Apache on CentOS/RHEL (Rocky Linux and AlmaLinux 9/10)

This article is a localized edition of the Japanese original. Read the Japanese original

This guide shows how to install Apache HTTP Server (package name httpd) on CentOS and RHEL-family Linux, updated for the operating systems current as of October 2026. The old yum steps for CentOS 7 work in much the same way, but that OS is no longer supported, so use one of the current distributions below for any new build.

CentOS support status and what this guide covers

OS Status (as of October 2026)
CentOS Linux 7 End of life on June 30, 2024. No more updates, so don't use it for new builds
CentOS Linux 8 End of life on December 31, 2021
CentOS Stream 9 Until May 31, 2027 (aligned with the end of RHEL 9 full support)
CentOS Stream 10 Until May 31, 2030 (aligned with the end of RHEL 10 full support)

Common successors to CentOS Linux are RHEL (Red Hat Enterprise Linux) itself and the RHEL-compatible Rocky Linux and AlmaLinux. The commands below are the same on RHEL 9 / 10 and their compatible distributions. If you still have CentOS 7 servers, plan the OS migration before worrying about Apache settings.

Step 1: Install and start httpd

# Update packages, then install httpd and mod_ssl (for HTTPS)
sudo dnf -y update
sudo dnf -y install httpd mod_ssl

# Start it now and enable it at boot in one step
sudo systemctl enable --now httpd

# Check status and version (RHEL 9 ships Apache 2.4.x)
systemctl status httpd --no-pager
httpd -v

If systemctl status shows active (running), it's running. If it fails to start, check why with this command.

sudo journalctl -u httpd --no-pager -n 50

Step 2: Open HTTP and HTTPS in firewalld

A web server can't serve the public unless ports 80 (HTTP) and 443 (HTTPS) are reachable from outside. Open both in firewalld, the standard firewall on RHEL-family systems.

sudo firewall-cmd --permanent --zone=public --add-service=http
sudo firewall-cmd --permanent --zone=public --add-service=https
sudo firewall-cmd --reload

# Check which services are open
sudo firewall-cmd --zone=public --list-services

Without --permanent, the rules disappear when firewalld reloads or the OS restarts. On cloud servers, you also need to allow 80/443 in the cloud provider's security group or packet filter, separately from the OS firewall.

What you should restrict is not the public ports 80/443 but administrative entry points such as SSH (port 22) and admin panels.

Step 3: Check that it responds

At this point there's nothing to publish yet, so Apache's default page is shown. On RHEL-family systems, conf.d/welcome.conf serves that default page with status code 403.

# The default page is returned with status 403
curl -I http://localhost/

# Placing a test file makes it return 200
echo 'It works' | sudo tee /var/www/html/index.html
curl -I http://localhost/

If you see the same content when you open http://your-server-ip/ in a browser on another computer, the firewall is letting traffic through too.

Step 4: Know where the configuration files are

Location Contents
/etc/httpd/conf/httpd.conf Main configuration file
/etc/httpd/conf.d/*.conf Additional settings (loaded via IncludeOptional). Put per-site settings here
/etc/httpd/conf.modules.d/*.conf Which modules are loaded
/etc/httpd/conf.d/ssl.conf HTTPS settings created when you install mod_ssl
/var/www/html Default document root
/var/log/httpd/ access_log and error_log

Adding your own .conf files in conf.d/ is easier than editing httpd.conf directly, because package updates are simpler to handle.

Step 5: Create a virtual host (example for hosting WordPress)

To keep settings separate per domain, create a virtual host file in conf.d/.

# /etc/httpd/conf.d/example.com.conf
<VirtualHost *:80>
    ServerName example.com
    ServerAlias www.example.com
    DocumentRoot /var/www/example.com/public

    <Directory /var/www/example.com/public>
        # Enable .htaccess for WordPress permalinks
        AllowOverride All
        Require all granted
    </Directory>

    ErrorLog /var/log/httpd/example.com-error.log
    CustomLog /var/log/httpd/example.com-access.log combined
</VirtualHost>
sudo mkdir -p /var/www/example.com/public

# Check syntax before applying (you want to see Syntax OK)
sudo apachectl configtest
sudo systemctl reload httpd

SELinux settings

SELinux is enabled by default on RHEL-family systems. Directories created under /var/www/ inherit the web content label (httpd_sys_content_t), but that label doesn't let Apache write files. Give wp-content, where WordPress writes files during uploads and updates, a writable label.

# Install policycoreutils-python-utils if semanage is missing
sudo dnf -y install policycoreutils-python-utils

sudo semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/example.com/public/wp-content(/.*)?"
sudo restorecon -Rv /var/www/example.com

# Check the label
ls -Zd /var/www/example.com/public/wp-content

Don't work around problems by disabling SELinux. You can review denials with sudo ausearch -m avc -ts recent.

Installing PHP (PHP-FPM) and enabling HTTPS with Let's Encrypt are covered in the related articles.

Step 6: Check server activity with server-status

http://localhost/server-status doesn't appear (it returns 404) until you add mod_status settings. On RHEL-family systems the mod_status module itself is already loaded, so you only need to define where it's shown and who can see it.

# /etc/httpd/conf.d/server-status.conf
<Location "/server-status">
    SetHandler server-status
    # Allow access only from the server itself
    Require local
</Location>
sudo apachectl configtest
sudo systemctl reload httpd

# Compact machine-readable output
curl "http://localhost/server-status?auto"

server-status shows connected clients and requested URLs, so restrict who can see it, as Require local does, and don't expose it publicly.

Step 7: Basic settings for running it

To reveal less version information, add the following file.

# /etc/httpd/conf.d/security.conf
# Limit the Server header to just "Apache"
ServerTokens Prod
# Don't show the version at the bottom of error pages
ServerSignature Off
sudo apachectl configtest
sudo systemctl reload httpd

# Ongoing updates (httpd is updated as an OS package too)
sudo dnf -y upgrade

Install Apache from OS packages and update it with dnf rather than building from source. If you build from source, you have to track security fixes yourself.

Cautions

  • After changing settings, run apachectl configtest before applying them. Restarting with a syntax error leaves Apache stopped and takes the whole site down.
  • systemctl restart drops in-progress connections. To apply configuration changes, use systemctl reload.
  • Logs are rotated regularly by logrotate (configured in /etc/logrotate.d/httpd, installed by the package). Monitor disk space on busy sites.

Summary

  • CentOS Linux 7 and 8 are end of life. Use RHEL 9 / 10, Rocky Linux, AlmaLinux or similar for new builds
  • dnf install httpd mod_ssl → systemctl enable --now httpd → open http / https in firewalld with --permanent
  • Put site settings in conf.d/, check them with apachectl configtest, then reload
  • Give WordPress's wp-content the SELinux label httpd_sys_rw_content_t
  • Enable server-status with SetHandler server-status and Require local

Related articles:

Questions about WordPress? The publisher of this site is based in Japan and replies in Japanese. Contact (Japanese)

お気軽にご相談ください

お見積りへ お問い合わせへ
▲