【问题标题】:Docker cannot connect application to MySQLDocker 无法将应用程序连接到 MySQL
【发布时间】:2017-07-17 23:14:53
【问题描述】:

我正在尝试运行依赖于 mysql 的集成测试(在 python 中)。目前它们依赖于本地运行的 SQL,但我希望它们依赖于在 docker 中运行的 MySQL。

Dockerfile的内容:

FROM continuumio/anaconda3:4.3.1
WORKDIR /opt/workdir
ADD . /opt/workdir
RUN python setup.py install

Docker Compose 的内容:

version: '2'

services:
   mysql:
     image: mysql:5.6
     container_name: test_mysql_container
     environment:
       - MYSQL_ROOT_PASSWORD=test
       - MYSQL_DATABASE=My_Database
       - MYSQL_USER=my_user
       - MYSQL_PASSWORD=my_password
     volumes:
       - db_data:/var/lib/mysql
     restart: always
     expose:
       - "3306"

   my_common_package:
     image: my_common_package
     depends_on:
       - mysql
     restart: always
     links:
       - mysql

volumes:
  db_data:

现在,我尝试使用以下方法在我的包中运行测试:

docker-compose run my_common_package python testsql.py

我收到错误消息

pymysql.err.OperationalError: (2003, "Can't connect to MySQL server on on 'localhost' ([Errno 99] 无法分配请求的地址)")

【问题讨论】:

  • testsql.py 中有什么你认为应该连接到 mysql 的 docker 容器的?
  • 您需要使用mysql 主机名进行连接,而不是本地主机名。在网络方面,您可以将容器视为虚拟机,
  • 在 testsql.py 模块中,我只是有一行使用 python 连接到 'localhost' 端口 '3306' 上的 mysql 实例
  • @andrew 查看下面的答案
  • @andrew 如果您在查看我的答案后还有任何问题,请回复。

标签: python mysql docker docker-compose dockerfile


【解决方案1】:

docker-compose 默认会创建虚拟网络,因为 compose 文件中的所有容器/服务都可以通过 IP 地址相互访问。通过使用linksdepends_on 或网络别名,它们可以通过主机名相互联系。在您的情况下,主机名是服务名称,但这可以被覆盖。 (见:docs

您在my_common_package 容器/服务中的脚本应根据您的设置连接到端口3306 上的mysql。 (不是localhost 端口3306

另请注意,仅当服务的 Dockerfile 没有 EXPOSE 语句时,才需要使用 expose。标准的 mysql 镜像已经这样做了。

如果您想将容器端口映射到localhost,您需要使用ports,但只有在必要时才这样做。

services:
   mysql:
     image: mysql:5.6
     container_name: test_mysql_container
     environment:
       - MYSQL_ROOT_PASSWORD=test
       - MYSQL_DATABASE=My_Database
       - MYSQL_USER=my_user
       - MYSQL_PASSWORD=my_password
     volumes:
       - db_data:/var/lib/mysql
     ports:
       - "3306:3306"

这里我们说mysql容器中的3306端口应该映射到localhost的3306端口。

现在您可以在 docker 之外使用 localhost:3306 连接到 mysql。例如,您可以尝试在本地(不在容器中)运行 testsql.py

容器到容器的通信将始终使用每个容器的主机名进行。将容器视为虚拟机。

你甚至可以找到使用docker network list创建的网络docker-compose:

1b1a54630639        myproject_default             bridge              local
82498fd930bb        bridge                        bridge              local

..然后使用docker network inspect <id>查看详情。

分配给容器的 IP 地址可能非常随机,因此容器与容器之间通信的唯一可行方法是使用主机名。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-11-07
    • 1970-01-01
    • 2020-04-23
    • 2018-03-31
    • 1970-01-01
    • 2016-02-21
    • 1970-01-01
    相关资源
    最近更新 更多