Docker容器如何连接到主机

43次阅读
没有评论

问题描述

在使用Docker容器时,遇到了一个问题:他想要在容器内部连接到主机(他正在Ubuntu上运行)。他尝试了几种解决方案,包括添加extra_hosts: host.docker.internal:host-gateway,但仍然无法建立连接。他是通过docker-compose up命令运行Docker的。
例如,当他在容器内运行脚本requests.get("http//:host.docker.internal:8000")时,会收到以下错误:

requests.exceptions.ConnectionError: HTTPConnectionPool(host='localhost', port=8000): Max retries exceeded with url: / (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7f18ac13dd90>: Failed to establish a new connection: [Errno 111] Connection refused'))

这是他的docker-compose.yml文件:

version: 3.7
services:
  web:
    container_name: schedule_model_service-api
    build: .
    ports:
      - "8001:8001"
    command: startserver
    volumes:
      - ./:/app
    env_file:
      - .env
    depends_on:
      - postgres
      - redis
    extra_hosts:
    - "host.docker.internal:host-gateway"
  worker:
    container_name: schedule_model_service-worker
    build: .
    command: celeryworker
    volumes:
      - ./:/app
    env_file:
      - .env
    depends_on:
      - web
      - postgres
      - redis
  redis:
    container_name: schedule_model_service-redis
    image: redis:6.2.6
    volumes:
      - ./docker-data/redis:/var/lib/redis
    env_file:
      - .env
    restart: on-failure
  postgres:
    container_name: schedule_model_service-db
    image: postgres:14.1
    volumes:
      - ./docker-data/postgresql:/var/lib/postgresql/data
    env_file:
      - .env
    restart: on-failure

解决方案

请注意以下操作注意版本差异及修改前做好备份。

方案1

如果容器需要连接到主机或远程服务,你需要知道主机的IP地址或域名。任何其他的解决方法只适用于你的笔记本电脑或者只是用于学术目的,在真实的场景和真实的用户中是无效的。例如,AWS中的容器需要连接到Azure的MySQL。
在你的情况下,你需要获取主机的本地IP地址。你可以在docker-compose up之前获取IP地址,如下所示:

export MACHINE_HOST_IP=$(hostname -I | awk '{print $1}')
docker-compose up ...

然后,在你的compose文件中使用这个值。例如,如果你的主机上有一个MySQL数据库,你的容器需要连接到它,你可以使用以下配置:

version: '3.2'
services:
  wordpress:
    environment:
      DB_HOST : ${MACHINE_HOST_IP}:3306
      DB_USER : usr_wordpress

请参考以下链接进行进一步了解:
https://stackoverflow.com/questions/52173352/what-is-the-difference-between-publishing-808080-and-80808080-in-a-docker-run/52213178#52213178
https://stackoverflow.com/questions/63136530/how-to-connect-api-with-web-spa-through-docker/63207679#63207679

方案2

问题可能是你在requests.get("http//:host.docker.internal:8000")中多了一个冒号。应该是requests.get("http//host.docker.internal:8000")
你可能遇到了requests URL解析的一个bug;从异常消息中可以看出,它试图连接到localhost:8000,而更合理的做法应该是报告URL格式错误。

正文完