Cómo implementar MySQL/MariaDB en Docker con almacenamiento de datos persistente
Introducción
En este tutorial, implementas un contenedor de base de datos MySQL o MariaDB usando Docker con almacenamiento de datos persistente. Ejecutar bases de datos en contenedores simplifica la implementación, el control de versiones y la portabilidad entre entornos. Al final de este tutorial, tendrás una instancia de MySQL o MariaDB lista para producción ejecutándose en Docker con los datos almacenados de manera segura fuera del contenedor.
Requisitos previos
Público objetivo: Administradores de sistemas intermedios
Tiempo estimado para completar: ~30–45 minutos
Sistema Operativo
- Ubuntu 24.04 LTS (probado)
- También compatible con: Ubuntu 22.04 LTS, Debian 12 / 13
Requisitos de Software
- Docker 24.0.6 o posterior
- Docker Compose v2 (incluido con instalaciones modernas de Docker)
Verifica tu versión de Docker:
docker --version
Salida esperada: Docker version 24.0.6, build ed223bc
Verifica la versión de Docker Compose:
docker compose version
Salida esperada: Docker Compose version v5.1.0
Si no tienes Docker instalado, lo instalarás durante el Paso 1.
Requisitos de Hardware
- Mínimo 2 GB de RAM
- Al menos 10 GB de espacio libre en disco
Requisitos de Red
- Puerto 3306 disponible (puerto predeterminado de MySQL/MariaDB)
- Firewall configurado para permitir acceso solo si se requieren conexiones externas
Permisos
- Un usuario no root con privilegios
sudo - Usuario agregado al grupo
docker(recomendado)
Conocimientos Asumidos
- Conceptos básicos de Docker (imágenes, contenedores, volúmenes)
- Comodidad con operaciones en línea de comandos
Paso 1: Instalar y Verificar Docker
Si Docker no está instalado, instálalo:
sudo apt update && sudo apt upgrade -y && sudo apt install curl
curl -sSL https://get.docker.com/ | CHANNEL=stable bash
sudo apt install docker-ce docker-compose-plugin -y
Habilita y inicia Docker:
sudo systemctl enable docker
sudo systemctl start docker
Verifica que Docker esté ejecutándose:
sudo systemctl status docker
Resultado esperado: El estado del servicio Docker muestra active (running).
Agrega tu usuario al grupo docker para evitar usar sudo al usar Docker:
sudo usermod -aG docker <YOUR_USERNAME>
newgrp docker
Paso 2: Crear un Directorio de Datos Persistente
Un montaje de enlace mapea un directorio del sistema host directamente en un contenedor, haciéndolo accesible dentro del sistema de archivos del contenedor.
Crea un directorio para los datos de la base de datos y establece los permisos adecuados:
mkdir -p ~/mysql-docker/data
chmod 750 ~/mysql-docker/data
Este directorio almacenará los archivos de la base de datos fuera del contenedor.
Sin almacenamiento persistente, todos los datos de la base de datos se pierden cuando se elimina el contenedor.
Paso 3: Crear una Configuración de Docker Compose
Navega a tu directorio de proyecto:
cd ~/mysql-docker
Crea un archivo docker-compose.yml:
nano docker-compose.yml
Agrega la siguiente configuración (ejemplo de MySQL):
services: mysql: image: mysql:8.0.36 container_name: mysql-server restart: unless-stopped environment: MYSQL_ROOT_PASSWORD: <YOUR_STRONG_ROOT_PASSWORD> MYSQL_DATABASE: appdb MYSQL_USER: appuser MYSQL_PASSWORD: <YOUR_STRONG_USER_PASSWORD> ports: - "3306:3306" volumes: - ./data:/var/lib/mysql
Alternativa de MariaDB — si prefieres MariaDB, usa:
services: mariadb: image: mariadb:11.3 container_name: mariadb-server restart: unless-stopped environment: MARIADB_ROOT_PASSWORD: <YOUR_STRONG_ROOT_PASSWORD> MARIADB_DATABASE: appdb MARIADB_USER: appuser MARIADB_PASSWORD: <YOUR_STRONG_USER_PASSWORD> ports: - "3306:3306" volumes: - ./data:/var/lib/mysql
Importante: Nunca codifiques contraseñas reales en el control de versiones. Usa variables de entorno o un archivo .env en producción. Reemplaza <YOUR_STRONG_USER_PASSWORD> y <YOUR_STRONG_ROOT_PASSWORD> con tus contraseñas seguras.
Paso 4: Iniciar el Contenedor de la Base de Datos
Ejecuta:
docker compose up -d
Salida esperada:
- Docker descarga la imagen (si no está ya descargada)
- El contenedor se inicia en modo separado
Verifica el estado del contenedor:
docker ps
Salida esperada:
CONTAINER ID IMAGE STATUS PORTS abc123def456 mysql:8.0.36 Up 10 seconds 0.0.0.0:3306->3306/tcp
Paso 5: Verificar la Funcionalidad de la Base de Datos
Conectar al Contenedor
Para el contenedor de MySQL ejecuta:
docker exec -it mysql-server mysql -u root -p
Para el contenedor de MariaDB ejecuta:
docker exec -it mariadb-server mysql -u root -p
Ingresa tu contraseña de root.
Resultado esperado: Aparece el prompt de MySQL: mysql>
Verificar Bases de Datos
SHOW DATABASES;
Deberías ver:
- appdb
- information_schema
- mysql
- performance_schema
- sys
EXIT;
Probar la Persistencia de Datos
Crea una tabla de prueba
docker exec -it mysql-server mysql -u root -p
Dentro del shell de MySQL ingresa los siguientes comandos:
USE appdb;
CREATE TABLE test_table (id INT PRIMARY KEY);
EXIT;
Detén y elimina el contenedor
docker compose down
Reinicia el contenedor
docker compose up -d
Verifica que la tabla aún exista
docker exec -it mysql-server mysql -u root -p
Dentro del shell de MySQL ingresa los siguientes comandos:
USE appdb;
SHOW TABLES;
Resultado esperado: Aparece test_table. Esto confirma que el almacenamiento persistente está funcionando.
Paso 6: Asegurar la Implementación
Restringir el Acceso Externo
Si el acceso a la base de datos solo se necesita internamente, modifica los puertos en docker-compose.yml:
ports: - "127.0.0.1:3306:3306"
Reinicia:
docker compose down
docker compose up -d
Importante: Evita exponer el puerto 3306 públicamente a menos que sea absolutamente necesario.
Usar un Archivo .env
Crea .env:
nano .env
Ejemplo:
MYSQL_ROOT_PASSWORD=<YOUR_STRONG_ROOT_PASSWORD> MYSQL_PASSWORD=<YOUR_STRONG_USER_PASSWORD>
Referencia en docker-compose.yml:
environment: MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} MYSQL_PASSWORD: ${MYSQL_PASSWORD}
Verificación
Puedes confirmar que todo funciona correctamente:
- Ejecutando
docker ps— el contenedor está Up - Conectándote a través de la CLI de MySQL — el inicio de sesión tiene éxito
- Reiniciando el contenedor — los datos persisten
- Verificando los registros:
docker logs mysql-server
Entradas de registro esperadas: "ready for connections".
Revertir Cambios
Para detener y eliminar el contenedor:
docker compose down
Para eliminar datos persistentes:
Importante: Esto elimina permanentemente todos los datos de la base de datos.
rm -rf ~/mysql-docker/data
Para desinstalar Docker:
sudo apt remove docker-ce docker-compose-plugin -y
Solución de Problemas
El Contenedor No Inicia
Verifica los registros:
docker logs mysql-server
Causas comunes:
- Contraseña débil rechazada
- Puerto 3306 ya en uso
Verifica el uso del puerto:
sudo ss -tulnp | grep 3306
Errores de Permiso
Si ves errores de permiso denegado:
sudo chown -R 999:999 ~/mysql-docker/data
999 es comúnmente el ID de usuario del contenedor MySQL.
Conclusión y Próximos Pasos
Has implementado con éxito MySQL o MariaDB en Docker con almacenamiento persistente. La base de datos ahora se ejecuta en un contenedor aislado mientras almacena datos de manera segura en el sistema host.
Próximos pasos:
- Configurar copias de seguridad automáticas
- Implementar replicación para alta disponibilidad
- Integrar con contenedores de aplicaciones
- Agregar monitoreo con Prometheus y Grafana