我有一个Nginx在码头集装箱里运行。我在主机系统上运行了MySql。我想从我的容器中连接到MySql。MySql仅绑定到本地主机设备。
是否有任何方法可以从这个docker容器连接到这个MySql或本地主机上的任何其他程序?
这个问题与“如何从docker容器中获取docker主机的IP地址”不同,因为docker主机IP地址可以是网络中的公共IP或私有IP,而这些IP可能在docker容器内无法访问(如果托管在AWS或其他地方,我指的是公共IP)。即使你有docker主机的IP地址,这并不意味着你可以从容器内连接到docker主机,因为你的docker网络可能是overlay、host、bridge、macvlan、none等,这限制了该IP地址的可达性。
这在NGINX/PHP-FPM堆栈上对我有效,而无需接触任何代码或网络,应用程序只是希望能够连接到本地主机
将mysqld.sock从主机装载到容器内部。
在运行mysql的主机上查找mysql.sock文件的位置:netstat-ln|awk'/mysql(.*)?\。袜子/{打印$9}'
将该文件装载到docker中预期的位置:docker运行-v/hostpath/to/mysqld.sock:/containerpath/to/mysqld.sock
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
我做了一个类似于上述帖子的黑客,获取本地IP以映射到容器中的别名(DNS)。主要问题是使用一个在Linux和OSX中都有效的简单脚本动态获取主机IP地址。我在两种环境中都使用了这个脚本(即使在配置了“$LANG”!=“en_*”的Linux发行版中也是如此):
ifconfig | grep -E "([0-9]{1,3}\.){3}[0-9]{1,3}" | grep -v 127.0.0.1 | awk '{ print $2 }' | cut -f2 -d: | head -n1
因此,使用Docker Compose,完整的配置将是:
启动脚本(docker run.sh):
export DOCKERHOST=$(ifconfig | grep -E "([0-9]{1,3}\.){3}[0-9]{1,3}" | grep -v 127.0.0.1 | awk '{ print $2 }' | cut -f2 -d: | head -n1)
docker-compose -f docker-compose.yml up
docker-compose.yml文件:
myapp:
build: .
ports:
- "80:80"
extra_hosts:
- "dockerhost:$DOCKERHOST"
然后改变http://localhost到http://dockerhost在您的代码中。
有关如何定制DOCKERHOST脚本的更高级指南,请阅读本文并解释其工作原理。
这不是对实际问题的回答。这就是我解决类似问题的方法。解决方案完全来自:定义Docker容器网络,以便容器可以通信。感谢Nic Raboy
这里留给其他可能希望在一个容器和另一个容器之间进行REST调用的人。回答问题:在docker环境中使用什么来代替localhost?
了解您的网络看起来像docker网络
创建一个新的网络docker网络创建-d我的网络
启动第一个容器docker运行-d-p 5000:5000--network=“my net”--name“first_container”<MyImage1:v0.1>
查看第一个集装箱码头工人检查first_container的网络设置。“网络”:应该有“我的网”
启动第二个容器docker运行-d-p 6000:6000--network=“my net”--name“second_container”<MyImage2:v0.1>
检查第二个集装箱码头的网络设置,检查second_container。“网络”:应该有“我的网”
ssh到第二个容器docker exec-it secondcontainer sh或docker exec-it secondtainer bash中。
在第二个容器内部,可以通过ping first_container ping第一个容器。此外,您的代码调用如http://localhost:5000可以替换为http://first_container:5000
主机上的服务器正在监听端口5000;它将从主机发回一个字符串响应作为响应
echo“主机响应”|nc-l-p 5000
docker默认在网桥模式下运行(这比在主机网络模式下运行更安全);docker中的进程获取主机上第一个网络接口的ipv4地址,该地址不是127.0.0.1;这个ipv4地址通过环境变量HOSTIP传递给docker;在docker内部有一个nc命令,该命令连接到主机ip和端口5000上的服务器;该命令还读取服务器的响应。
HOST=$(ifconfig|grep“inet”|grep-v 127.0.0.1|awk“{print$2}”| head-1|sed-n‘s/[^0-9]*\([0-9\.]*\)/\1/p');docker run-e HOSTIP=“${HOST}”--rm-it alpine/bin/sh-c'echo“来自容器的问候语”|nc$HOSTIP 5000-v'
计算第一个列出接口的ipv4地址的表达式在osx和linux上确实有效:
HOST=$(ifconfig|grep“inet”|grep-v 127.0.0.1|awk“{print$2}”| head-1|sed-n‘s/[^0-9]*\([0-9\.]*\)/\1/p')
让它更通用:您可以在另一个docker容器中运行服务器,如下所示:
docker run--expose 5000-p:5000:5000--rm-it alpine/bin/sh-c'echo“来自主机的响应”|nc-l-p 5000'
--暴露5000码头集装箱可以接受端口5000上的连接
-p:5000:5000主机端的docker引擎监听任何接口上的端口5000,并将连接转发到容器网络(nc正在运行)的端口5000。