Installing WordPress directly on Ubuntu with Apache and MariaDB is the clean route when the server needs a normal virtual host, predictable file ownership, and an upstream WordPress layout that does not depend on distro repackaging. That keeps upgrades, troubleshooting, and later hardening work aligned with the structure that current WordPress releases expect.
On Ubuntu, Apache serves the site, PHP runs inside the web server through mod_php, and MariaDB stores posts, users, settings, and plugin data. The wp-config.php file joins the web root to the database credentials, while AllowOverride All and mod_rewrite let WordPress manage the .htaccess rules behind clean permalinks.
Examples use a dedicated document root under /var/www, an empty database, and current Ubuntu packages instead of a bundled control-panel stack. The browser installer should be opened only after DNS or a local host mapping points the target hostname at the server, because the most common first-run failures are wrong database credentials, a virtual-host mismatch, or leftover WordPress tables in a reused database.
Steps to install WordPress on Ubuntu with Apache and MariaDB:
- Update the package index and install Apache, MariaDB, PHP, and the common WordPress PHP extensions.
$ sudo apt-get update $ sudo apt-get install --yes apache2 mariadb-server php libapache2-mod-php php-mysql php-xml php-curl php-zip php-gd php-intl php-mbstring ca-certificates curl unzip rsync Reading package lists... Done Building dependency tree... Done ##### snipped #####
- Enable the Apache and MariaDB services so they start now and on future boots.
$ sudo systemctl enable --now apache2 mariadb $ systemctl is-active apache2 mariadb active active
The default unit names on Ubuntu are apache2 and mariadb.
- 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;
Ubuntu commonly authenticates the local MariaDB root account through the Unix socket, so sudo mariadb is usually the correct entry point.
Replace strong_password_here with a unique password that is not reused for any other service account.
- Create a dedicated document root for the site.
$ sudo mkdir -p /var/www/example.com/public_html
- Download the current WordPress tarball into a temporary working directory and extract it.
$ cd /tmp $ curl -fsSLO https://wordpress.org/latest.tar.gz $ tar -xzf latest.tar.gz
- Copy the extracted WordPress files into the site document root.
$ sudo rsync -a /tmp/wordpress/ /var/www/example.com/public_html/
The trailing slashes copy the contents of the extracted wordpress directory into the document root instead of nesting another wordpress directory below it.
- 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' );
Keep DB_HOST as localhost when MariaDB runs on the same host.
- Fetch a fresh set of authentication keys and salts from the official WordPress API and replace the placeholder block in wp-config.php.
$ curl -s https://api.wordpress.org/secret-key/1.1/salt/
Paste the returned define(… ) lines over the default authentication-key section before saving the file.
- Set ownership and file permissions so Apache can read and update the site safely.
$ sudo chown -R www-data:www-data /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.phpThis 755/644 pattern keeps the tree readable without leaving the site world-writable.
- Create an Apache virtual host for the site.
$ sudo vi /etc/apache2/sites-available/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 ${APACHE_LOG_DIR}/example.com-error.log CustomLog ${APACHE_LOG_DIR}/example.com-access.log combined </VirtualHost>Replace example.com and www.example.com with the real hostname for the site before enabling the virtual host.
- Enable mod_rewrite and the new virtual host, disable the default site, and test the Apache configuration.
$ sudo a2enmod rewrite $ sudo a2ensite example.com.conf $ sudo a2dissite 000-default.conf $ sudo apache2ctl configtest Syntax OK
WordPress permalinks depend on mod_rewrite when Apache is serving the site directly.
Related: How to enable or disable Apache modules
Related: How to test Apache configuration - Reload Apache so the new virtual host becomes active.
$ sudo systemctl reload apache2
- Verify that the installer endpoint responds before opening it in a browser.
$ curl -I http://www.example.com/wp-admin/install.php HTTP/1.1 200 OK ##### snipped #####
If this check fails on a local-only build, confirm that the hostname resolves to the server in /etc/hosts before troubleshooting Apache or PHP.
- Open http://www.example.com/wp-admin/install.php in a browser and complete the initial site title, administrator account, and password setup.
If the page reports Already Installed instead of showing the first-run form, the target database already contains WordPress tables. Use an empty database or remove the old tables before retrying.
Mohd Shakir Zakaria is a cloud architect with deep roots in software development and open-source advocacy. Certified in AWS, Red Hat, VMware, ITIL, and Linux, he specializes in designing and managing robust cloud and on-premises infrastructures.
