SSD Nodes Learn Hosting plans →
Guías Matt ConnorPor Matt Connor

Cómo instalar MySQL en Debian (y por qué te da MariaDB)

En Debian, apt no trae MySQL: trae MariaDB. Decide entre la MariaDB de Debian y el MySQL de Oracle, instala cualquiera de los dos y deja la base de datos cerrada a internet.

Qué pasa cuando intentas instalar MySQL en Debian

Si quieres instalar MySQL en Debian, primero debes saber una cosa: la versión estable de Debian no trae MySQL en su archivo oficial. Trae MariaDB, una bifurcación de MySQL mantenida por la MariaDB Foundation. El paquete default-mysql-server existe, pero instala MariaDB. Tienes dos caminos. Puedes usar la MariaDB de Debian, que recibe parches de seguridad del propio Debian. O puedes añadir el repositorio APT de Oracle y tener MySQL de verdad.

Los comandos de abajo están escritos para Debian 13 «trixie», la versión estable a 1 de octubre de 2026. Si todavía buscas cómo instalar MySQL en Debian 12 «bookworm», la situación es la misma: allí default-mysql-server también apunta a MariaDB, en la serie 10.11. Los pasos sirven para las dos versiones. Solo cambian los números de versión.

Todos los comandos de esta guía los ejecutas tú, en tu servidor. Después de cada paso importante hay una comprobación, y te explico qué debes ver.

¿Hay un paquete mysql-server en Debian? Compruébalo con apt-cache policy

Antes de instalar nada, pregunta a apt qué tiene disponible. Estos comandos no cambian nada en el sistema:

sudo apt update
apt-cache policy mysql-server default-mysql-server mariadb-server

Lee la salida paquete por paquete. Para cada nombre, apt muestra una línea Installed: (lo que tienes instalado) y una línea Candidate: (lo que instalaría). Si tu sistema está en español, verás Instalados: y Candidato:. En un Debian 13 sin repositorios extra, default-mysql-server y mariadb-server tienen candidato, y la tabla de versiones de debajo apunta a deb.debian.org con la rama trixie. Para mysql-server no hay candidato, o apt avisa de que no encuentra el paquete. Las dos respuestas significan lo mismo: ningún repositorio configurado ofrece ese nombre.

Para ver qué hay detrás del metapaquete, pregunta por sus dependencias:

apt-cache depends default-mysql-server

La línea Depends: nombra mariadb-server-compat. Ese paquete depende a su vez de mariadb-server. Por eso apt install default-mysql-server te deja con MariaDB instalada.

En packages.debian.org, a 1 de octubre de 2026, mysql-server solo aparece en sid, la rama inestable, con MySQL 9.7. No está en trixie (estable) ni en forky (testing). Mezclar paquetes de sid con la rama estable no es una opción razonable para un servidor. Si no tienes clara la diferencia, lee qué significan stable, testing y unstable en un servidor Debian antes de tocar tus fuentes de apt.

MariaDB o MySQL: cuál instalar en tu servidor Debian

MariaDB nació en 2009 como bifurcación de MySQL. Para la mayoría de las aplicaciones web son intercambiables: el protocolo de red y el SQL habitual son compatibles. WordPress, Nextcloud o Drupal funcionan igual con MariaDB. Si vienes de montar una pila LAMP en Ubuntu 24.04, donde mysql-server sí está en el archivo, en Debian puedes usar MariaDB sin cambiar el código PHP de tu aplicación.

Elige la MariaDB de Debian cuando:

  • Los requisitos de tu aplicación dicen «MySQL o MariaDB». Es el caso más común.
  • Quieres que los parches de seguridad lleguen por trixie-security, igual que los del resto del sistema.

