我有两个容器:一个简单的golang程序和mysql.我可以启动两者,但golang应用程序无法连接到mysql.我收到连接拒绝.
如果我将docker exec
放入mysql容器,并尝试使用mysql -u root -p
进行本地连接,则一切正常。
如果在主机上,我尝试连接到mysql -h 0.0.0.0 -P 10000 -u root -p
的容器,一切正常。
我在docker-compose
中添加了MYSQL_ROOT_HOST: '%'
,在mysqld.cnf
中添加了bind-address = 0.0.0.0
,但仍然不工作。
我做错了什么?
对接合成
version: '3'
services:
web:
build:
context: .
dockerfile: docker/web/Dockerfile
ports:
- "8081:8081" # http
- "443:443" # https
links:
- db_private
volumes:
- ../../../../.:/go
db_private:
image: mysql:5.7
restart: always
environment:
MYSQL_DATABASE: ${MYSQL_DATABASE}
MYSQL_USER: ${MYSQL_USER}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_ROOT_HOST: '%'
ports:
- '10000:3306'
expose:
- '3306'
volumes:
- ./mysql-entry-point.sql:/docker-entrypoint-initdb.d
- private-db:/var/lib/mysql
- ./mysqld.cnf:/etc/mysql/mysql.conf.d/mysqld.cnf
# Names our volume
volumes:
private-db:
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文件
package main
import (
"fmt"
"github.com/gin-gonic/gin"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
"net/http"
"time"
)
var db *gorm.DB
type (
FooModel struct {
Id int64 `gorm:"primary_key"`
name string
}
)
func init() {
//open a db connection
var err error
db, err = gorm.Open("mysql", "user:pwd@(0.0.0.0:10000)/myDB?charset=utf8&parseTime=true")
if err != nil {
fmt.Println(err)
panic("failed to connect database")
}
//Migrate the schema
db.AutoMigrate(&FooModel{})
db.LogMode(true)
}
// main inits routes
func main() {
router := gin.Default()
router.GET("/getExample", getExample)
router.Run("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
5条答案
按热度按时间lx0bsm1f1#
您的Web应用正在容器中运行,这意味着地址0.0.0.0是容器本身,而不是运行它的主机。请尝试使用
db_private
名称而不是地址0.0.0.0连接数据库。kmynzznz2#
0.0.0.0
不是容器的IP地址。它是一个特殊地址,表示“所有可用接口”。您使用
0.0.0.0
从主机连接到容器,因为它们共享一个接口,因为您在docker-compose.yml
文件中公开了端口。如果你的应用程序总是在一个容器中,而你的数据库总是在一个容器中,Docker提供了一个方法来连接一个到另一个。
服务名
db_private
可以在web
(或golang)容器中找到。这将始终有效,因为Docker有一个内部DNS服务器,您的容器可以使用它,无论您的容器使用哪个IP地址。
是的,你总是想使用
0.0.0.0
作为容器内的绑定接口,因为你永远不知道你会得到哪个IP地址,所以这就像一个快捷方式说“全部”。57hvy0tb3#
在我的例子中,而是使用Docker主机的
db_private
,我通过运行以下命令来获取本地IP:=〉172.16.4.227
然后我在我的gorm SQL连接中使用这个IP:
这对我很有效
3df52oht4#
你可以在
just 3 steps
中简单地解决这个问题:1.在
docker-compose
文件中将ports
从10000:3306
更改为3306:3306
。1.在
Golang file
中将0.0.0.0:10000
更改为db_private:3306
。1.不需要清理容器和镜像,运行以下命令:
9rygscc15#
这可能对某人有帮助!我有同样的问题,花了5个小时来解决这个问题。在我的情况下,我使用的是“sqlc”的golang,也想通过组合文件传递连接字符串。
但是当我试图通过 Postman 调用API时,我得到了像访问被拒绝到'root'@'x.x.x.x'这样的错误。长话短说,我从DB_SOURCE中删除了双引号,它工作了!