在Dockerfile中拒绝连接,但在Dockerfile中执行时不拒绝

时间:2020-10-26 14:13:51

标签: docker docker-compose dockerfile

我有一个调用本地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

1 个答案:

答案 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_wheelpip wheel保留在那里的依赖项,则可以COPY .whl文件进入图像并直接安装。如果它们全部来自同一源代码树,则可以进行多阶段构建,在早期构建阶段,仅构建库也可以工作。)