无法从Docker容器连接mysql? [英] Unable to connect mysql from docker container?
问题描述
我已经创建了一个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:
设置值为
会在MySQL中导致以下错误消息: root
的MYSQL_USER
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屋!