Set Up MariaDB (MySQL) on Fedora

Installing MariaDB on Fedora takes only a few DNF commands and a quick security setup to get a production-ready MySQL-compatible database running natively.

Set Up MariaDB (MySQL) on Fedora

You installed a web application that expects a database, and the setup script failed with Access denied for user 'root'@'localhost'. Or you migrated from a tutorial that used MySQL, only to find mysql-server isn't in the Fedora repositories. Fedora ships MariaDB as the default drop-in replacement. The commands look familiar, but the service names, configuration hierarchy, and security defaults differ enough to trip you up if you follow a generic guide blindly.

What MariaDB is on Fedora

MariaDB is a fork of MySQL created by the original developers after Oracle acquired MySQL. On Fedora, it is the canonical relational database. The wire protocol is compatible, so your application connects using the same driver and the same connection string. The difference is under the hood. MariaDB uses its own package names, systemd units, and configuration paths. Fedora packages it with SELinux contexts baked in and systemd integration that handles socket activation and resource limits automatically.

Think of MariaDB as the Fedora-native evolution of MySQL. You get the same SQL syntax and client tools, but the backend is maintained by the community and integrated tightly with the operating system. You are not installing MySQL. You are installing MariaDB, and you need to use the MariaDB commands to manage it.

Install the server package. The client is useless without the daemon.

Install and start the service

Install the server and client packages. The client is often pulled in as a dependency, but installing it explicitly ensures you have the command-line tools for management. Fedora's package manager resolves all dependencies automatically.

sudo dnf install mariadb-server mariadb # WHY: mariadb-server provides the daemon, systemd unit, and default configuration. mariadb provides the command-line client for administration.

Start the service and enable it for boot. The --now flag starts the service immediately and enables it for future boots in a single transaction. This is the standard pattern for any new service.

sudo systemctl enable --now mariadb # WHY: Enable the service for boot and start it immediately. The daemon binds to the socket and initializes the data directory.

Verify the service is running. Always check the status before proceeding. The status output shows the active state and the last few log lines, which helps you spot startup errors early.

systemctl status mariadb # WHY: Confirm the service is active and check recent logs for warnings or errors. Look for "Active: active (running)" in the output.

Run journalctl -xeu mariadb if the service fails to start. The -x flag adds explanatory text and the -e flag jumps to the end of the journal. Most sysadmins type this muscle-memory style when debugging units.

Secure the installation

A fresh MariaDB install has a blank root password and allows anonymous access. Run the security wizard immediately. This script walks you through setting a root password, removing anonymous users, and disabling remote root login.

sudo mariadb-secure-installation # WHY: Interactive script to harden the database. It sets the root password, removes anonymous users, removes the test database, and reloads privileges.

The script prompts you for several decisions. Set a strong root password. Remove anonymous users to prevent anyone from logging in without a user account. Remove the test database, which is open to all users by default. Reload the privilege tables to apply changes.

If you skip this step, your database is exposed to local and potentially remote attacks. The root password you set here is for administrative access only. Applications should never use the root account.

Run the secure installation script. A default install is an open door.

Create a database and user

Connect as root to create a database and a dedicated user. The -p flag prompts for the password you set during the security wizard. Never use the root account for your application. Create a user with limited privileges scoped to the specific database.

sudo mariadb -u root -p # WHY: Connect as root to perform administrative tasks. The -p flag prompts for the password securely.

Inside the MariaDB shell, create the database and user. Use utf8mb4 for full Unicode support, including emojis. Scope the user to localhost to prevent remote login unless explicitly required.

CREATE DATABASE myapp CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; # WHY: utf8mb4 supports the full Unicode range. utf8mb4_unicode_ci is the standard collation for general purpose data.
CREATE USER 'myuser'@'localhost' IDENTIFIED BY 'strongpassword'; # WHY: Create a dedicated user scoped to localhost. Applications should never run as the database root.
GRANT ALL PRIVILEGES ON myapp.* TO 'myuser'@'localhost'; # WHY: Grant permissions only on the specific database. Avoid GRANT ALL ON *.* unless absolutely necessary.
FLUSH PRIVILEGES; # WHY: Reload the grant tables to apply changes immediately without restarting the server.
EXIT; # WHY: Close the administrative session.

Test the application user. Root works on a fresh install; the app user tells you if permissions are actually correct.

sudo mariadb -u myuser -p -e "SELECT 1;" # WHY: Verify the application user can connect and execute a query. Replace SELECT 1 with a simple test if needed.

Configure remote access

