Docker 无法将应用程序连接到 MySQL [英] Docker cannot connect application to MySQL

查看:42
本文介绍了Docker 无法将应用程序连接到 MySQL的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to run integration tests (in python) which depend on mysql. Currently they depend on SQL running locally, but I want them to depend on a MySQL running in docker.

Dockerfile 的内容:

Contents of Dockerfile:

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

Docker Compose 的内容:

Contents of 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:

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

Now, I try to run the tests in my package using:

docker-compose run my_common_package python testsql.py

我收到错误

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

pymysql.err.OperationalError: (2003, "Can't connect to MySQL server on 'localhost' ([Errno 99] Cannot assign requested address)")

推荐答案

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

docker-compose will by default create virtual network were all the containers/services in the compose file can reach each other by an IP address. By using links, depends_on or network aliases they can reach each other by host name. In your case the host name is the service name, but this can be overridden. (see: docs)

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

Your script in my_common_package container/service should then connect to mysql on port 3306 according to your setup. (not localhost on port 3306)

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

Also note that using expose is only necessary if the Dockerfile for the service don't have an EXPOSE statement. The standard mysql image already does this.

如果要将容器端口映射到 localhost,则需要使用 ports,但仅在必要时才这样做.

If you want to map a container port to localhost you need to use ports, but only do this if it's necessary.

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端口.

Here we are saying that port 3306 in the mysql container should be mapped to localhost on port 3306.

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

Now you can connect to mysql using localhost:3306 outside of docker. For example you can try to run your testsql.py locally (NOT in a container).

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

Container to container communication will always happen using the host name of each container. Think of containers as virtual machines.

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

You can even find the network docker-compose created using docker network list:

1b1a54630639        myproject_default             bridge              local
82498fd930bb        bridge                        bridge              local

...然后使用docker network inspect 查看详情.

.. then use docker network inspect <id> to look at the details.

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

Assigned IP addresses to containers can be pretty random, so the only viable way for container to container communication is using hostnames.

这篇关于Docker 无法将应用程序连接到 MySQL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