Elige el MySQL de Oracle cuando se cumpla algo de esta lista:

  • Replicas desde o hacia otro MySQL, por ejemplo Amazon RDS for MySQL o un servidor primario que ya tienes. Los GTID (identificadores globales de transacción) de MySQL y de MariaDB tienen formatos distintos, así que la replicación basada en GTID no funciona entre los dos.
  • Usas el X Protocol (puerto 33060) o la AdminAPI de MySQL Shell para InnoDB Cluster y Group Replication. MariaDB no implementa ninguno de los dos. Su solución de clúster es Galera.
  • El proveedor de tu software solo certifica «MySQL 8.4» o «MySQL 9.7», y quieres poder abrir un caso de soporte sin discusiones.
  • Tu esquema depende mucho de columnas JSON. En MySQL, JSON es un tipo binario propio. En MariaDB, JSON es un alias de LONGTEXT con una comprobación JSON_VALID. Un volcado se importa, pero mide tus consultas JSON antes de migrar.

Si todavía no has elegido distribución y necesitas el MySQL de Oracle, esa necesidad pesa en la decisión. Qué sistema operativo elegir para tu VPS compara las opciones. Y si dudas entre instalar la base de datos en el sistema o en un contenedor, base de datos en Docker o directamente en el host explica qué cambia en cada caso.

Camino A: instalar MariaDB desde los repositorios de Debian

sudo apt update
sudo apt install -y mariadb-server
systemctl status mariadb --no-pager
sudo mariadb -e "SELECT VERSION();"

systemctl status debe mostrar active (running). La consulta debe devolver una versión que empieza por 11.8 y contiene la palabra MariaDB. A 1 de octubre de 2026, el archivo de trixie ofrece MariaDB 11.8.6.

Instalo mariadb-server y no default-mysql-server porque el nombre dice lo que obtienes. El metapaquete instala el mismo servidor más un paquete pequeño de compatibilidad.

sudo mariadb entra sin contraseña, y no es un fallo. En Debian, el usuario root de MariaDB se autentica con el plugin unix_socket. Ese plugin comprueba qué usuario de Linux se conecta por el socket local, y solo deja entrar a root. Por eso sudo mariadb funciona y mariadb -u root sin sudo falla.

Endurecer MariaDB con mariadb-secure-installation

sudo mariadb-secure-installation

En trixie, este script viene en el paquete mariadb-client, que se instala con el servidor. El nombre antiguo, mysql_secure_installation, vive en un paquete aparte (mariadb-client-compat), así que puede no existir en tu sistema. Usa el nombre que empieza por mariadb-.

Cuando el script pida la contraseña actual de root, pulsa Enter: root no tiene contraseña porque usa unix_socket. Puedes mantener unix_socket para root. Después responde que sí a quitar los usuarios anónimos, a prohibir el acceso remoto de root, a borrar la base de datos test y a recargar las tablas de privilegios.

Camino B: instalar MySQL de Oracle con el repositorio APT oficial

Oracle publica un repositorio APT para Debian. Lo añades con un paquete pequeño, mysql-apt-config, que escribe la entrada del repositorio y su clave GPG (GNU Privacy Guard). La página de plataformas soportadas de Oracle lista Debian 12 y Debian 13 para las series 9.7 LTS y 8.4 LTS, a 1 de octubre de 2026.

¿Qué versión de MySQL elegir?

LTS significa soporte a largo plazo (long-term support). Según el calendario de Oracle, MySQL 9.7 LTS salió el 21 de abril de 2026, con soporte principal hasta abril de 2031. MySQL 8.4 LTS tiene soporte principal hasta abril de 2029. MySQL 8.0 pasó a Sustaining Support en abril de 2026, lo que significa que ya no recibe correcciones nuevas.

Para una instalación nueva, elige 9.7 LTS. Elige 8.4 LTS solo si tu aplicación, o el servidor con el que replicas, está en 8.4. Evita las versiones Innovation en un servidor de producción, porque cada una deja de recibir parches cuando sale la siguiente.

Añadir el repositorio

Abre la página de descarga del repositorio APT de MySQL: https://dev.mysql.com/downloads/repo/apt/. Copia el enlace del fichero mysql-apt-config_..._all.deb. El enlace «No thanks, just start my download» evita el registro.

sudo apt install -y wget
cd /tmp
wget https://dev.mysql.com/get/mysql-apt-config_VERSION_all.deb
sudo apt install ./mysql-apt-config_VERSION_all.deb

