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

查看:176
本文介绍了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年,无法通过以下方式连接到MySQL服务器 'localhost'([Errno 99]无法分配请求的地址))

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

推荐答案

docker-compose默认情况下将创建虚拟网络,前提是撰写文件中的所有容器/服务都可以通过IP地址相互访问.通过使用linksdepends_on或网络别名,它们可以通过主机名相互访问.在您的情况下,主机名是服务名,但是可以覆盖它. (请参阅:文档)

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应该映射到端口3306上的localhost.

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 <id>查看详细信息.

.. 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天全站免登陆