我正在尝试运行依赖于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,“无法连接到MySQL服务器上 'localhost'([Errno 99]无法分配请求的地址)“)
答案 0 :(得分:1)
docker-compose将默认创建虚拟网络,所有compose文件中的容器/服务都可以通过IP地址相互连接。通过使用links
,depends_on
或网络别名,他们可以通过主机名相互联系。在您的情况下,主机名是服务名称,但可以覆盖它。 (见:docs)
my_common_package
容器/服务中的脚本应根据您的设置连接到端口mysql
上的3306
。 (而不是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应该映射到端口3306上的localhost。
现在您可以使用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地址可能非常随机,因此容器到容器通信的唯一可行方法是使用主机名。