Sustituye VERSION por la que muestra la página ese día. No copies un número de otro tutorial. Un mysql-apt-config antiguo puede traer una clave de firma caducada, y entonces apt update falla con un error de firma para repo.mysql.com. El ./ delante del nombre importa: sin él, apt busca un paquete con ese nombre en los repositorios en lugar de usar el fichero local.

El paquete abre un menú de texto. Entra en la opción del servidor MySQL, elige la serie LTS que decidiste y termina con «Ok». Si te equivocas, sudo dpkg-reconfigure mysql-apt-config vuelve a abrir el menú.

sudo apt update
apt-cache policy mysql-server

Ahora mysql-server sí tiene candidato, y la tabla de versiones apunta a repo.mysql.com. Si no hay candidato, el repositorio no se añadió bien. Revisa los errores de apt update y los ficheros de /etc/apt/sources.list.d/.

Instalar el servidor

sudo apt install mysql-server

Durante la instalación, un diálogo pide una contraseña para root. Puedes dejarla vacía. Según la documentación de MySQL, root queda entonces autenticado por las credenciales del socket local, igual que MariaDB en Debian. sudo mysql entra y mysql -u root sin sudo no.

systemctl status mysql --no-pager
sudo mysql -e "SELECT VERSION();"

El servicio se llama mysql. Debe estar active (running), y la versión debe empezar por la serie que elegiste, por ejemplo 9.7..

Este camino asume un servidor sin MariaDB. Los paquetes de Oracle entran en conflicto con los de MariaDB, y apt propone quitarlos. Lee esa lista antes de aceptar. Si MariaDB ya tiene datos, haz un volcado de las bases de tu aplicación con mariadb-dump, instala MySQL en un VPS limpio y restaura allí.

Endurecer MySQL con mysql_secure_installation

sudo mysql_secure_installation

En MySQL el script conserva el nombre clásico, con guion bajo. Primero ofrece activar el componente VALIDATE PASSWORD, que rechaza contraseñas débiles al crear cuentas. Actívalo si otras personas van a crear usuarios. Después hace las mismas preguntas que la versión de MariaDB: usuarios anónimos, acceso remoto de root, base de datos test y recarga de privilegios.

Cómo hacer que MySQL escuche solo en localhost (bind-address)

Este es el paso más importante de la guía. Mira en qué direcciones escucha el servidor:

sudo ss -ltnp | grep -E ':3306|:33060'

Con la MariaDB de Debian debes ver 127.0.0.1:3306. El fichero /etc/mysql/mariadb.conf.d/50-server.cnf trae bind-address = 127.0.0.1 por defecto. No lo cambies salvo que necesites acceso remoto directo.

Con el MySQL de Oracle, mira la salida con cuidado. En MySQL, el valor por defecto de bind_address es *, que significa todas las interfaces IPv4 e IPv6. El X Protocol tiene su propia variable, mysqlx_bind_address, que también vale * por defecto, en el puerto 33060. Si tu configuración no fija esas variables, ss muestra una dirección comodín en los dos puertos.

Busca el fichero que contiene la sección [mysqld]:

sudo grep -rlF '[mysqld]' /etc/mysql/

En los paquetes de Oracle suele ser /etc/mysql/mysql.conf.d/mysqld.cnf. Añade estas dos líneas debajo de [mysqld]:

bind-address = 127.0.0.1
mysqlx-bind-address = 127.0.0.1

Reinicia y comprueba:

sudo systemctl restart mysql
sudo ss -ltnp | grep -E ':3306|:33060'
sudo mysql -e "SHOW VARIABLES LIKE '%bind_address';"

Las dos variables deben valer 127.0.0.1, y ss debe mostrar esa dirección en los dos puertos. Si no usas el X Protocol, puedes desactivarlo del todo con la línea mysqlx = OFF en la misma sección.

¿Necesito un firewall si MySQL ya escucha en localhost?

Sí, como segunda capa. Una base de datos en 127.0.0.1 no recibe conexiones de fuera, porque el kernel solo entrega a esa dirección los paquetes que nacen en la propia máquina. El firewall te protege el día que alguien cambia bind-address y olvida volver a cambiarlo.

