我有一个调用本地docker容器服务器的命令。
我使用docker-compose run name_of_service /bin/bash
来执行图像,然后从那里调用下面的命令按预期进行。
pip install --trusted-host pypi --extra-index-url http://pypi:8000 -r requirements.txt
但是在Dockerfile中运行几乎相同的命令会导致重试错误
RUN pip install --trusted-host pypi --extra-index-url http://pypi:8000 -r requirements.txt --user
WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.HTTPConnection object at 0x7f54bac2dad0>: Failed to establish a new connection: [Errno -2] Name or service not known')': /custom-utils/
这两项服务都在一个docker-compose.yml
中Yaml
service:
image: service:20.10.1
build:
context: platform
dockerfile: service/Dockerfile
depends_on:
- api
- pypi
environment:
PORT: "8088"
ports:
- "8088:8088"
volumes:
- some_location_of_source
restart: always
pypi:
image: pypi:20.10.1
build:
context: services/pypi
dockerfile: Dockerfile
environment:
PORT: "8000"
expose:
- "8000"
ports:
- "8000:8000"
volumes:
- some_location_of_source
答案 0 :(得分:1)
Dockerfile RUN
指令永远无法对其他服务进行网络调用,即使在同一docker-compose.yml
文件中也是如此。您需要安排软件包服务器在“其他地方”运行(即使在Docker中但单独启动也可以)。
在技术层面上有两个问题。 Compose大致假设所有映像构建都在启动任何容器之前发生,因此无法要求pypi
服务在构建service
映像之前启动(depends_on:
不影响构建阶段)。映像构建也未连接到Compose创建的Docker网络,因此它们无法执行解析容器主机名之类的操作;这将导致您遇到的特定错误。
将其拆分为两个单独的Compose YAML文件可能是可行的,一个用于软件包服务器,一个用于主要服务。您可以启动软件包服务器;然后docker-compose build
主要服务;然后停止打包服务器。由于您已经发布了ports:
,因此可以通过主机的IP地址之一访问软件包服务器。或者,如果您使用的是MacOS或Windows主机,则使用特殊的主机名host.docker.internal
;或者使用From inside of a Docker container, how do I connect to the localhost of the machine?中描述的一种技术。
RUN pip install \
--extra-index-url http://host.docker.internal:8000 \
-r requirements.txt
(取决于此软件包服务器中的确切位置,您可能根本不需要它。如果您python setup.py bdist_wheel
或pip wheel
保留在那里的依赖项,则可以COPY
.whl
文件进入图像并直接安装。如果它们全部来自同一源代码树,则可以进行多阶段构建,在早期构建阶段,仅构建库也可以工作。)