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 configtestbefore applying them. Restarting with a syntax error leaves Apache stopped and takes the whole site down. systemctl restartdrops in-progress connections. To apply configuration changes, usesystemctl 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 withapachectl configtest, thenreload - Give WordPress's
wp-contentthe SELinux labelhttpd_sys_rw_content_t - Enable server-status with
SetHandler server-statusandRequire local
Related articles:
- Checking Apache configuration syntax
- Setting up Apache virtual hosts
- Configuring Apache with PHP-FPM
- Setting up an SSL certificate on Apache with Certbot
- Monitoring Apache with mod_status
Questions about WordPress? The publisher of this site is based in Japan and replies in Japanese. Contact (Japanese)