Debian no instala ufw por defecto, y las imágenes de cada proveedor de VPS son distintas. No lo supongas. Compruébalo:

command -v ufw || echo "ufw no está instalado"
sudo nft list ruleset

Si nft list ruleset no imprime nada, no hay reglas de nftables cargadas. Entonces cualquier puerto que escuche en una interfaz pública está abierto a internet. Si el comando nft no existe, tampoco hay reglas de nftables.

Si no tienes otro firewall configurado, ufw es el camino más corto:

sudo apt install -y ufw
sudo ufw allow 22/tcp
sudo ufw enable
sudo ufw status verbose

Permite SSH (Secure Shell) antes de ufw enable. La política por defecto de ufw para el tráfico entrante es deny, así que sin esa regla tu siguiente conexión SSH queda bloqueada. status verbose debe mostrar deny (incoming) y la regla de 22/tcp. No hay ninguna regla para el puerto 3306, y eso es lo correcto. Los fundamentos de ufw en un VPS explica cómo añadir más reglas sin cerrarte la puerta.

Si ya gestionas el firewall con nftables o con el panel de tu proveedor, no añadas ufw encima. Dos herramientas que escriben reglas a la vez hacen difícil saber qué regla decide. Basta con que ninguna regla acepte el puerto 3306.

Un caso aparte: si ejecutas MySQL en un contenedor Docker y publicas el puerto con -p 3306:3306, Docker escribe sus propias reglas de NAT (traducción de direcciones de red), y el puerto queda abierto aunque ufw status no lo muestre.

Crear un usuario para tu aplicación

No uses root desde la aplicación. Abre la consola con sudo mariadb o sudo mysql y ejecuta lo mismo en los dos servidores:

CREATE DATABASE app CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'app'@'localhost' IDENTIFIED BY 'una-clave-larga-y-aleatoria';
GRANT ALL PRIVILEGES ON app.* TO 'app'@'localhost';

Prueba la cuenta con mariadb -u app -p app en MariaDB, o mysql -u app -p app en MySQL. Debe pedir la contraseña y abrir la base app.

Acceso remoto sin abrir el puerto 3306

Si quieres usar un cliente gráfico desde tu ordenador, no abras el puerto. Usa un túnel SSH:

ssh -N -L 3307:127.0.0.1:3306 usuario@203.0.113.10

Mientras ese comando sigue abierto, tu cliente se conecta a 127.0.0.1, puerto 3307, en tu propio ordenador. SSH lleva el tráfico cifrado hasta el servidor, y la conexión llega a la base de datos desde 127.0.0.1. No necesitas una cuenta con host remoto ni una regla nueva en el firewall.

Si de verdad necesitas una conexión directa, por ejemplo desde otro servidor de aplicaciones, cambia tres cosas a la vez. Pon en bind-address la IP privada del servidor. Crea una cuenta para la IP exacta del cliente, como 'app'@'198.51.100.7', con REQUIRE SSL para exigir TLS (transport layer security). Y abre el puerto solo para esa IP:

sudo ufw allow from 198.51.100.7 to any port 3306 proto tcp

Actualizaciones de seguridad: quién te las envía

Con MariaDB, los parches llegan por trixie-security, como el resto de Debian. Si tienes unattended-upgrades activo, los aplica solo. Si sospechas que no corre, por qué unattended-upgrades no se ejecuta en Debian explica cómo comprobarlo.

Con MySQL de Oracle, el equipo de seguridad de Debian no interviene. Oracle publica sus correcciones en las Critical Patch Updates trimestrales (enero, abril, julio y octubre). sudo apt update && sudo apt upgrade instala la nueva versión menor dentro de tu serie. La configuración por defecto de unattended-upgrades en Debian solo acepta orígenes de Debian, así que no actualiza MySQL. Puedes añadir el origen de Oracle en /etc/apt/apt.conf.d/50unattended-upgrades: apt-cache policy, sin argumentos, muestra una línea release o=... por cada repositorio, y ese valor o= es el que necesitas. Si prefieres no automatizarlo, apunta en tu calendario las fechas de las Critical Patch Updates.

