Can';t从Golang容器连接到MySQL容器

Can';t从Golang容器连接到MySQL容器,mysql,docker,go,Mysql,Docker,Go,我有两个容器:一个简单的golang程序和mysql。 我可以启动两者,但golang应用程序无法连接到mysql。我收到的连接被拒绝 如果我docker exec进入mysql容器,并尝试与mysql-u root-p进行本地连接,所有这些都可以正常工作 如果在主机上,我尝试使用mysql-h0.0.0.0-p1000-uroot-p连接到容器,所有这些都可以正常工作 我在docker compose和bind address=0.0.0.0中将mysqld.cnf添加到mysqld.cnf中

我有两个容器:一个简单的golang程序和mysql。 我可以启动两者,但golang应用程序无法连接到mysql。我收到的连接被拒绝

如果我
docker exec
进入mysql容器,并尝试与
mysql-u root-p
进行本地连接,所有这些都可以正常工作

如果在主机上,我尝试使用
mysql-h0.0.0.0-p1000-uroot-p
连接到容器,所有这些都可以正常工作

我在
docker compose
bind address=0.0.0.0
中将
mysqld.cnf
添加到
mysqld.cnf中,但仍然不起作用

我做错了什么

docker compose

    FROM golang:alpine
    RUN mkdir /app
    ADD . /app/
    
    WORKDIR /app
    
    RUN apk update && apk upgrade && apk add --no-cache bash git openssh
    
    RUN go get github.com/jinzhu/gorm
    RUN go get github.com/jinzhu/gorm/dialects/mysql
    RUN go get github.com/gin-gonic/gin
    RUN go get github.com/gin-contrib/cors
    
    
    RUN go build -o main .
    RUN adduser -S -D -H -h /app appuser
    USER appuser
    CMD ["./main"]
版本:“3”
服务:
网状物:
建造:
上下文:。
dockerfile:docker/web/dockerfile
端口:
-“8081:8081”#http
-“443:443”#https
链接:
-德布鲁私人酒店
卷数:
-../../../../../../go.:/go
db_私人:
图片:mysql:5.7
重新启动:始终
环境:
MYSQL_数据库:${MYSQL_数据库}
MYSQL\u用户:${MYSQL\u用户}
MYSQL\u密码:${MYSQL\u密码}
MYSQL\u ROOT\u密码:${MYSQL\u ROOT\u密码}
MYSQL\u根目录\u主机:''
端口:
- '10000:3306'
揭露:
- '3306'
卷数:
-./mysql entry point.sql:/docker entrypoint initdb.d
-私有数据库:/var/lib/mysql
-./mysqld.cnf:/etc/mysql/mysql.conf.d/mysqld.cnf
#命名我们的卷
卷数:
私人数据库:
Web容器Dockerfile

    FROM golang:alpine
    RUN mkdir /app
    ADD . /app/
    
    WORKDIR /app
    
    RUN apk update && apk upgrade && apk add --no-cache bash git openssh
    
    RUN go get github.com/jinzhu/gorm
    RUN go get github.com/jinzhu/gorm/dialects/mysql
    RUN go get github.com/gin-gonic/gin
    RUN go get github.com/gin-contrib/cors
    
    
    RUN go build -o main .
    RUN adduser -S -D -H -h /app appuser
    USER appuser
    CMD ["./main"]
Golang文件

    FROM golang:alpine
    RUN mkdir /app
    ADD . /app/
    
    WORKDIR /app
    
    RUN apk update && apk upgrade && apk add --no-cache bash git openssh
    
    RUN go get github.com/jinzhu/gorm
    RUN go get github.com/jinzhu/gorm/dialects/mysql
    RUN go get github.com/gin-gonic/gin
    RUN go get github.com/gin-contrib/cors
    
    
    RUN go build -o main .
    RUN adduser -S -D -H -h /app appuser
    USER appuser
    CMD ["./main"]
主程序包
进口(
“fmt”
“github.com/gin gonic/gin”
“github.com/jinju/gorm”
_“github.com/jinzhu/gorm/dialogs/mysql”
“net/http”
“时间”
)
var db*gorm.db
类型(
FooModel结构{
Id int64`gorm:“主键”`
名称字符串
}
)
func init(){
//打开数据库连接
变量错误
db,err=gorm.Open(“mysql”,“user:pwd@(0.0.0.0:10000)/myDB?charset=utf8&parseTime=true”)
如果错误!=零{
fmt.Println(错误)
死机(“连接数据库失败”)
}
//迁移模式
db.AutoMigrate(&FooModel{})
db.LogMode(真)
}
//主要inits路线
func main(){
路由器:=gin.Default()
GET(“/getExample”,getExample)
路由器运行(“0.0.0.0:8081”)
}
func getExample(c*gin.Context){
c、 JSON(http.StatusOK,gin.H{“status”:http.StatusOK,“data”:“bye”})
}
我将
mysqld.cnf
复制到包含该文件的容器中

    [mysqld]
    pid-file    = /var/run/mysqld/mysqld.pid
    socket      = /var/run/mysqld/mysqld.sock
    datadir     = /var/lib/mysql
    #log-error  = /var/log/mysql/error.log
    # By default we only accept connections from localhost
    #bind-address   = 127.0.0.1
    bind-address   = 0.0.0.0
    # Disabling symbolic-links is recommended to prevent assorted security risks
    symbolic-links=0

您的web应用正在容器中运行,这意味着地址0.0.0.0是容器本身,而不是它运行的主机。尝试使用
db_private
名称而不是地址0.0.0.0连接db。

在我的情况下,使用Docker主机的
db_private
,我通过运行以下命令获取本地IP:

ipconfig getifaddr en0
=>172.16.4.227

然后我在gorm SQL连接中使用此IP:

db, err = gorm.Open("mysql", "user:pwd@(172.16.4.227:10000)/myDB?charset=utf8&parseTime=true")

这对我有用

0.0.0.0
不是您容器的IP地址。这是一个特殊的地址,意思是“所有可用的接口”

您正在使用
0.0.0.0
从主机连接到容器,因为它们共享一个接口,因为您在
docker compose.yml
文件中公开了端口

如果您的应用程序总是在一个容器中,而您的数据库总是在一个容器中,Docker为您提供了一种将一个连接到另一个的方法

db_private
,即服务名称,可从您的
web
(或golang)容器中找到

这将始终有效,因为Docker有一个内部DNS服务器,您的容器可以使用该服务器,无论您的容器具有哪个IP地址

host> docker-compose up -d
host> docker-compose exec web /bin/sh
 web$ ping db_private

是的,您总是想在容器中使用
0.0.0.0
作为绑定接口,因为您永远不知道将获得哪个IP地址,所以这就像是说“全部”的快捷方式/myDB?charset=utf8&parseTime=true“)但我仍然收到“拨号tcp 0.0.0:10000:连接:连接被拒绝”您的代码仍在尝试连接到0.0.0.0。也许在图像构建过程中出了问题?您没有运行已更改的程序。我正在执行docker系统修剪--卷,然后执行docker compose构建,是否缺少某些内容?还有一件事:尝试db_private:3306,因为这是容器上打开的端口。它在主机上发布为10000。