Databases are the backbone of nearly every web application in existence. MySQL has held the top spot in the relational database world for nearly three decades and it’s not hard to see why. It’s open source, exceptionally well-documented and supported by virtually every hosting stack imaginable. From a personal blog to an enterprise platform processing millions of records, MySQL handles the workload without breaking a sweat.
If you’re spinning up a new VPS and need a reliable database layer, MySQL is a rock-solid starting point. This guide covers the entire setup from start to finish: installing MySQL on Ubuntu, locking it down with the built-in security script, creating a dedicated database user and verifying your connection. By the end you’ll have a production-ready MySQL instance ready to power whatever you’re building.
What Is MySQL?
MySQL is an open-source relational database management system (RDBMS). It organizes data into structured tables with defined columns and uses SQL (Structured Query Language) to query, insert, update and delete records. Oracle acquired MySQL in 2010 through its purchase of Sun Microsystems but the project remains open source under the GPL license and continues to evolve actively.
It’s famously the “M” in the LAMP stack (Linux, Apache, MySQL, PHP) and the database engine powering WordPress, Drupal, Magento and countless other applications. MySQL supports ACID-compliant transactions, full-text indexing, JSON document storage and robust replication features. Whether your project demands a compact single-server setup or a clustered configuration with read replicas, MySQL is built for it.
Prerequisites
Before starting, confirm your environment meets the following requirements.
| Requirement | Minimum | Recommended |
|---|---|---|
| Operating System | Ubuntu 22.04 LTS | Ubuntu 24.04 LTS |
| CPU | 1 vCPU | 2+ vCPUs |
| RAM | 1 GB | 4 GB |
| Storage | 10 GB SSD | 40+ GB SSD |
| Server Access | Root or sudo user | Root or sudo user |
Step 1: Update Your System
Start with a clean slate. Pull in the latest package index and apply any pending security patches before touching anything else. Outdated packages are a surprisingly common source of installation headaches and there’s no reason to carry that risk forward.
sudo apt update && sudo apt upgrade -y
Step 2: Install MySQL Server
Ubuntu’s official package repositories ship MySQL 8.0, the current long-term support release and a fully production-capable version. Install it with a single command.
sudo apt install mysql-server -y
MySQL starts automatically after installation finishes. Verify the service is running before moving on.
sudo systemctl status mysql
Look for Active: active (running) in the output. If the service didn’t start on its own, enable and launch it manually.
sudo systemctl enable --now mysql
If you need MySQL 8.4 LTS or a newer version than what Ubuntu ships by default, add the official MySQL APT repository before installing. Visit dev.mysql.com/downloads/repo/apt/ to download the latest configuration package, run through the version-selection prompt and then proceed with apt install mysql-server as shown above.
Step 3: Secure Your MySQL Installation
A fresh MySQL installation ships with permissive defaults that make sense for local development but not for a server exposed to the internet. Think of it like a new house with all the windows left open. The mysql_secure_installation script closes them in about two minutes. Run it now.
sudo mysql_secure_installation
The script walks you through a series of prompts. Here’s what each one controls and what to choose for a production deployment.
| Prompt | Recommended Choice | Why It Matters |
|---|---|---|
| Validate Password Component | Enable (select MEDIUM or STRONG) | Enforces password strength for all MySQL accounts |
| Set Root Password | Set a strong, unique password | Secures the most privileged account on the server |
| Remove Anonymous Users | Y | Anonymous connections are an open door you don’t want |
| Disallow Root Login Remotely | Y | Root should only ever connect from localhost |
| Remove Test Database | Y | The test database has open permissions by default |
| Reload Privilege Tables | Y | Applies all changes immediately without a restart |
Step 4: Log In and Create a Database
With MySQL locked down, it’s time to create your first database and a dedicated application user. Connecting your application as root is a bad habit worth skipping entirely. A purpose-specific user with scoped permissions limits the damage considerably if credentials ever end up in the wrong hands.
On Ubuntu, MySQL’s root account authenticates via the auth_socket plugin by default rather than a password. Use sudo to log in.
sudo mysql
Run the following SQL commands inside the MySQL shell. Replace myapp_db, myapp_user and YourStrongPassword! with values specific to your project.
CREATE DATABASE myapp_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'myapp_user'@'localhost' IDENTIFIED BY 'YourStrongPassword!';
GRANT ALL PRIVILEGES ON myapp_db.* TO 'myapp_user'@'localhost';
FLUSH PRIVILEGES;
EXIT;
A few notes on what’s happening here. The utf8mb4 character set provides full Unicode support, including emoji. The @'localhost' restriction locks the user to local connections only, which is exactly the right default. FLUSH PRIVILEGES reloads the grant tables immediately so the new permissions take effect without restarting the service.
Step 5: Configure the Firewall
MySQL binds to 127.0.0.1 by default, accepting connections from the local machine only. That’s exactly where you want it. Port 3306 should stay closed to the outside world. The only rule you need right now is one that keeps SSH open so you don’t lock yourself out.
sudo ufw allow OpenSSH
sudo ufw enable
sudo ufw status
Applications running on the same server connect to MySQL through localhost and need no firewall changes. If you genuinely need remote database access from a separate app server, tunnel through SSH rather than exposing port 3306 publicly. It’s faster to configure than most people expect and far more secure than an open port.
Step 6: Test Your Database Connection
Verify the new user can connect and reach the correct database before you wire any application to it. One quick test here saves significant debugging time later.
mysql -u myapp_user -p myapp_db
Enter the password you set during the user creation step. Once inside the MySQL shell, confirm the session is pointed at the right database.
SHOW DATABASES;
SELECT DATABASE();
EXIT;
Seeing myapp_db in the output confirms the user has correct permissions and the database is ready for connections.
How to Update MySQL
MySQL ships regular security patches so staying current is part of normal server maintenance. The upgrade process on Ubuntu takes about thirty seconds.
sudo apt update
sudo apt upgrade mysql-server -y
sudo systemctl restart mysql
sudo systemctl status mysql
Before any major version upgrade, such as moving from MySQL 8.0 to 8.4, back up all your databases first. Don’t skip this step.
mysqldump -u root -p --all-databases > all_databases_backup_$(date +%F).sql
The $(date +%F) appends today’s date to the filename automatically. When you have multiple backups on disk, you’ll be glad they’re labeled clearly.
Troubleshooting Common MySQL Issues
MySQL Service Won’t Start
If MySQL fails to start after installation or a restart, pull the recent service logs. The error message almost always points directly at the problem.
sudo journalctl -u mysql --no-pager -n 50
Port conflicts are a common culprit. Check whether something else is already occupying port 3306.
sudo ss -tlnp | grep 3306
If another process is using that port, stop it or reconfigure MySQL to bind to a different port in /etc/mysql/mysql.conf.d/mysqld.cnf. Incorrect ownership of the MySQL data directory is another frequent cause. Fix it with the following command and try starting the service again.
sudo chown -R mysql:mysql /var/lib/mysql
sudo systemctl start mysql
Access Denied for Root User
On Ubuntu, MySQL root authentication uses the auth_socket plugin by default rather than a password. Running mysql -u root -p will fail even if you type the correct password. Always connect as root using sudo.
sudo mysql
If you need password-based root access (for scripts or remote management tools, for example), switch the authentication method after logging in.
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'YourNewRootPassword!';
FLUSH PRIVILEGES;
Forgot the Root Password
Stop MySQL and restart it with the --skip-grant-tables flag. This bypasses authentication temporarily so you can log in and reset the password.
sudo systemctl stop mysql
sudo mysqld_safe --skip-grant-tables &
Connect without a password and reset root’s credentials.
sudo mysql -u root
FLUSH PRIVILEGES;
ALTER USER 'root'@'localhost' IDENTIFIED BY 'NewStrongPassword!';
EXIT;
Restart MySQL normally to re-enable authentication.
sudo systemctl restart mysql
MySQL Is Consuming Too Much Memory
MySQL’s InnoDB buffer pool defaults to 128 MB but grows significantly under sustained load. On a VPS with limited RAM, this can crowd out other services running on the same machine. Set an explicit ceiling in the MySQL configuration file.
sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf
Add or update the following line under the [mysqld] section.
innodb_buffer_pool_size = 256M
For a dedicated database server, allocating 70 to 80 percent of total RAM to the buffer pool is reasonable. For a shared VPS running multiple services, keep it lower. Restart MySQL to apply the change.
sudo systemctl restart mysql
Application Can’t Connect to the Database
Start by confirming MySQL is actually running.
sudo systemctl status mysql
Next, verify the user’s host restriction inside MySQL.
sudo mysql
SELECT user, host, plugin FROM mysql.user WHERE user = 'myapp_user';
If the host column shows localhost, the application must connect using 127.0.0.1 or localhost as the database host rather than an external IP or fully qualified hostname. Check your application’s database configuration file and confirm the host value matches exactly. Verify the database name and password are spelled correctly in both the MySQL grant statement and your application config. A single typo in either place produces the same generic connection error.
What to Build Next
With a secured, tested MySQL instance on your VPS, you’re ready to connect real applications and expand your stack. A few directions worth exploring next.
- Connect WordPress: MySQL is the native database engine for WordPress. Pair this installation with a WordPress VPS setup and you’ll have a fully self-hosted site running in a matter of minutes.
- Add a Browser-Based GUI: Tools like phpMyAdmin or Adminer give you a visual interface for managing tables, running queries and importing data without opening a terminal.
- Automate Your Backups: Schedule nightly
mysqldumpexports using cron or integrate a tool like AutoMySQLBackup. Backups feel unnecessary until the moment they’re not. - Configure Read Replication: MySQL’s binary log replication lets you add read replicas for performance or wire up a failover secondary for high availability. Both are well within reach on a standard VPS setup.
- Secure Remote Access via SSH Tunnel: If you need to connect to MySQL from a remote machine, tunnel through SSH rather than opening port 3306. It takes about five minutes to configure and eliminates an entire category of attack surface.
Conclusion
MySQL is one of those foundational technologies that quietly powers an enormous slice of the modern web. Getting it installed and configured correctly on your VPS is a skill that pays dividends across nearly every project you build. Follow the steps above and you’ll have a production-ready database instance with proper user permissions, a locked-down firewall and the baseline security configuration your server needs from day one.


