Docker: Conectarse al servidor MySQL de tu máquina host

Hace unos días empecé a trabajar con Docker para un proyecto personal. Actualmente estoy acostumbrado a trabajar con Vagrant, así que le di la oportunidad a Docker para probar algo nuevo, ya que había leído muy buenos comentarios de esta herramienta.

Lo que voy a detallar a continuación es una nota mental para dejar registro de como finalmente logré conectarme desde un contenedor de Docker a mi servidor MySQL que tengo corriendo en mi máquina local (o host como llaman en el mundo Docker). Perdí muchas horas en esto y no quiero volver a pasar por lo mismo.

Docker es un poco más complejo de configurar, lo que asusta a muchos usuarios, pero existe algo llamado Docker Compose lo que es muy símil a un Vagrantfile y finalmente hace mucho más amigable la configuración. Luego de leer este y este tutorial, quedé listo para trabajar con Docker… casi.

En mi máquina de trabajo actual tengo levantado un ambiente de desarrollo, donde ya tengo instalado MySQL y quería ocupar este mismo servidor en Docker.

Espero que a alguien más le sirva esto. Aclarar que esto fue probado en Docker 1.13.1.

EL PASO A PASO

    1. Configurar MySQL para que escuche conexiones desde todas las IP

      Por defecto MySQL viene configurado para escuchar sólo conexiones locales. Podemos ejecutar el siguiente comando para ver nuestra configuración actual:

      SHOW GLOBAL VARIABLES LIKE 'bind_address'

      Por defecto, debería retornar 127.0.0.1 y necesitamos cambiar ese valor a 0.0.0.0. Con eso le damos acceso a cualquier IP para acceder al servicio.

      El cambio debe realizarse en el archivo de configuración de MySQL: my.cnf. La ubicación de este archivo puede variar dependiendo del sistema operativo.

      Abrimos ese archivo y buscamos la línea donde dice bind_address. Si está comentada la descomentamos, si no existe simplemente agregamos la variable, debe quedar así:

      bind-address = 0.0.0.0

      Reiniciamos el servicio y verificamos que el valor ahora esté en 0.0.0.0.

      Si estás trabajando en MacOS e instalaste MySQL con Homebrew debemos modificar otro archivo: /usr/local/Cellar/mysql/<version_mysql>/homebrew.mxcl.mysql.plist. Allí vas a encontrar que Homebrew al levantar el servicio, configura por parámetro el bind-address, así que el cambio lo debes hacer aquí. (Gracias)

    2. Dar permisos al usuario para conectarse remotamente

      En este punto ya tenemos acceso a MySQL desde cualquier IP, pero ahora resta darle los permisos al usuario de nuestra base de datos para poder acceder al servidor desde donde se encuentre. Para ello debemos ejecutar los siguientes comandos en MySQL:

      GRANT ALL PRIVILEGES ON base_de_datos_de_juanito.* TO 'juanito'@'%' IDENTIFIED BY 'password_de_juanito';
      FLUSH PRIVILEGES;

      Con ese comando estamos permitiendo que el usuario juanito pueda acceder a la base_de_dato_de_juanito desde cualquier host (indicado con el carácter %). Ten en cuenta que al final debe ir la clave de juanito y no la clave del usuario root.

    3. Configurar la IP de tu máquina host en el archivo docker-compose.yml

      Ahora solo resta que el contenedor sepa la IP de tu máquina (host) para poder utilizar MySQL. Para llegar a esta “solución” tuve que leer mucho y finalmente encontré este workaround.

        1. En tu archivo .bash_profile debemos configurar una variable de entorno donde se almacenará tu IP local:
          export DOCKERHOST="$(ifconfig | grep "inet " | grep -Fv 127.0.0.1 | awk '{print $2}')"

          Los invito a probar que efectivamente funcione. Cierren su terminal, vuelvan a abrirlo y escriban:

          echo $DOCKERHOST

          Deberían ver en pantalla la IP local de su máquina. Si no lo ven, deben buscar algún comando que les funciona en su máquina, ya que fue probado en MacOS.

          No cambien el nombre de la variable a DOCKER_HOST ya que Docker de forma interna hace uso de esta variable y no podrán levantar ningún contenedor. Me pasó y tuve que llegar al canal de IRC de ayuda de Docker para darme cuenta de mi error.

        2. Ahora configuramos nuestro docker-compose.yml para que el contenedor tenga conocimiento de esta información:
          version: "2.1"
          
          services:
              nginx:
                  build: ./nginx/
                  ports:
                      - 8080:80
                  volumes:
                      - ./../code:/code:ro
                  depends_on:
                      - php
              php:
                  build: ./php/
                  expose:
                      - 9000
                  volumes:
                      - ./../code:/code
                  extra_hosts:
                      - "dockerhost:$DOCKERHOST"
          

          Si se fijan bien, en nuestro contenedor php hemos hecho uso de extra_hosts, donde le indicamos al contenedor que el host dockerhost debe ser resuelto a nuestra IP local ($DOCKERHOST).

        3. Finalmente nos queda comprobar que efectivamente el contenedor sea capaz de resolver dockerhost a nuestra IP. Para ello podemos ingresar por consola y hacer un simple ping:
          ping dockerhost

          Deberíamos ver en consola nuestra IP. Todo bien. Ahora, cuando queramos configurar en nuestras aplicaciones el host MySQL, simplemente indicamos que es dockerhost, en vez de localhost o una IP cualquiera.

      Tengan en cuenta que el nombre dockerhost pudo haber sido cualquier otro, es solo algo referencial.

Se que se ve mucho trabajo para algo tan simple, pero me entretuvo y aprendí mucho de Docker y de su funcionamiento. ¿Solución simple?: haber configurado en mi proyecto PHP que MySQL se encontraba en mi IP local. Pero no era lo que buscaba, ya que por lo general uno no tiene IP estática, a menos que tengas acceso a la red y te la puedas configurar.

Anuncios

Deja un comentario (puedes utilizar Markdown)

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s