MySQL 8 en Docker de manera fácil y para toda la familia
Tags: mysql, docker, castellano, spanish
Published: 2019-05-06 10:34:35

---
title: MySQL 8 en Docker de manera fácil y para toda la familia
published: true
description: Como crear una instalación de MySQL 8 dentro de Docker que nos permitirá disponer de una versión alternativa a la del sistema operativo
cover_image: https://thepracticaldev.s3.amazonaws.com/i/nddjk7b7hfxksbto9j9l.jpeg
tags: MySQL, Docker, Castellano, Spanish
---

Estaba yo por aquí con mi feliz vida de programador y usuario Linux (GNU/Linux para los puristas) cuando de repente se muestra ante mí una situación que no sucede de manera habitual (dentro de mi bonito mundo): Necesitar dos versiones diferentes de un mismo servicio corriendo al mismo tiempo y sin entrar en conflicto.

Como usuario Linux siempre he tenido opciones sencillas para disponer de versiones de cierto software según necesidades, o bien no depender de versiones.

Servicios como Apache, nginx o Redis, con tener siempre la última ya vas servido. Otros como PHP o PostgreSQL puedes instalar todas las versiones que quieras sin que entren en conflicto entre sí, pero con MySQL no hay esa posibilidad "sencilla".

Para un nuevo proyecto necesitaba MySQL 8 ya que dispone de muchas mejoras en funcionalidades de geoposicionamiento, a parte de un mejor rendimiento en general cuando se trabaja con gran cantidad de datos, así que finalmente opté por la vía Docker.

Si no te metes en fregaos, es bastante más sencillo de lo que parece :)

Estos son los pasos a seguir:

```bash
# Instalamos los paquetes necesarios desde los repositorios oficiales de Ubuntu
$> sudo apt install docker.io

# Iniciamos el servicio
$> sudo systemctl start docker

# Activamos Docker al inicio del sistema
$> sudo systemctl enable docker

# Descargamos la imagen de MySQL
$> sudo docker pull mysql/mysql-server

# Creamos un volumen para almacenar los datos de manera persistente
# La localización será /var/lib/docker/volumes/mysql-8-data
$> sudo docker volume create mysql-8-data

# Iniciamos la instancia con la última versión de MySQL 8
# Mapeamos el puerto 3307 de nuestra máquina para 3306 de Docker
# Asignamos el volumen anterior para que las bases de datos sean persistentes
$> sudo docker run \
    -p 3307:3306 \
    -v mysql-8-data:/var/lib/mysql \
    --name mysql-8 \
    --restart always \
    -d mysql/mysql-server:latest

# Esperamos unos segundos y veremos la contraseña que se genera durante la instalación
$> sudo docker logs mysql-8 2>&1 | grep GENERATED
[Entrypoint] GENERATED ROOT PASSWORD: exTeNg0L9uMuquwWyP4DaebPAdr

# Accedemos por bash de Docker a la instalación
$> sudo docker exec -it mysql-8 bash

# Nos autenticamos en MySQL usando las credenciales de los logs (exTeNg0L9uMuquwWyP4DaebPAdr)
bash-4.2# mysql -uroot -p

# Creamos un usuario root para conexión externa a Docker con contraseña diferente
mysql> CREATE USER 'root'@'%' IDENTIFIED BY '!dC^:kI4*wT:|UE';
ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement.

# Ups! no podemos, debemos actualizar primero nuestro usuario y mantenemos la contraseña
mysql> ALTER USER USER() IDENTIFIED BY 'exTeNg0L9uMuquwWyP4DaebPAdr';
Query OK, 0 rows affected (0.03 sec)

# Ahora sí, creamos un usuario root para conexión externa a Docker con contraseña diferente
mysql> CREATE USER 'root'@'%' IDENTIFIED BY '!dC^:kI4*wT:|UE';
Query OK, 0 rows affected (0.04 sec)

# Le asignamos los privilegios de puto amo
mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'@'%';
Query OK, 0 rows affected (0.03 sec)

# Creamos la base de datos de nuestro proyecto
mysql> CREATE DATABASE `project` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
Query OK, 1 row affected (0.06 sec)

# Creamos el usuario con el que nos autenticaremos en ella desde nuestra aplicación
mysql> CREATE USER 'project'@'%' IDENTIFIED WITH mysql_native_password BY '*43i0;l+6=7:*lA';
Query OK, 0 rows affected (0.04 sec)

# Le asignamos los permisos
mysql> GRANT ALL PRIVILEGES ON `project`.* TO 'project'@'%';
Query OK, 0 rows affected (0.02 sec)

mysql> exit

bash-4.2# exit

# Probamos la conexión desde fuera de Docker con la contraseña de usuario (*43i0;l+6=7:*lA)
# Recuerda indicar el puerto de esta instalación con -P3307
$> mysql --protocol=tcp -P3307 -uproject -p project
```

Tal y como indica @frandieguez, podemos pasarle directamente los parámetros a MySQL para comenzar con unos ya preestablecidos por nosotros, simplemente hay que lanzar `docker run` de la siguiente manera:

```bash
$> sudo docker run \
    -p 3307:3306 \
    -v mysql-8-data:/var/lib/mysql \
    -e MYSQL_ROOT_PASSWORD=XXXX -e MYSQL_USER=XXXX -e MYSQL_DATABASE=XXXX \
    --name mysql-8 \
    --restart always \
    -d mysql/mysql-server:latest \

```

Si todo ha ido bien (que debería) pues ya tenemos una instancia Docker en nuestro equipo/servidor que nos provee de MySQL 8.

Si necesitas toquetear la configuración de MySQL no podrás hacerlo directamente desde `docker shell` ya que no dispone de editor.

La solución más sencilla (para mí) es la siguiente:

```bash
# Copiamos el fichero de configuración desde el contenedor a nuestro equipo
$> sudo docker cp mysql-8:/etc/my.cnf my.cnf

# Editamos la configuración a nuestro gusto
$> sudo vi my.cnf

# Pasamos de nuevo el fichero al contenedor
$> sudo docker cp my.cnf mysql-8:/etc/my.cnf

# Reiniciamos el contenedor
$> sudo docker restart mysql-8
```

Así ya tendremos nuestro MySQL totalmente customizado.

Enjoy!