django.db.utils.OperationalError:(2005年,“未知的MySQL服务器主机'db'(-2)”)

时间:2018-08-26 09:02:19

标签: python mysql django docker docker-compose

我正在尝试在docker容器中使用mysql运行django:

version: '2'
services:

  db:
    image: mysql:latest
    volumes:
      - ./db:/var/lib/mysql
    ports:
      - "3306:3306"
    environment:
      MYSQL_ROOT_PASSWORD: mypassword
      MYSQL_USER: root
      MYSQL_PASSWORD: mypassword
      MYSQL_DATABASE: django
    expose:
      - "3306"

  web:
    build: .
    command: python manage.py runserver 0.0.0.0:8000
    volumes:
      - .:/code
    ports:
      - "8000:8000"
    depends_on:
     - db

但是在docker-compose up --build之后出现错误:

  

django.db.utils.OperationalError:(2005年,“未知的MySQL服务器主机   'db'(-2)“)

很有可能,装有mysql的容器没有时间启动。但是我确实在depends_on: - db

中指定了web

谁知道这可能是怎么回事?

3 个答案:

答案 0 :(得分:2)

According to the official docker-compose documentationdepends_on意味着该服务依赖于另一个服务,没有它就无法运行,但这并不意味着另一个服务已准备好处理请求。

因此,当您启动部署时,docker-compose会确保在启动web服务时,db也正在运行(如果您尝试杀死db容器,则我们会在docker compose日志中注意到web也被杀死)。由于MySQL映像第一次启动需要一些时间,因此导致数据库无法立即处理查询。

为解决此问题,docker-compose具有关键字restart,该关键字指定发生问题且进程终止时(例如,db未准备好处理请求)时的容器行为。

最后,您的docker-compose.yaml文件应为:

version: '2'
services:

  db:
    image: mysql:latest
    volumes:
      - ./db:/var/lib/mysql
    restart: always
    ports:
      - "3306:3306"
    environment:
      MYSQL_ROOT_PASSWORD: mypassword
      MYSQL_USER: root
      MYSQL_PASSWORD: mypassword
      MYSQL_DATABASE: django
    expose:
      - "3306"

  web:
    build: .
    command: python manage.py runserver 0.0.0.0:8000
    volumes:
      - .:/code
    restart: always
    ports:
      - "8000:8000"
    depends_on:
     - db

You can find more about the restart keyword in the official documentation

答案 1 :(得分:0)

depends_on在docker-compose中意味着服务依赖于另一个服务,没有它就无法运行,但这并不意味着另一个服务已准备就绪并且正在侦听请求。

我想做的是在命令中向容器中添加一个wait-for-it,该容器需要另一个服务来启动并准备处理请求。

在涉及dbweb的情况下,在我的代码目录中放入wait-for-it.sh后,我将对Web容器的命令修改为:

./wait-for-it.sh -t 300 db:3306 && python manage.py runserver 0.0.0.0:8000

这只会告诉web等待端口db上主机3306的可用性,从而同步两个相互依赖的服务的启动

答案 2 :(得分:0)

如果我没记错,您应该在 reject 中使用links

docker-compose