无法从Docker容器连接mysql? [英] Unable to connect mysql from docker container?

查看:612
本文介绍了无法从Docker容器连接mysql?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经创建了一个docker-compose文件,它具有 Go Mysql 两个服务。它为go和mysql创建容器。现在我正在运行尝试连接到作为docker容器运行的mysql数据库的代码。但是我得到了错误。

I have created a docker-compose file it has two services with Go and Mysql. It creates container for go and mysql. Now i am running code which try to connect to mysql database which is running as a docker container. but i get error.

docker-compose.yml

version: "2"
services:
  app:
    container_name: golang
    restart: always
    build: .
    ports:
      - "49160:8800"
    links:
      - "mysql"
    depends_on:
      - "mysql" 

  mysql:
    image: mysql
    container_name: mysql
    volumes:
      - dbdata:/var/lib/mysql
    restart: always
    environment:
      - MYSQL_ROOT_PASSWORD=root
      - MYSQL_DATABASE=testDB
      - MYSQL_USER=root
      - MYSQL_PASSWORD=root
    ports:
      - "3307:3306"
volumes:
  dbdata:

连接到mysql数据库时出错

golang   | 2019/02/28 11:33:05 dial tcp 127.0.0.1:3306: connect: connection refused
golang   | 2019/02/28 11:33:05 http: panic serving 172.24.0.1:49066: dial tcp 127.0.0.1:3306: connect: connection refused
golang   | goroutine 19 [running]:

与MySql数据库的连接

func DB() *gorm.DB {
    db, err := gorm.Open("mysql", "root:root@tcp(mysql:3306)/testDB?charset=utf8&parseTime=True&loc=Local")
    if err != nil {
        log.Panic(err)
    }
    log.Println("Connection Established")
    return db
}

编辑:更新的docker文件

FROM golang:latest 
RUN go get -u github.com/gorilla/mux
RUN go get -u github.com/jinzhu/gorm
RUN go get -u github.com/go-sql-driver/mysql
COPY ./wait-for-it.sh .
RUN chmod +x /wait-for-it.sh
WORKDIR /go/src/app
ADD . src
EXPOSE 8800
CMD ["go", "run", "src/main.go"]

我正在使用gorm程序包,该程序包使我可以连接到数据库

I am using gorm package which lets me connet to the database

推荐答案

depends_on 不能验证MySQL是否已准备好接收连接。无论数据库容器是否已准备好进行连接,无论数据库容器是否正在运行,它都会启动第二个容器,这可能会导致应用程序出现此问题,因为它期望数据库已准备就绪,而这可能不是真的。

depends_on is not a verification that MySQL is actually ready to receive connections. It will start the second container once the database container is running regardless it was ready for connections or not which could lead to such an issue with your application as it expects the database to be ready which might not be true.

引用自文档


depends_on在启动Web之前不等待db和redis处于就绪状态-仅在它们启动之前。

depends_on does not wait for db and redis to be "ready" before starting web - only until they have been started.

有许多工具/脚本可用于解决此问题,例如等待,如果您的图像基于 Alpine ,则 sh 兼容例如(如果您的图片中有bash,则可以使用 wait-for-it

There are many tools/scripts that can be used to solve this issue like wait-for which sh compatible in case your image based on Alpine for example (You can use wait-for-it if you have bash in your image)

您所要做的就是添加通过 Dockerfile 将脚本脚本写入图像,然后在 docker-compose.yml 中使用此命令获取所需的服务使它等待数据库。

All you have to do is to add the script to your image through Dockerfile then use this command in docker-compose.yml for the service that you want to make it wait for the database.

-之后是通常会执行的命令用来启动您的应用程序

What comes after -- is the command that you would normally use to start your application

version: "2"
services:
  app:
    container_name: golang
    ...
        command: ["./wait-for", "mysql:3306", "--", "go", "run", "myapplication"]
    links:
      - "mysql"
    depends_on:
      - "mysql" 

  mysql:
    image: mysql
  ...




我已经从docker-compose中删除了一些部分

I have removed some parts from the docker-compose for easier readability.

修改此部分使用 CMD c $ c>您的golang图片。

Modify this part go run myapplication with the CMD of your golang image.

请参见控制启动顺序,以获取有关此问题的更多信息以及解决该问题的策略。



解决连接问题后还会出现的另一个问题如下:

See Controlling startup order for more on this problem and strategies for solving it.


Another issue that will rise after you solve the connection issue will be as the following:

设置值为 root 的MYSQL_USER 会在MySQL中导致以下错误消息:

Setting MYSQL_USER with root value will cause a failure in MySQL with this error message:

ERROR 1396 (HY000) at line 1: Operation CREATE USER failed for 'root'@'%'

$ b操作CREATE USER失败
$ b

这是因为该用户已存在于数据库中,并试图创建另一个用户。如果您需要使用root用户本身,则只能使用此变量 MYSQL_ROOT_PASSWORD 或更改 MYSQL_USER 的值,因此可以安全地在应用程序中而不是root用户中使用它。

This is because this user already exist in the database and it tries to create another. if you need to use the root user itself you can use only this variable MYSQL_ROOT_PASSWORD or change the value of MYSQL_USER so you can securely use it in your application instead of the root user.

更新:如果找不到您并且路径正确,您可能需要编写以下命令:

Update: In case you are getting not found and the path was correct, you might need to write the command as below:

command: sh -c "./wait-for mysql:3306 -- go run myapplication"

这篇关于无法从Docker容器连接mysql?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