Installing WordPress directly on a current dnf-based server is the right approach when the host needs a standard Apache virtual host, a local database, and a deployment layout that matches upstream WordPress rather than a distro-maintained wrapper package. That keeps the files, upgrades, and troubleshooting path predictable across Fedora, CentOS Stream, and Red Hat-style systems.

On these systems, Apache serves the site, PHP-FPM handles PHP requests over a local Unix socket, and MariaDB stores the WordPress data. The default php.conf on current Fedora-family installs already points Apache at /run/php-fpm/www.sock when mod_php is not enabled, so the service layer matters as much as the virtual host and wp-config.php file.

Examples target current Fedora, CentOS Stream, and Red Hat Enterprise Linux style hosts that use dnf, httpd, and php-fpm. Older legacy yum flows and retired CentOS releases are not covered here, and systems with enforcing SELinux often need an explicit writable label on WordPress upload paths before media uploads and plugin-installed assets work reliably.

Steps to install WordPress on CentOS, Fedora, or Red Hat with Apache, MariaDB, and PHP-FPM:

  1. Install Apache, MariaDB, PHP-FPM, and the common WordPress PHP extensions.
    $ sudo dnf install -y httpd mariadb-server php php-fpm php-mysqlnd php-xml php-curl php-zip php-gd php-intl php-mbstring tar curl rsync
  2. Enable and start the Apache, MariaDB, and PHP-FPM services.
    $ sudo systemctl enable --now httpd mariadb php-fpm
    $ systemctl is-active httpd mariadb php-fpm
    active
    active
    active

    Current Fedora-family php.conf uses PHP-FPM by default when mod_php is not enabled, so leaving php-fpm stopped usually turns every .php request into a backend or 503 error.

  3. Open the local MariaDB shell and create a dedicated database and database user for WordPress.
    $ sudo mariadb
    MariaDB [(none)]> CREATE DATABASE wordpress CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
    MariaDB [(none)]> CREATE USER 'wordpress'@'localhost' IDENTIFIED BY 'strong_password_here';
    MariaDB [(none)]> GRANT ALL PRIVILEGES ON wordpress.* TO 'wordpress'@'localhost';
    MariaDB [(none)]> FLUSH PRIVILEGES;
    MariaDB [(none)]> EXIT;

    Replace strong_password_here with a unique password that is not reused for any other account on the server.

  4. Create a dedicated document root for the site.
    $ sudo mkdir -p /var/www/example.com/public_html
  5. Download the current WordPress tarball to a temporary directory and extract it.
    $ cd /tmp
    $ curl -LO https://wordpress.org/latest.tar.gz
    $ tar -xzf latest.tar.gz
  6. Copy the extracted WordPress files into the site document root.
    $ sudo rsync -a /tmp/wordpress/ /var/www/example.com/public_html/
  7. Create wp-config.php from the sample file and add the database connection values.
    $ sudo cp /var/www/example.com/public_html/wp-config-sample.php /var/www/example.com/public_html/wp-config.php
    $ sudo vi /var/www/example.com/public_html/wp-config.php
    define( 'DB_NAME', 'wordpress' );
    define( 'DB_USER', 'wordpress' );
    define( 'DB_PASSWORD', 'strong_password_here' );
    define( 'DB_HOST', 'localhost' );
  8. Replace the placeholder authentication keys and salts in wp-config.php with fresh values from the official WordPress API.
    $ curl -s https://api.wordpress.org/secret-key/1.1/salt/

    Paste the returned define(… ) lines over the default salt block before saving the configuration file.

  9. Set ownership and permissions so Apache and PHP-FPM can read the site tree safely.
    $ sudo chown -R apache:apache /var/www/example.com/public_html
    $ sudo find /var/www/example.com/public_html -type d -exec chmod 755 {} \\;
    $ sudo find /var/www/example.com/public_html -type f -exec chmod 644 {} \\;
    $ sudo chmod 640 /var/www/example.com/public_html/wp-config.php
  10. Create the upload directory and persist an SELinux write label for it when the host runs in enforcing mode.
    $ sudo mkdir -p /var/www/example.com/public_html/wp-content/uploads
    $ getenforce
    Enforcing
    
    $ sudo dnf install -y policycoreutils-python-utils
    $ sudo semanage fcontext -a -t httpd_sys_rw_content_t '/var/www/example.com/public_html/wp-content/uploads(/.*)?'
    $ sudo restorecon -Rv /var/www/example.com/public_html/wp-content/uploads

    Skip the labeling commands when getenforce returns Permissive or Disabled.

    Without a writable SELinux context, the installer can succeed while media uploads later fail with unexplained permission errors.

  11. Create an Apache virtual host for the site.
    $ sudo vi /etc/httpd/conf.d/example.com.conf
    <VirtualHost *:80>
        ServerName example.com
        ServerAlias www.example.com
        DocumentRoot /var/www/example.com/public_html
    
        <Directory /var/www/example.com/public_html>
            AllowOverride All
            Require all granted
            DirectoryIndex index.php
        </Directory>
    
        ErrorLog /var/log/httpd/example.com-error.log
        CustomLog /var/log/httpd/example.com-access.log combined
    </VirtualHost>

    Replace the example hostnames with the real DNS names for the site before reloading Apache.

  12. Test the Apache configuration and reload the service after the syntax check passes.
    $ sudo httpd -t
    Syntax OK
    $ sudo systemctl reload httpd
  13. Verify that the installer endpoint responds before completing the browser-based setup.
    $ curl -I http://www.example.com/wp-admin/install.php
    HTTP/1.1 200 OK
    ##### snipped #####

    If this request returns a permission or backend error, re-check file ownership, the php-fpm service state, and the SELinux label on wp-content/uploads.

  14. Open http://www.example.com/wp-admin/install.php// in a browser and finish the initial WordPress setup by creating the site title, administrator account, and password.

    After the installer finishes, continue with HTTPS and post-install hardening from the related pages.