By default, MariaDB listens only on localhost. To allow remote connections, you must change the bind address and open the firewall. Fedora's configuration hierarchy uses drop-in files. Edit files in /etc/my.cnf.d/. Never edit files in /usr/lib/, as they ship with the package and get overwritten on updates.

Create or edit the server configuration file. Add the bind-address directive to listen on all interfaces. Change the address to a specific IP if you only need access from one subnet.

sudo nano /etc/my.cnf.d/mariadb-server.cnf # WHY: Configuration files in /etc/my.cnf.d/ override defaults. This file persists across package updates.

Add the bind address to the [mysqld] section.

[mysqld]
bind-address = 0.0.0.0 # WHY: Listen on all network interfaces. Change to a specific IP if you only need access from one subnet.

Restart the service to apply the configuration change.

sudo systemctl restart mariadb # WHY: Reload the daemon to pick up the new bind address. The service must restart to rebind the socket.

Open the firewall. MariaDB uses the same port as MySQL, so the firewall service name is mysql. Add the service to the permanent rules and reload the firewall. Always reload after changes, otherwise the runtime configuration and persistent configuration diverge.

sudo firewall-cmd --permanent --add-service=mysql # WHY: Add the MySQL/MariaDB service definition to the permanent firewall rules. This opens port 3306/tcp.
sudo firewall-cmd --reload # WHY: Apply the permanent rules to the running firewall. The reload is mandatory for changes to take effect.

Edit /etc/my.cnf.d/. Files in /usr/lib/ get overwritten on the next update.

Handle SELinux for custom data paths

If you move the data directory away from the default /var/lib/mysql, SELinux blocks access by default. SELinux checks the security context of files, not just the permissions. You must set the correct context for the new directory.

Use semanage to define the file context policy. This persists across relabels. Then use restorecon to apply the context to existing files.

sudo semanage fcontext -a -t mysqld_db_t "/newpath/mysql(/.*)?" # WHY: Define the SELinux file context policy for the new directory. This ensures the context survives a full relabel.
sudo restorecon -Rv /newpath/mysql # WHY: Apply the new context to existing files and directories recursively. The -v flag shows changes.

SELinux denials show up in journalctl -t setroubleshoot with a one-line summary. Read those messages before disabling SELinux. Disabling SELinux is rarely the right fix. Setting the context is faster and safer.

Relabel the directory. SELinux denies access based on context, not just permissions.

Backup and restore

Use mysqldump to create logical backups. The command works identically for MariaDB and MySQL. Dump the database to a SQL file and restore it using the client.

mysqldump -u myuser -p myapp > myapp_backup.sql # WHY: Dump the logical structure and data to a SQL file. The -p flag prompts for the password.
mysql -u myuser -p myapp < myapp_backup.sql # WHY: Restore the database from the SQL dump. The client command is mysql for compatibility.

For large databases, mysqldump can be slow and lock tables. Consider mariabackup for physical backups that support hot backups and point-in-time recovery. The logical dump is sufficient for most small to medium applications.

Dump before you migrate. Restoring from a dump is easier than recovering from a crash.

Common errors and fixes

You will encounter specific errors if the configuration or authentication is misconfigured. Recognizing the error saves time.

The Access denied for user 'root'@'localhost' error often appears when you try to log in with a password but the root user is configured for unix_socket authentication. Fedora's MariaDB package may default to unix_socket for root, which allows sudo mariadb to work without a password but blocks password login. Applications cannot use unix_socket. Create a dedicated user for the app, or change the root authentication plugin.

ALTER USER 'root'@'localhost' IDENTIFIED VIA mysql_native_password USING PASSWORD('strongpassword'); # WHY: Switch root to password authentication if you must use a password for root. Prefer creating a dedicated app user instead.

The Can't connect to local MySQL server through socket error means the client cannot find the socket file. Check if the service is running. Check the socket path in the configuration. The default socket is /var/lib/mysql/mysql.sock. If you moved the data directory, update the socket path in the config.

The Host '...' is not allowed to connect error means the user is scoped to localhost but you are connecting from a remote host. Create the user with the remote host or use 'user'@'%' to allow any host. Scope the user to the specific IP if possible for better security.

Check journalctl -xeu mariadb for the actual error. Guessing based on symptoms wastes time.

Choose the right database

Use MariaDB when you need a drop-in replacement for MySQL with Fedora's native package support and SELinux integration. Use PostgreSQL when your application requires advanced JSON features, complex query optimization, or strict SQL compliance. Use SQLite when you are building a lightweight application with no need for a separate server process or concurrent write access. Stay on the Fedora default MariaDB version unless your application requires a specific legacy release. The Fedora package is tested against the kernel and libraries.

Where to go next