nginx Desde el interior de un contenedor Docker, ¿cómo me conecto al host local de la máquina?




8 Answers

Para macOS y Windows

Docker v 18.03 y superior (desde el 21 de marzo de 2018)

Use su dirección IP interna o conéctese al nombre de DNS especial host.docker.internal que se resolverá con la dirección IP interna que usa el host.

Soporte de Linux pendiente https://github.com/docker/for-linux/issues/264

MacOS con versiones anteriores de Docker

Docker para Mac v 17.12 a v 18.02

Igual que el anterior, pero use docker.for.mac.host.internal en docker.for.mac.host.internal lugar.

Docker para Mac v 17.06 a v 17.11

Igual que el anterior, pero usa docker.for.mac.localhost en docker.for.mac.localhost lugar.

Docker para Mac 17.05 e inferior

Para acceder a la máquina host desde el contenedor de la ventana acoplable, debe adjuntar un alias de IP a su interfaz de red. Puede enlazar cualquier IP que desee, solo asegúrese de no usarla para nada más.

sudo ifconfig lo0 alias 123.123.123.123/24

Luego, asegúrese de que su servidor esté escuchando la IP mencionada anteriormente o 0.0.0.0 . Si está escuchando en localhost 127.0.0.1 , no aceptará la conexión.

Luego simplemente apunte su contenedor de la ventana acoplable a esta IP y podrá acceder a la máquina host

Para probar puedes ejecutar algo como curl -X GET 123.123.123.123:3000 dentro del contenedor.

El alias se reiniciará en cada reinicio, así que cree un script de inicio si es necesario.

Solución y más documentación aquí: https://docs.docker.com/docker-for-mac/networking/#use-cases-and-workarounds

nginx docker reverse-proxy docker-networking

Entonces tengo un Nginx corriendo dentro de un contenedor docker, tengo un mysql corriendo en localhost, quiero conectarme al MySql desde mi Nginx. El MySql se ejecuta en localhost y no está exponiendo un puerto al mundo exterior, por lo que está vinculado en localhost, no en la dirección IP de la máquina.

¿Hay alguna manera de conectarse a este MySql o cualquier otro programa en localhost desde este contenedor docker?




Esto me funcionó en una pila NGINX / PHP-FPM sin tocar ningún código o red en la que la aplicación solo espera poder conectarse a localhost

Monte mysqld.sock desde el host al interior del contenedor.

Busque la ubicación del archivo mysql.sock en el host que ejecuta mysql:
netstat -ln | awk '/mysql(.*)?\.sock/ { print $9 }'

Monte ese archivo a donde se espera en la ventana acoplable:
docker run -v /hostpath/to/mysqld.sock:/containerpath/to/mysqld.sock

Posibles ubicaciones de mysqld.sock:

/tmp/mysqld.sock
/var/run/mysqld/mysqld.sock 
/var/lib/mysql/mysql.sock
/Applications/MAMP/tmp/mysql/mysql.sock # if running via MAMP



Solución para Windows 10

Docker Community Edition 17.06.0-ce-win18 2017-06-28 (estable)

Puede usar el nombre DNS del host docker.for.win.localhost para resolver la IP interna. (Advertencia algunas fuentes mencionan windows pero debería ser win )

Visión general
Necesitaba hacer algo similar, es decir, conectar desde mi contenedor Docker a mi host local, que ejecutaba el Azure Storage Emulator y el CosmosDB Emulator .

El Azure Storage Emulator escucha de forma predeterminada el 127.0.0.1 , mientras que también puede cambiar la IP de su límite, estaba buscando una solución que funcionara con la configuración predeterminada.

Esto también funciona para conectar desde mi contenedor Docker a SQL Server e IIS , ambos ejecutándose localmente en mi host con la configuración de puerto predeterminada.




Edit: terminé haciendo un prototipo del concepto en GitHub. Echa un vistazo a: https://github.com/sivabudh/system-in-a-box

Primero, mi respuesta está dirigida a 2 grupos de personas: aquellos que usan una Mac y aquellos que usan Linux.

El modo de red del host no funciona en una Mac. Debe utilizar un alias de IP, consulte: https://.com/a/43541681/2713729

¿Qué es un modo de red host? Consulte: https://docs.docker.com/engine/reference/run/#/network-settings

En segundo lugar, para aquellos de ustedes que están usando Linux (mi experiencia directa fue con Ubuntu 14.04 LTS y pronto estaré actualizando a 16.04 LTS en producción), , puede hacer que el servicio que se ejecuta dentro de un contenedor Docker se conecte a los servicios de localhost el host Docker (por ejemplo, su computadora portátil).

¿Cómo?

La clave es cuando ejecutas el contenedor Docker, debes ejecutarlo con el modo de host . El comando se ve así:

