docker - 无法从 docker 容器连接 mysql?
问题描述
我创建了一个 docker-compose 文件,它有两个服务Go
和Mysql
. 它为 go 和 mysql 创建容器。现在我正在运行尝试连接到作为 docker 容器运行的 mysql 数据库的代码。但我得到错误。
码头工人-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
}
编辑:更新的泊坞窗文件
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 包,它可以让我连接到数据库
解决方案
depends_on
不是验证 MySQL 实际上已准备好接收连接。一旦数据库容器运行,它将启动第二个容器,无论它是否已准备好连接,这可能会导致您的应用程序出现此类问题,因为它期望数据库已准备好,这可能不是真的。
从文档中引用:
在启动 web 之前,depends_on 不会等待 db 和 redis “准备好” - 仅在它们启动之前。
有许多工具/脚本可用于解决此问题,例如wait-for兼容,sh
以防您的图像基于Alpine
例如(如果您的图像中有 bash,您可以使用wait-for-it )
您所要做的就是将脚本添加到您的图像中,Dockerfile
然后将此命令docker-compose.yml
用于您希望使其等待数据库的服务。
接下来是--
您通常用来启动应用程序的命令
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 中删除了一些部分。
go run myapplication
使用CMD
您的 golang 图像修改此部分。
有关此问题和解决策略的更多信息,请参阅控制启动顺序。
解决连接问题后会出现的另一个问题如下:
MYSQL_USER
使用value设置root
将导致 MySQL 失败,并显示以下错误消息:
ERROR 1396 (HY000) at line 1: Operation CREATE USER failed for 'root'@'%'
这是因为该用户已经存在于数据库中,并且它试图创建另一个用户。如果您需要使用 root 用户本身,您可以只使用此变量MYSQL_ROOT_PASSWORD
或更改的值,MYSQL_USER
以便您可以在应用程序中安全地使用它而不是 root 用户。
更新:如果您找不到并且路径正确,您可能需要编写如下命令:
command: sh -c "./wait-for mysql:3306 -- go run myapplication"
推荐阅读
- javascript - PHP 表单发送电子邮件但 $_POST['email'] 失败
- json - 将大对象数组发送到spring boot控制器并将数据保存在数据库中
- html - 如何使用 css 恢复溢出滚动行为
- java - 如何处理域类(Java)中的依赖异步操作?
- c# - 将变量传递给函数和列表传递给函数之间的性能差异
- asp.net - Kendo Grid 日期时间过滤
- finance - 松树脚本内的动态日期范围
- vba - 访问 VBA 退出被调用的子程序并跳过子程序的其余部分
- google-colaboratory - 如何在 Google colab 中自动保存笔记本?
- java - 字符数组或字符串生成器