无法通过在docker compose文件中链接来连接到mysql映像

时间:2017-09-18 22:46:49

标签: mysql django docker docker-compose

我正在使用以下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数据库映像?

1 个答案:

答案 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应用程序之前就已经发生了。

这应该有所帮助 - 并且还应该帮助处理几个级别的问题,这可能是原因。