我正在使用以下docker-compose文件
version: '2'
services:
app_test:
build:
context: .
dockerfile: Dockerfile-jenkins-test
ports:
- "7200:7200"
volumes:
- .:/opt/project
environment:
- DJANGO_SETTINGS_MODULE=myapp.settings.test
- MYSQL_DATABASE=test_db
- DB_HOST=mysql_test_db
- MYSQL_ROOT_PASSWORD=my_pass
- DB_PORT=3306
links:
- mysql_test_db
mysql_test_db:
image: mysql:latest
container_name: mysql_db_container
expose:
- "3306"
environment:
- MYSQL_ROOT_PASSWORD=mypass
- MYSQL_DATABASE=test_db
当尝试使用DB_HOST mysql_test_db访问mysql时会出错提示
django.db.utils.OperationalError:(2005,"未知的MySQL服务器主机 ' mysql_test_db' (0)&#34)
如何从app_test访问链接的MySQL数据库映像?
答案 0 :(得分:2)
您不需要此类“链接”,docker-compose中的所有服务都可以访问自己,并使用其服务名称自动“链接”。
也没有必要公开3306,因为在该docker-compose堆栈的内部docker-network中,无论如何,网络内的任何服务都可以访问该端口。
version: '2'
services:
app_test:
build:
context: .
dockerfile: Dockerfile-jenkins-test
ports:
- "7200:7200"
volumes:
- .:/opt/project
environment:
- DJANGO_SETTINGS_MODULE=myapp.settings.test
- MYSQL_DATABASE=test_db
- DB_HOST=mysql_test_db
- MYSQL_ROOT_PASSWORD=my_pass
- DB_PORT=3306
mysql_test_db:
image: mysql:latest
container_name: mysql_db_container
environment:
- MYSQL_ROOT_PASSWORD=mypass
- MYSQL_DATABASE=test_db
但是你最有可能的是,服务启动的顺序并不适合你。 Mysql需要一段时间才能连接数据库并配置凭据,而你的django应用程序启动速度非常快,并且在配置这些凭据之前立即尝试连接。
在你的django应用程序的入口点,你需要使用wait-for-it https://github.com/vishnubob/wait-for-it之类的东西并测试3306端口是否可用。在MSQYL术语中,这甚至可能是假的,因为该规定以mysqld_safe守护进程开始,不允许任何连接,但是TCP套接字是打开的并且会欺骗“等待它”。
所以你可以做的是使用你的凭证使用真正的mysql连接阻止应用程序启动,直到建立连接:
#!/bin/bash
RET=1
echo "Waiting for database"
while [[ RET -ne 0 ]]; do
sleep 1;
if [ -z "${db_password}" ]; then
mysql -h $db_host -u $db_user -e "select 1" > /dev/null 2>&1; RET=$?
else
mysql -h $db_host -u $db_user -p$db_password -e "select 1" > /dev/null 2>&1; RET=$?
fi
done
echo "DB reached, continuing"
所以这在您实际引导django应用程序之前就已经发生了。
这应该有所帮助 - 并且还应该帮助处理几个级别的问题,这可能是原因。