Errores frecuentes y qué significan

ERROR 1698 (28000): Access denied for user 'root'@'localhost'. Ejecutaste mysql -u root o mariadb -u root sin sudo. Root se autentica por el socket, y el plugin compara la cuenta con tu usuario de Linux. Usa sudo mariadb o sudo mysql. No le pongas contraseña a root solo para evitar este error: crea una cuenta para cada aplicación.

apt no encuentra mysql-server. Es lo normal en Debian 13 sin el repositorio de Oracle. Vuelve a la salida de apt-cache policy del principio. Si ya añadiste el repositorio, mira si apt update mostró errores.

apt update da un error de firma para repo.mysql.com. La clave que instaló tu mysql-apt-config no coincide con la que firma el repositorio hoy, normalmente porque el paquete es antiguo. Descarga el mysql-apt-config actual desde la página de Oracle e instálalo encima con sudo apt install ./ seguido del nombre del fichero.

ERROR 2003 (HY000): Can't connect to MySQL server on '203.0.113.10:3306' (111). El número entre paréntesis es el código de error del sistema. 111 significa «connection refused»: el paquete llegó, pero nadie escuchaba en esa dirección, normalmente porque bind-address es 127.0.0.1. 110 significa «connection timed out»: un firewall descarta el paquete por el camino. El cliente de MariaDB usa un texto algo distinto, pero el número se lee igual.

ERROR 1130 (HY000): Host '198.51.100.7' is not allowed to connect to this MySQL server. La conexión llegó al servidor, pero no existe una cuenta para ese host. Una cuenta es un par usuario@host, y 'app'@'localhost' no cubre conexiones remotas. MariaDB escribe «MariaDB server» al final del mensaje.

FAQ

¿Por qué apt instala MariaDB cuando pido MySQL en Debian?

El archivo estable de Debian no incluye MySQL de Oracle. A 1 de octubre de 2026, el paquete mysql-server solo existe en sid, la rama inestable. El metapaquete default-mysql-server depende de mariadb-server-compat, que depende de mariadb-server. Ejecuta apt-cache policy mysql-server default-mysql-server y apt-cache depends default-mysql-server para verlo en tu propio servidor.

¿Puedo instalar MySQL en Debian 12 igual que en Debian 13?

Sí. En Debian 12 «bookworm», default-mysql-server también instala MariaDB, en la serie 10.11. Para tener MySQL de Oracle, el camino es el mismo: el paquete mysql-apt-config de la página de descargas de MySQL. Oracle lista Debian 12 y Debian 13 como plataformas soportadas para MySQL 8.4 LTS y 9.7 LTS.

¿Qué versión de MySQL debo instalar desde el repositorio de Oracle?

Para una instalación nueva, a 1 de octubre de 2026, elige MySQL 9.7 LTS, que tiene soporte principal hasta abril de 2031. Elige 8.4 LTS solo si tu aplicación o un servidor con el que replicas lo exige. Evita MySQL 8.0, que ya está en Sustaining Support, y las versiones Innovation en producción.

¿Qué script de seguridad uso: mysql_secure_installation o mariadb-secure-installation?

Depende del servidor. Con MariaDB en Debian 13, usa sudo mariadb-secure-installation, que viene en el paquete mariadb-client. El nombre mysql_secure_installation está en otro paquete, mariadb-client-compat, y puede no estar instalado. Con MySQL de Oracle, usa sudo mysql_secure_installation.

¿Es seguro dejar MySQL escuchando en todas las interfaces?

No, salvo que lo necesites y lo protejas. El MySQL de Oracle escucha por defecto en todas las interfaces, en el puerto 3306 y en el 33060 del X Protocol. Fija bind-address y mysqlx-bind-address en 127.0.0.1, comprueba el resultado con sudo ss -ltnp, y usa un túnel SSH para conectarte desde fuera. La MariaDB de Debian ya viene con bind-address = 127.0.0.1.