问题描述
在多阶段构建的过程中,用户想要在Dockerfile中运行一些测试。这些测试试图在Dockerfile的RUN命令中连接到localhost上的特定端口(该端口在宿主机上是可用的)。然而,似乎它们无法在Dockerfile的RUN命令中连接成功。用户想知道是否有可能在构建过程中实现这样的连接,如果可以,应该如何实现?在构建时可以进行外部连接(用于下载依赖等),但在运行时可以进行回环连接。
以下是用户的Dockerfile示例:
FROM python:3.7-alpine as tester
COPY . .
RUN python -m unittest discover
下面是用于检查连接的Python代码示例:
def setUp():
timeout = 120.0
port = 15903
host = 'localhost'
start_time = time.perf_counter()
while True:
try:
with socket.create_connection((host, port), timeout=timeout):
break
except OSError as ex:
time.sleep(1.0)
if time.perf_counter() - start_time >= timeout:
raise TimeoutError('Waited too long for the port {} on host {} to start accepting connections.'.format(port, host)) from ex
解决方案
以下解决方案考虑了Docker版本和操作系统的不同情况。
使用宿主机IP地址进行通信
从容器的角度来看,localhost
是容器本身。如果你想要与宿主机通信,你需要知道宿主机的IP地址。根据操作系统和Docker配置的不同,这个IP地址可能会有所不同。
- 对于Mac用户,从18.03版本开始,推荐使用
host.docker.internal
。
以下是一个在Mac上从容器与Docker主机通信的示例:
# Dockerfile
FROM python:3.7-alpine
RUN ping host.docker.internal -c 4
运行上述Dockerfile后的输出示例:
sending build context to Docker daemon 562.7kB
Step 1/2 : FROM python:3.7-alpine
---> a93594ce93e7
Step 2/2 : RUN ping host.docker.internal -c 4
---> Running in 54ce465f7386
PING host.docker.internal (192.168.65.2): 56 data bytes
64 bytes from 192.168.65.2: seq=0 ttl=37 time=0.735 ms
64 bytes from 192.168.65.2: seq=1 ttl=37 time=1.898 ms
64 bytes from 192.168.65.2: seq=2 ttl=37 time=0.720 ms
64 bytes from 192.168.65.2: seq=3 ttl=37 time=0.643 ms
--- host.docker.internal ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 0.643/0.999/1.898 ms
Removing intermediate container 54ce465f7386
---> b2f32c26a135
Successfully built b2f32c26a135
注意事项
- 使用宿主机IP地址进行通信是一个可行的方法,但在不同的操作系统和Docker版本中,使用的方式可能会有所不同。因此,在使用这种方法时需要进行相关的测试和验证,以确保其在你的环境中正常工作。
总结
在Docker构建过程中连接到宿主机是可能的,但需要注意在不同操作系统和Docker版本中使用的方法可能会有所不同。你可以通过获取宿主机的IP地址来实现这一目标,但需要注意它在不同环境中的适用性。
正文完