Verified guide
This guide was verified by creating a cloud server and running every command in it, from start to finish, exactly as written.
- OS
- Ubuntu 24.04.5 LTS · x86_64
- Installed version
- MySQL 8.0.46 (8.0.46-0ubuntu0.24.04.4)
- Test server
- DigitalOcean · 1 vCPU / 1 GB RAM / 25 GB SSD (s-1vcpu-1gb, sgp1)
- Last checked
- 2026-10-09
This guide contains affiliate links. If you sign up through them, Codesand may earn a commission. This doesn't affect the content or our assessments.
Install MySQL 8.0 on an Ubuntu 24.04 server, apply the basic security settings and create a user and a database for remote access, and then configure remote access and the firewall so that only your PC can connect.
1. Requirements
- One Ubuntu 24.04 LTS server (1 GB of memory or more recommended)
- SSH access with an account that has
sudoprivileges - The public IP address of the PC you will connect from (e.g.
203.0.113.10)
If you don't have a server, create the smallest DigitalOcean Droplet (1 vCPU · 1 GB). This Droplet is enough to install MySQL 8.0. Every step in this guide was verified on a server created as a Droplet (1 vCPU · 1 GB memory · 25 GB SSD · Ubuntu 24.04 · Singapore).
2. Install MySQL
The default Ubuntu 24.04 repositories include MySQL 8.0. Update the package list, then install it.
sudo apt update
sudo apt install -y mysql-serverWhen the installation finishes, check the installed version.
mysql --versionmysql Ver 8.0.46-0ubuntu0.24.04.4 for Linux on x86_64 ((Ubuntu))3. Check the service status
When the installation finishes, the mysql service starts automatically.
sudo systemctl status mysql --no-pager● mysql.service - MySQL Community Server
Loaded: loaded (/usr/lib/systemd/system/mysql.service; enabled; preset: enabled)
Active: active (running) since Fri 2026-10-09 11:41:25 UTC; 17s agoCheck which addresses and ports MySQL accepts connections on.
sudo ss -tlnp | grep mysqldLISTEN 0 70 127.0.0.1:33060 0.0.0.0:* users:(("mysqld",pid=3339,fd=21))
LISTEN 0 151 127.0.0.1:3306 0.0.0.0:* users:(("mysqld",pid=3339,fd=23))Port 3306 is used by regular MySQL clients, and port 33060 is the X Protocol port used by MySQL Shell and similar tools. Both ports are open only on 127.0.0.1, so for now you can connect only from the server itself. This guide opens only port 3306 to remote connections.
Now check that you can connect to MySQL. Right after installation, you can connect as root without a password with sudo mysql.
sudo mysql -e "SELECT VERSION();"+-------------------------+
| VERSION() |
+-------------------------+
| 8.0.46-0ubuntu0.24.04.4 |
+-------------------------+You can see why no password is needed in the MySQL user list.
sudo mysql -e "SELECT user, host, plugin FROM mysql.user;"+------------------+-----------+-----------------------+
| user | host | plugin |
+------------------+-----------+-----------------------+
| debian-sys-maint | localhost | caching_sha2_password |
| mysql.infoschema | localhost | caching_sha2_password |
| mysql.session | localhost | caching_sha2_password |
| mysql.sys | localhost | caching_sha2_password |
| root | localhost | auth_socket |
+------------------+-----------+-----------------------+The MySQL root user authenticates with auth_socket. auth_socket checks the name of the Linux account that connects to MySQL instead of a password, so you can connect as MySQL root only when you run the client with Linux root privileges (sudo).
4. Basic security settings
MySQL includes the mysql_secure_installation tool, which applies the basic security settings through a series of questions. The tool asks, in order, whether to set up the password validation component, set the root password, remove anonymous users, remove root accounts that can connect remotely, and remove the test database. In this guide, you run the user and database cleanup steps directly in SQL. Because root uses auth_socket, you do not set a password for it.
First, check the current list of databases.
sudo mysql -e "SHOW DATABASES;"+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+When MySQL is installed from the Ubuntu package, as the user list and database list above show, there are no anonymous users and no test database, and root can connect only from localhost. If you installed MySQL another way or have changed its settings, use the commands below to reach the same state. If the server is already in the state shown above, running them changes nothing and prints no output.
sudo mysql -e "DELETE FROM mysql.user WHERE User='';"
sudo mysql -e "DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1');"
sudo mysql -e "DROP DATABASE IF EXISTS test;"
sudo mysql -e "DELETE FROM mysql.db WHERE Db='test' OR Db='test\_%';"
sudo mysql -e "FLUSH PRIVILEGES;"The first line deletes anonymous users that have no name, and the second line deletes root accounts that can connect from outside the server. The third and fourth lines delete the test database and its access privileges, and the last line applies the changed privileges immediately.
5. Create a user and a database
It is safer for applications to connect as a dedicated user instead of the admin account root. Create the database appdb and the user appuser. Be sure to replace the password with a value of your own, and replace 203.0.113.10 with the public IP of the PC you will connect from.
sudo mysql -e "CREATE DATABASE appdb;"
sudo mysql -e "CREATE USER 'appuser'@'localhost' IDENTIFIED BY 'change-this-password';"
sudo mysql -e "CREATE USER 'appuser'@'203.0.113.10' IDENTIFIED BY 'change-this-password';"
sudo mysql -e "GRANT ALL PRIVILEGES ON appdb.* TO 'appuser'@'localhost', 'appuser'@'203.0.113.10';"MySQL identifies a user by user name@connecting host. 'appuser'@'localhost' is used when you connect from the server itself, and 'appuser'@'203.0.113.10' is used when you connect from your PC. Both users have all privileges on appdb only and cannot access other databases.
Check that the users were created.
sudo mysql -e "SELECT user, host, plugin FROM mysql.user WHERE user = 'appuser';"+---------+----------------+-----------------------+
| user | host | plugin |
+---------+----------------+-----------------------+
| appuser | 203.0.113.10 | caching_sha2_password |
| appuser | localhost | caching_sha2_password |
+---------+----------------+-----------------------+Connect as appuser on the server. The -p option means that the client asks for the password, and appdb at the end is the database to connect to.
mysql -u appuser -p appdb -e "SELECT CURRENT_USER(), DATABASE();"Enter password:
+-------------------+------------+
| CURRENT_USER() | DATABASE() |
+-------------------+------------+
| appuser@localhost | appdb |
+-------------------+------------+6. Allow remote connections
The default settings allow only localhost connections. To allow remote connections, change bind-address in /etc/mysql/mysql.conf.d/mysqld.cnf to 0.0.0.0. 0.0.0.0 means that MySQL accepts connections on all of the server's IPv4 addresses.
sudo sed -i 's/^bind-address.*/bind-address = 0.0.0.0/' /etc/mysql/mysql.conf.d/mysqld.cnf
grep -n 'bind-address' /etc/mysql/mysql.conf.d/mysqld.cnf31:bind-address = 0.0.0.0
32:mysqlx-bind-address = 127.0.0.1mysqlx-bind-address on line 32 is the setting for the X Protocol (port 33060), so leave it as it is. Restart MySQL and check that port 3306 is now open on external addresses as well. If you see 0.0.0.0:3306, it is working.
sudo systemctl restart mysql
sudo ss -tlnp | grep mysqldLISTEN 0 70 127.0.0.1:33060 0.0.0.0:* users:(("mysqld",pid=4048,fd=21))
LISTEN 0 151 0.0.0.0:3306 0.0.0.0:* users:(("mysqld",pid=4048,fd=23))7. Configure the firewall (ufw)
Separately from the MySQL settings, allow only your PC's IP to reach port 3306 in the firewall as well. Always allow SSH before you enable the firewall. If you enable the firewall without allowing SSH, your connection to the server is cut off.
sudo ufw allow OpenSSH
sudo ufw allow from 203.0.113.10 to any port 3306 proto tcp
sudo ufw --force enable
sudo ufw statusStatus: active
To Action From
-- ------ ----
OpenSSH ALLOW Anywhere
3306/tcp ALLOW 203.0.113.10
OpenSSH (v6) ALLOW Anywhere (v6)8. Check the connection from your PC
If the mysql client isn't installed on your PC, you can run the MySQL client with Docker and connect. Replace 203.0.113.20 with the server's IP. Because the --rm option is added, the container is deleted automatically when the command finishes. -it is an option that attaches a terminal so that you can enter the password.
docker run --rm -it mysql:8.0 mysql -h 203.0.113.20 -u appuser -p appdb -e "SELECT CURRENT_USER(), DATABASE();"Enter password:
+------------------------+------------+
| CURRENT_USER() | DATABASE() |
+------------------------+------------+
| appuser@203.0.113.10 | appdb |
+------------------------+------------+If your PC's IP is displayed after appuser@, remote access is working. Also check that the connection is encrypted.
docker run --rm -it mysql:8.0 mysql -h 203.0.113.20 -u appuser -p appdb -e "SHOW STATUS LIKE 'Ssl_version';"Enter password:
+---------------+---------+
| Variable_name | Value |
+---------------+---------+
| Ssl_version | TLSv1.3 |
+---------------+---------+TLSv1.3 means that the connection is encrypted with TLS. MySQL 8.0 creates a self-signed certificate when it starts for the first time, and the client uses an encrypted connection when the server supports it.
9. Troubleshooting
ERROR 1698 (28000): Access denied for user 'root'@'localhost'
MySQL root uses auth_socket, so you cannot connect with a password. On the server, connect with sudo mysql. For applications and external tools, use the appuser you created in step 5.
ERROR 2003 (HY000): Can't connect to MySQL server on '203.0.113.20:3306' (111)
This means that MySQL is not accepting connections on external addresses. You get this error if you connect remotely before changing bind-address. 111 in parentheses means that the connection was refused (Connection refused). Check with grep -n 'bind-address' /etc/mysql/mysql.conf.d/mysqld.cnf that it is 0.0.0.0, and check that you ran sudo systemctl restart mysql after changing it.
ERROR 1045 (28000): Access denied for user 'appuser'@'203.0.113.10' (using password: YES)
This means that the password is wrong, or that there is no user for the user@host combination you connected with. With the settings in this guide, connecting as root from a remote PC gives the same error, Access denied for user 'root'@'203.0.113.10'. If the public IP of your home or office has changed, check the registered host with sudo mysql -e "SELECT user, host, plugin FROM mysql.user WHERE user = 'appuser';".
10. Uninstall
To delete MySQL and all of its data, run the commands below. Because the database files are deleted as well, back up any data you need with mysqldump first.
sudo DEBIAN_FRONTEND=noninteractive apt purge -y 'mysql-*'
sudo apt autoremove -y
sudo rm -rf /etc/mysql /var/lib/mysql /var/log/mysqlDEBIAN_FRONTEND=noninteractive is an option that uses the default answers instead of showing configuration prompts while the packages are removed. 'mysql-*' is enclosed in quotes so that the shell does not expand * into file names and passes it to apt as is. When you run the command, several lines with the names of packages that are not installed are displayed, such as Package 'mysql-server-5.7' is not installed, so not removed. This is normal, because apt checks every package whose name starts with mysql-.
Also delete the port 3306 rule you added to the firewall.
sudo ufw delete allow from 203.0.113.10 to any port 3306 proto tcpRule deletedCheck that no MySQL packages remain. If 0 is displayed, everything has been deleted.
dpkg -l | grep -c mysql0Try it yourself
No server yet? You can spin up an Ubuntu server in a few minutes with one of these providers. We verified this guide on DigitalOcean.
Was this guide helpful? Let us know if anything is wrong or out of date.
Request a correction