MySQL 8.0 on Debian is now a legacy installation path: Oracle’s MySQL 8.0 release notes mark 8.0.46 as the end-of-life release in April 2026, but the MySQL APT repository still publishes 8.0 packages for Debian 12 (Bookworm) and Debian 11 (Bullseye). Use these steps when an application still requires the 8.0 branch, and plan a tested move to MySQL 8.4 LTS or MariaDB for new deployments.
Debian 13 (Trixie) does not have a mysql-8.0 component in Oracle’s Debian repository. Trixie users should install Oracle’s MySQL 8.4 LTS packages or use Debian’s default MariaDB packages instead. The 8.0 commands stay scoped to Debian 12 and Debian 11 so APT does not silently resolve a different branch.
Install MySQL 8.0 on Debian 12 or 11
Start by matching your Debian release to the package source. Oracle’s current supported-platform list points new Debian 13 and Debian 12 users toward current MySQL LTS releases, while MySQL 8.0 remains useful only for compatibility-bound systems that cannot move yet.
| Debian Release | MySQL 8.0 Repository State | Validated Candidate | Recommendation |
|---|---|---|---|
| Debian 13 (Trixie) | No mysql-8.0 component | Not available | Use MySQL 8.4 LTS or MariaDB |
| Debian 12 (Bookworm) | Oracle mysql-8.0 component available | 8.0.46-1debian12 | Use only for MySQL 8.0 compatibility |
| Debian 11 (Bullseye) | Oracle mysql-8.0 component available | 8.0.37-1debian11 | Legacy maintenance path only |
Do not install MySQL 8.0 on a server that already runs MariaDB or another MySQL-compatible fork unless you have a tested migration plan and verified backups. Oracle’s MySQL packages conflict with MariaDB packages, and replacing a live database server is a maintenance-window task, not a routine package install.
Oracle documents the repository family in the MySQL APT repository guide, and the current platform matrix is listed on Oracle’s MySQL supported platforms page. Debian’s default package sources do not ship Oracle MySQL; they ship MariaDB as the default MySQL-compatible server.
Use one Oracle MySQL source path. Do not configure both extrepo and the manual source on the same system, because duplicate MySQL APT sources can create confusing candidates or signature-path conflicts. The manual DEB822 source keeps the Debian release and MySQL branch guard visible before APT refreshes metadata.
Refresh Debian Packages
Refresh APT before adding a new vendor source so dependency resolution uses current Debian metadata.
sudo apt update
sudo apt upgrade
These commands use
sudo. If your user cannot run administrative commands, configure sudo access before continuing.
Install Repository Prerequisites
Install the tools needed to download the signing key, convert it into an APT keyring, and create the repository file. Minimal Debian systems often lack curl and gpg, so install them explicitly.
sudo apt install -y ca-certificates curl gpg
Import the MySQL APT Signing Key
Import MySQL’s current APT signing key and store it as a dedicated keyring. The curl command guide explains the download flags if you want a deeper look at the command.
curl -fsSL "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0xb7b3b788a8d3785c" | sudo gpg --dearmor --yes -o /usr/share/keyrings/mysql.gpg
Verify the key identity before trusting packages from the repository.
gpg --show-keys --with-fingerprint /usr/share/keyrings/mysql.gpg
Expected key identity:
pub rsa4096 2023-10-23 [SC] [expires: 2027-10-23]
BCA4 3417 C3B4 85DD 128E C6D4 B7B3 B788 A8D3 785C
uid MySQL Release Engineering <mysql-build@oss.oracle.com>
Create the MySQL 8.0 APT Source
Create a DEB822 source file that only enables the MySQL 8.0 and tools components for standard amd64 Debian systems. The release guard stops the command on Debian 13 and any other unsupported codename before it writes a source file.
(
. /etc/os-release
arch=$(dpkg --print-architecture)
case "$VERSION_CODENAME" in
bookworm|bullseye) ;;
*)
printf 'Oracle does not publish MySQL 8.0 packages for Debian %s. Use MySQL 8.4 LTS or MariaDB instead.\n' "$VERSION_CODENAME"
exit 1
;;
esac
case "$arch" in
amd64) ;;
*)
printf 'This MySQL 8.0 source block was validated for amd64, not %s.\n' "$arch"
exit 1
;;
esac
printf '%s\n' \
'Types: deb' \
'URIs: https://repo.mysql.com/apt/debian' \
"Suites: $VERSION_CODENAME" \
'Components: mysql-8.0 mysql-tools' \
"Architectures: $arch" \
'Signed-By: /usr/share/keyrings/mysql.gpg' | sudo tee /etc/apt/sources.list.d/mysql.sources > /dev/null
)
Confirm that the source file uses your Debian codename and the mysql-8.0 component.
cat /etc/apt/sources.list.d/mysql.sources
Debian 12 example:
Types: deb URIs: https://repo.mysql.com/apt/debian Suites: bookworm Components: mysql-8.0 mysql-tools Architectures: amd64 Signed-By: /usr/share/keyrings/mysql.gpg
Debian 11 should show Suites: bullseye. If a file shows Suites: trixie, remove it and use a current MySQL 8.4 or MariaDB path instead.
Confirm the MySQL 8.0 Candidate
Refresh APT, then check which package source owns mysql-server. With the MySQL 8.0 source enabled, APT resolves mysql-server to Oracle’s MySQL Community packages.
sudo apt update
apt-cache policy mysql-server
Relevant Debian 12 output:
mysql-server:
Installed: (none)
Candidate: 8.0.46-1debian12
Version table:
8.0.46-1debian12 500
500 https://repo.mysql.com/apt/debian bookworm/mysql-8.0 amd64 Packages
Debian 11 should show 8.0.37-1debian11 from bullseye/mysql-8.0. If APT shows MariaDB, Debian’s default-mysql-server, or no candidate, fix the repository file before installing.
Install MySQL 8.0 Server
Install the standard mysql-server package after the candidate points to Oracle’s mysql-8.0 component.
sudo apt install mysql-server
The MySQL Community package can prompt for a root password and an authentication plugin. Choose a strong root password and keep caching_sha2_password unless a legacy application is known to require mysql_native_password. Store the password in your normal secrets workflow.
Verify and Start Using MySQL 8.0
Check the MySQL Service and Version
The Oracle package installs a mysql systemd service and normally starts it automatically. Check the installed client version and service state.
mysql --version
systemctl is-active mysql
systemctl is-enabled mysql
Expected output pattern:
mysql Ver 8.0.x for Linux on x86_64 (MySQL Community Server - GPL) active enabled
If the service is not running, start it and enable it at boot.
sudo systemctl enable --now mysql
Connect to MySQL Locally
Use the root password created during installation to run a simple version query.
mysql -u root -p -e "SELECT VERSION();"
Expected output pattern:
VERSION() 8.0.x
Create a Database and Application User
A normal application should not connect as the MySQL root account. Create a database and a dedicated local user, then grant that user access only to the database it needs.
mysql -u root -p
CREATE DATABASE appdb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'appuser'@'localhost' IDENTIFIED BY 'replace_with_a_strong_password';
GRANT ALL PRIVILEGES ON appdb.* TO 'appuser'@'localhost';
FLUSH PRIVILEGES;
EXIT;
Replace the database name, user name, and password with values that match your application. Test the new account before wiring it into an application config file.
mysql -u appuser -p appdb -e "SHOW TABLES;"
Secure MySQL 8.0 After Installation
Run the MySQL Security Helper
Run MySQL’s bundled security helper after the service starts. It reviews common weak defaults such as anonymous users, remote root login, the test database, and privilege-table reloads.
sudo mysql_secure_installation
For a new server, the usual secure choices are to keep or set a strong root password, remove anonymous users, disallow remote root login, remove the test database, and reload privilege tables. The helper is interactive, so read each prompt instead of pasting a fixed answer sequence from an old tutorial.
Keep MySQL Local Unless Remote Access Is Required
MySQL should stay reachable only from localhost unless an application on another host must connect directly. For many web stacks, the safer design is to keep the database local to the application server or connect through a private network, VPN, or SSH tunnel.
sudo ss -ltnp | grep ':3306' || echo 'No MySQL TCP listener found on port 3306.'
A localhost-only listener commonly appears as 127.0.0.1:3306 or [::1]:3306. Do not expose 3306/tcp to the internet.
Allow Remote Application Access When Needed
If a separate application server must connect, change MySQL’s bind address deliberately, restrict the firewall to the application server IP, and create a MySQL account scoped to that host. Use 0.0.0.0 only when a firewall or private network limits who can reach port 3306/tcp.
printf '%s\n' '[mysqld]' 'bind-address = 0.0.0.0' | sudo tee /etc/mysql/mysql.conf.d/99-remote-bind.cnf > /dev/null
sudo systemctl restart mysql
sudo ss -ltnp | grep ':3306'
If you use UFW on Debian, allow only the trusted application host. Replace 192.0.2.50 with the real private IP address of your application server.
sudo ufw allow from 192.0.2.50 to any port 3306 proto tcp
Create a MySQL user that matches the remote host instead of allowing broad host patterns.
CREATE USER 'appuser'@'192.0.2.50' IDENTIFIED BY 'replace_with_a_strong_password';
GRANT ALL PRIVILEGES ON appdb.* TO 'appuser'@'192.0.2.50';
FLUSH PRIVILEGES;
Rollback remote access by removing
/etc/mysql/mysql.conf.d/99-remote-bind.cnf, restarting MySQL, and deleting the UFW rule created for port3306/tcp. Keep the database closed until a specific application host needs direct access.
Update MySQL 8.0 Packages
APT manages MySQL packages after the Oracle source is configured. Because MySQL 8.0 is past its support window, updates should be treated as final branch maintenance only, not ongoing feature or long-term security coverage. Schedule package updates for a maintenance window because MySQL server package upgrades can restart the service.
sudo apt update
sudo apt install mysql-server
Run the candidate check again when planning a branch change. A MySQL 8.0-to-8.4 move is a database upgrade and needs backups, application compatibility checks, and a maintenance window.
apt-cache policy mysql-server
Remove MySQL 8.0 from Debian
Back Up Databases Before Removal
Export databases before removing server packages. The command prompts for the MySQL root password and writes a dated SQL dump in your home directory.
mysqldump --all-databases --single-transaction --routines --triggers -u root -p > ~/mysql-8-0-backup-$(date +%F).sql
Stop and Purge MySQL Packages
Stop the service, then purge the Oracle MySQL packages installed by the repository path.
sudo systemctl stop mysql
sudo apt purge mysql-server mysql-client mysql-community-server mysql-community-client mysql-community-server-core mysql-community-client-core mysql-community-client-plugins mysql-common
Check for remaining installed MySQL packages before cleaning dependencies or data directories.
dpkg-query -W -f='${db:Status-Abbrev} ${binary:Package}\n' 'mysql*' 2>/dev/null | grep '^ii' || echo 'No installed MySQL packages remain.'
Preview autoremovable packages before deleting dependencies on a reused server.
sudo apt autoremove --purge --dry-run
If the preview lists only MySQL-related packages you no longer need, run the cleanup.
sudo apt autoremove --purge
Remove the Oracle MySQL APT Source
Remove the source file created during installation, then remove the keyring only when no remaining APT source references it. Refresh APT afterward so Oracle’s repository no longer contributes candidates.
sudo rm -f /etc/apt/sources.list.d/mysql.sources
remaining_mysql_key_refs=$(find /etc/apt/sources.list /etc/apt/sources.list.d -type f -print 2>/dev/null | xargs -r grep -lF '/usr/share/keyrings/mysql.gpg' 2>/dev/null || true)
if [ -z "$remaining_mysql_key_refs" ]; then
sudo rm -f /usr/share/keyrings/mysql.gpg
else
printf 'Keeping /usr/share/keyrings/mysql.gpg because another APT source still references it:\n%s\n' "$remaining_mysql_key_refs"
fi
sudo apt update
apt-cache policy mysql-server
After source cleanup, apt-cache policy should no longer list repo.mysql.com. If an older extrepo-based setup is still present, remove that source as well before rechecking.
if command -v extrepo >/dev/null 2>&1; then
sudo extrepo disable mysql-8.0 || true
fi
sudo rm -f /etc/apt/sources.list.d/extrepo_mysql-8.0.sources /var/lib/extrepo/keys/mysql-8.0.*
sudo apt update
Delete MySQL Data Files Only When Intended
The cleanup command permanently deletes MySQL databases, logs, and configuration. Do not run it unless your backup is verified and no remaining MySQL-compatible server uses these paths.
sudo rm -rf /var/lib/mysql /var/log/mysql /etc/mysql
Troubleshoot MySQL 8.0 on Debian
Fix NO_PUBKEY or EXPKEYSIG for B7B3B788A8D3785C
If sudo apt update reports NO_PUBKEY, EXPKEYSIG, or an invalid signature for B7B3B788A8D3785C, refresh the MySQL keyring and run APT again.
curl -fsSL "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0xb7b3b788a8d3785c" | sudo gpg --dearmor --yes -o /usr/share/keyrings/mysql.gpg
sudo apt update
If the error continues, confirm that Signed-By: /usr/share/keyrings/mysql.gpg appears in /etc/apt/sources.list.d/mysql.sources and that the fingerprint matches the expected MySQL key identity.
Fix Package Not Found or the Wrong MySQL Branch
Check the Debian codename, repository file, and final candidate when APT cannot find MySQL 8.0 or resolves a different branch.
. /etc/os-release
printf '%s\n' "$VERSION_CODENAME"
cat /etc/apt/sources.list.d/mysql.sources
apt-cache policy mysql-server
Debian 12 must use Suites: bookworm, and Debian 11 must use Suites: bullseye. Debian 13 cannot use mysql-8.0; Oracle’s Trixie repository publishes MySQL 8.4 LTS and newer branches instead.
Fix mysql_secure_installation Command Not Found
Oracle’s MySQL 8.0 packages provide mysql_secure_installation through mysql-community-server-core. If the command is missing, verify that the Oracle server package is installed from the intended source. On Debian 13 (Trixie), use a supported MySQL 8.4 LTS or MariaDB path first; Oracle does not publish a Trixie mysql-8.0 component.
dpkg -l 'mysql-server*' 'mysql-community-server*' | grep '^ii'
dpkg -L mysql-community-server-core | grep '/mysql_secure_installation$'
If those checks fail, repair the repository source, refresh APT, and reinstall the server metapackage.
sudo apt update
sudo apt install mysql-server
Handle MariaDB or Other MySQL-Compatible Conflicts
APT may refuse the transaction or plan removals if MariaDB is already installed. Inspect the installed package set and simulate the MySQL install before making changes.
dpkg -l 'mariadb*' | grep '^ii' || echo 'No installed MariaDB packages found.'
apt-get -s install mysql-server
If the simulation lists MariaDB removals, held packages, or dependency conflicts, stop and plan a migration. Export databases, test restores, and confirm application compatibility before replacing server packages.
Fix Access Denied or Authentication Plugin Errors
Access denied errors usually mean the wrong user, password, host match, or authentication plugin was used. Start by checking the exact account and host entries from an administrative session.
mysql -u root -p -e "SELECT user, host, plugin FROM mysql.user ORDER BY user, host;"
For new applications, keep caching_sha2_password and update the application connector if it cannot authenticate. Use mysql_native_password only for a verified legacy application that cannot support the default plugin.
ALTER USER 'appuser'@'localhost' IDENTIFIED WITH caching_sha2_password BY 'replace_with_a_strong_password';
FLUSH PRIVILEGES;
If a legacy application truly requires the old plugin, change only that application user.
ALTER USER 'appuser'@'localhost' IDENTIFIED WITH mysql_native_password BY 'replace_with_a_strong_password';
FLUSH PRIVILEGES;
Diagnose a MySQL Service That Will Not Start
Check service status, recent journal entries, MySQL’s error log, and port ownership before changing data-directory permissions or deleting files.
sudo systemctl status mysql --no-pager
sudo journalctl -u mysql -n 80 --no-pager
sudo tail -n 80 /var/log/mysql/error.log
sudo ss -ltnp | grep ':3306' || echo 'No MySQL listener found on port 3306.'
Common causes include another service already using port 3306/tcp, a bad option in a file under /etc/mysql/, a failed remote-bind change, or data files copied with the wrong ownership. Avoid broad recursive ownership changes on /var/lib/mysql unless the error log specifically identifies a permissions problem.
Related Debian Guides
- Install MariaDB on Debian when you want Debian’s default MySQL-compatible server instead of Oracle MySQL.
- Install phpMyAdmin with Nginx on Debian for browser-based MySQL or MariaDB administration.
- Install PHP on Debian before deploying PHP applications that use MySQL.
- Install Fail2ban on Debian when you need log-based protection for exposed services.
- Manage third-party APT repositories on Debian with extrepo when auditing older external source files.
Conclusion
MySQL 8.0 is installed on Debian 12 or 11 from Oracle’s legacy 8.0 repository, with the service verified, the security helper available, and application-user setup ready for local workloads. Keep the server on a restricted listener, back up before package changes, and treat any move to MySQL 8.4 LTS as a planned database upgrade rather than a routine refresh.


Formatting tips for your comment
You can use basic HTML to format your comment. Useful tags currently allowed in published comments:
<code>command</code>command<strong>bold</strong><em>italic</em><blockquote>quote</blockquote>