无法从Docker容器连接到MySQL?

9 浏览
0 Comments

无法从Docker容器连接到MySQL?

我创建了一个docker-compose文件,其中包含两个服务:一个是使用Go的服务,另一个是使用Mysql的服务。它会为Go和Mysql创建容器。现在我正在运行代码,尝试连接到作为docker容器运行的mysql数据库,但是我遇到了错误。

docker-compose.yml

版本: "2"

服务:

app:

容器名称:golang

重启:始终

构建:。

端口:

- "49160:8800"

链接:

- "mysql"

依赖:

- "mysql"

mysql:

镜像:mysql

容器名称:mysql

卷:

- dbdata:/var/lib/mysql

重启:始终

环境:

- MYSQL_ROOT_PASSWORD=root

- MYSQL_DATABASE=testDB

- MYSQL_USER=root

- MYSQL_PASSWORD=root

端口:

- "3307:3306"

卷:

dbdata:

连接到Mysql数据库的错误

golang | 2019/02/28 11:33:05 dial tcp 127.0.0.1:3306:连接被拒绝

golang | 2019/02/28 11:33:05 http:在172.24.0.1:49066上服务发生崩溃:dial tcp 127.0.0.1:3306:连接被拒绝

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("连接已建立")

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包,它让我能够连接到数据库。

0
0 Comments

无法从Docker容器中连接到MySQL的原因是Docker的最新版本中不再需要使用link参数。解决方法是使用networks参数创建一个Docker网络,并将每个服务添加到其中。以下是一个示例的docker-compose.yml文件:

version: "2"

services:

app:

container_name: golang

restart: always

build: .

ports:

- "49160:8800"

networks:

- my_network

depends_on:

- "mysql"

mysql:

image: mysql

container_name: mysql

volumes:

- dbdata:/var/lib/mysql

restart: always

networks:

- my_network

environment:

- MYSQL_ROOT_PASSWORD=root

- MYSQL_DATABASE=testDB

- MYSQL_USER=root

- MYSQL_PASSWORD=root

ports:

- "3307:3306"

volumes:

dbdata:

networks:

my_network:

driver: bridge

另外,如果只从app服务连接到MySQL,不需要暴露MySQL的端口。如果容器在同一个网络中运行,它们可以访问该网络中的所有端口。

如果以上示例无法解决问题,可以尝试以下步骤:

1. 运行docker-compose命令,并使用`docker container exec -it CONTAINER_NAME bash`进入app容器。

2. 在app容器中安装ping工具,然后运行`ping mysql`来测试连接。

3. 检查连接字符串是否为`root:root(mysql:3306)/testDB?charset=utf8&parseTime=True&loc=Local`。

以上是解决无法从Docker容器中连接到MySQL的方法。这个问题可能是由于Docker启动顺序引起的。

0
0 Comments

无法从Docker容器中连接到MySQL的问题出现的原因是depends_on指令不能保证MySQL已经准备好接收连接。它只是在数据库容器运行后启动第二个容器,而不管数据库是否已准备好接收连接,这可能导致应用程序出现问题,因为它期望数据库已经准备好,但实际上可能并不是这样。

解决这个问题的方法有很多,比如使用wait-for工具/脚本,该工具与Alpine镜像兼容(如果你的镜像基于Alpine,你可以使用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

...

修改go run myapplication部分为你的Golang镜像的CMD

解决连接问题后可能会出现另一个问题:

使用root值设置MYSQL_USER会导致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"

请告诉我确切的代码,以便解决这个问题。

你已经将脚本添加到镜像并使其可执行了吗?

我还没有将脚本添加到镜像中。请告诉我如何将脚本添加到镜像中?虽然我已经在Dockerfile中写了COPY wait-for-it.sh /wait-for-it.sh

请将你更新后的Dockerfile发布到问题中,这样我可以检查一下。如果你已经使用了COPY,那就意味着脚本已经在镜像中,并且需要将其设置为可执行。

请检查我更新后的问题。我已经添加了Dockerfile。

实际上,无论日志中出现的错误的IP地址是否正确,mysql容器都不会正常工作,所以请仔细阅读我问题的第二部分,该部分与MYSQL_USER变量的使用相关。

让我知道它是如何工作的,因为找不到wait_for_it。

你需要通过启动一个新容器进入容器内部,然后尝试手动执行脚本,以检查脚本是否在容器内部,或者你需要修复权限等问题,以便按照你的期望找到脚本。

0