docker run --network="host" -id <Docker image ID>

Cuando realice un ifconfig (necesitará apt-get install net-tools su contenedor para que el ifconfig sea ​​invocable) dentro de su contenedor, verá que las interfaces de red son las mismas que las del host Docker (por ejemplo, su computadora portátil ).

Es importante tener en cuenta que soy un usuario de Mac, pero ejecuto Ubuntu bajo Parallels, por lo que usar una Mac no es una desventaja. ;-)

Y así es como se conecta el contenedor NGINX al MySQL que se ejecuta en un host localhost .




No estoy de acuerdo con la respuesta de Thomasleveil.

Hacer que mysql se enlace a 172.17.42.1 evitará que otros programas utilicen la base de datos en el host para alcanzarlo. Esto solo funcionará si todos los usuarios de la base de datos están acoplados.

Hacer que mysql se una a 0.0.0.0 abrirá el db al mundo exterior, lo que no solo es algo muy malo, sino también contrario a lo que el autor de la pregunta original quiere hacer. Dice explícitamente "El MySql se está ejecutando en localhost y no está exponiendo un puerto al mundo exterior, por lo que está vinculado a localhost"

Para responder el comentario de ivant.

"¿Por qué no enlazar mysql a docker0 también?"

Esto no es posible. La documentación de mysql / mariadb dice explícitamente que no es posible enlazar a varias interfaces. Solo se puede enlazar a 0, 1 o todas las interfaces.

Como conclusión, NO he encontrado ninguna forma de llegar a la base de datos (solo localhost) en el host desde un contenedor docker. Eso definitivamente parece ser un patrón muy común, pero no sé cómo hacerlo.




Los CGroups y los espacios de nombres están jugando un papel importante en el ecosistema de contenedores.

El espacio de nombres proporciona una capa de aislamiento. Cada contenedor se ejecuta en un espacio de nombres separado y su acceso está limitado a ese espacio de nombres. El Cgroups controla la utilización de recursos de cada contenedor, mientras que Namespace controla lo que un proceso puede ver y acceder al recurso respectivo.

Aquí está la comprensión básica del enfoque de solución que podría seguir,

Usar el espacio de nombres de red

Cuando un contenedor se genera fuera de la imagen, se define y crea una interfaz de red. Esto le da al contenedor una dirección IP y una interfaz únicas.

$ docker run -it alpine ifconfig

Al cambiar el espacio de nombres a host, las redes de cotainers no permanecen aisladas en su interfaz, el proceso tendrá acceso a la interfaz de red de las máquinas host.

$ docker run -it --net=host alpine ifconfig

Si el proceso escucha en los puertos, se escucharán en la interfaz del host y se asignarán al contenedor.

Usar el espacio de nombres PID Al cambiar el espacio de nombres Pid, ​​un contenedor puede interactuar con otros procesos más allá de su alcance normal.

Este contenedor se ejecutará en su propio espacio de nombres.

$ docker run -it alpine ps aux

Al cambiar el espacio de nombres al host, el contenedor también puede ver todos los demás procesos que se ejecutan en el sistema.

$ docker run -it --pid=host alpine ps aux

Compartir espacio de nombres

Esta es una mala práctica para hacer esto en producción porque está saliendo del modelo de seguridad del contenedor, lo que podría abrirse a vulnerabilidades y un fácil acceso a la escucha. Esto es solo para las herramientas de depuración y para subestimar las lagunas en la seguridad de los contenedores.

El primer contenedor es el servidor nginx. Esto creará una nueva red y espacio de nombres de proceso. Este contenedor se vinculará al puerto 80 de la interfaz de red recién creada.

$ docker run -d --name http nginx:alpine

Otro contenedor ahora puede reutilizar este espacio de nombres,

$ docker run --net=container:http mohan08p/curl curl -s localhost

Además, este contenedor puede ver la interfaz con los procesos en un contenedor compartido.

$ docker run --pid=container:http alpine ps aux

Esto le permitirá otorgar más privilegios a los contenedores sin cambiar o reiniciar la aplicación. De la misma manera, puede conectarse a mysql en el host, ejecutar y depurar su aplicación. Pero, no es recomendable ir por este camino. Espero eso ayude.




Para la máquina de Windows: -

Ejecute el siguiente comando para exponer el puerto de la ventana acoplable aleatoriamente durante el tiempo de construcción

$docker run -d --name MyWebServer -P mediawiki

En la lista de contenedores anterior puede ver el puerto asignado como 32768. Intente acceder

localhost:32768 

Puedes ver la página de mediawiki.




Ninguna de las respuestas funcionó para mí cuando usé Docker Toolbox en Windows 10 Home, pero 10.0.2.2 sí, ya que docker-toolbox usa VirtualBox, que expone al host a la VM en esta dirección.




Related