【问题标题】:Why does my docker mysql database container refuse connection from my app(golang) container为什么我的 docker mysql 数据库容器拒绝来自我的应用程序(golang)容器的连接
【发布时间】:2020-12-23 11:49:18
【问题描述】:

当我运行我的 docker 应用程序并键入以下 URL 时,我得到了显示的响应...

http://localhost:8080/complex

Hello...dial tcp 172.21.0.2:3306: connect: connection refused

我希望连接被接受,然后能够查询数据库等。

如果我故意将 main.go 文件中的连接字符串更改为不存在的主机(添加了一个 x)。

"root:root@tcp(godockerxDB:3306)/task_man")

使用这个网址...

http://localhost:8080/complex

我收到此回复...

Hello...dial tcp: lookup godockerxDB on 127.0.0.11:53: no such host

正如我所料,原来的主机似乎是正确的,但它只是拒绝连接。

我已经手动连接到 db 容器并确认数据库在那里并且正确设置了表和任务,并且我能够在其中查询数据库表单。

我的 main.go...

    package main

import (
    "database/sql"
    "encoding/json"
    "fmt"
    _ "github.com/go-sql-driver/mysql"
    "github.com/gorilla/mux"
    "net/http"
)

func simple(w http.ResponseWriter, r *http.Request) {
    enableCors(&w)
    fmt.Fprintf(w, "Hi there, I love %s!", r.URL.Path[1:])
}

var db *sql.DB
var err error

func main() {
    fmt.Print("hello")
    router := mux.NewRouter()
    router.HandleFunc("/complex", complex).Methods("GET")
    router.HandleFunc("/text", simple).Methods("GET")
    err := http.ListenAndServe(":8080", router)
    fmt.Print(err)

}
func enableCors(w *http.ResponseWriter) {
    (*w).Header().Set("Access-Control-Allow-Origin", "*")
}
func complex(w http.ResponseWriter, r *http.Request) {
    enableCors(&w)
    fmt.Fprintf(w, "Hello...")
    db, err = sql.Open("mysql", "root:root@tcp(godockerDB:3306)/task_man")
    if err != nil {
        fmt.Fprintf(w, "Hello David")
        fmt.Fprintf(w, err.Error())
    }
    defer db.Close()
    err2 := db.Ping()


    fmt.Fprintf(w, err2.Error())
}

我的应用程序 Docker 文件...

> FROM golang:1.12-alpine
> 
> RUN apk add --no-cache git
> 
> # Set the Current Working Directory inside the container WORKDIR /app/godocker
> 
> 
> COPY go.mod . COPY go.sum .
> 
> RUN go mod download
> 
> COPY . .
> 
> # Build the Go app RUN go build -o ./out/godocker .
> 
> 
> # This container exposes port 8080  EXPOSE 8080
> 
> # Run the binary program produced by `go install` CMD ["./out/godocker"]

我的数据库 Dockerfile...

FROM mysql:5.7
ENV MYSQL_ROOT_PASSWORD=root
COPY setup.sql /docker-entrypoint-initdb.d/

我的 docker-compose.yml ...

# Use root/example as user/password credentials
version: '3.1'

services:
  app:
    build:
      context: ./
      dockerfile: Dockerfile
    container_name: godockerAPP
    ports:
      - "8080:8080"
    depends_on:
      - db      
    restart: always
  db:
    build:
      context: ./dockerfiles/db
      dockerfile: Dockerfile
    container_name: godockerDB
    command: --default-authentication-plugin=mysql_native_password
    ports:
      - "3306:3306"
    restart: always

我运行的命令来启动 docker compose...

docker-compose down
docker-compose build
docker-compose up -d

构建数据库步骤 1/3:FROM mysql:5.7 ---> 718a6da099d8 步骤 2/3: ENV MYSQL_ROOT_PASSWORD=root ---> 使用缓存 ---> 9087b3db47ac 步骤 3/3 : 复制 setup.sql /docker-entrypoint-initdb.d/ ---> 使用缓存 ---> 195614e33d96 成功构建 195614e33d96 成功标记 godocker_db:latest Building app Step 1/11 : FROM golang:1.12 ---> ffcaee6f7d8b 步骤 2/11:ENV GO111MODULE=on ---> 使用缓存 ---> 25377bdeb7af 步骤 3/11:ENV CGO_ENABLED=0 ---> 使用缓存 ---> fd86c2a9948c 步骤 4/11:WORKDIR /app/server ---> 使用缓存 ---> 8d59571272b7 步骤 5/11:复制 go.mod。 ---> 使用缓存 ---> d1c8a0f00d33 步骤 6/11:复制 go.sum。 ---> 使用缓存 ---> a1b4b294de83 步骤 7/11:运行 go mod 下载 ---> 使用缓存 ---> 803fd4244374 步骤 8/11:复制。 . ---> 37887395cadd 步骤 9/11:运行 去构建 -o 主要。 ---> 在 efe19e8eedc8 中运行去除中间 容器 efe19e8eedc8 ---> a115e9f17fc3 步骤 10/11:暴露 8080:8080 ---> 在 4155040d490c 中运行去除中间 容器 4155040d490c ---> 3e431bff9e84 步骤 11/11:CMD ["./main"] ---> 在 f5f9bab56ab0 中运行 移除中间容器 f5f9bab56ab0 ---> a8867809f163 构建成功 a8867809f163 成功标记 godocker_app:latest

C:\DEV\Go\src\godocker>docker-compose up -d 创建网络 带有默认驱动程序的“godocker_default”正在创建 godockerDB ... 完成创建 godockerAPP ...完成

C:\DEV\Go\src\godocker>dow e03697533be6 239278c1f0ea

C:\DEV\Go\src\godocker>dup

C:\DEV\Go\src\godocker>docker-compose down 删除 godockerAPP ... done 删除 godockerDB ... done 删除网络 godocker_default

C:\DEV\Go\src\godocker>docker-compose build 构建数据库步骤 1/3: FROM mysql:5.7 ---> 718a6da099d8 步骤 2/3:ENV MYSQL_ROOT_PASSWORD=root ---> 使用缓存 ---> 9087b3db47ac 步骤 3/3 : 复制 setup.sql /docker-entrypoint-initdb.d/ ---> 使用缓存 ---> 195614e33d96 成功构建 195614e33d96 成功标记 godocker_db:latest 构建应用程序步骤 1/11 : FROM golang:1.12 ---> ffcaee6f7d8b 步骤 2/11:ENV GO111MODULE=on ---> 使用缓存 ---> 25377bdeb7af 步骤 3/11:ENV CGO_ENABLED=0 ---> 使用缓存 ---> fd86c2a9948c 步骤 4/11:WORKDIR /app/server ---> 使用缓存 ---> 8d59571272b7 步骤 5/11:复制 go.mod。 ---> 使用缓存 ---> d1c8a0f00d33 步骤 6/11:复制 go.sum。 ---> 使用缓存 ---> a1b4b294de83 步骤 7/11:运行 go mod 下载 ---> 使用缓存 ---> 803fd4244374 步骤 8/11:复制。 . ---> 05a487690611 步骤 9/11:运行 去构建 -o 主要。 ---> 运行在 9d9cc6a3b214 去除中间 容器 9d9cc6a3b214 ---> ee950a1706f5 步骤 10/11:暴露 8080:8080 ---> 运行在 faa43abcfe40 去除中间 容器 faa43abcfe40 ---> 877be92dc560 步骤 11/11:CMD ["./main"] ---> 在 dd2dcf9ce4be 中运行 删除中间容器 dd2dcf9ce4be ---> cf9bea6d2348 成功构建 cf9bea6d2348 成功标记 godocker_app:latest

C:\DEV\Go\src\godocker>docker-compose up -d 创建网络 带有默认驱动程序的“godocker_default”正在创建 godockerDB ... 完成创建 godockerAPP ...完成

C:\DEV\Go\src\godocker>dow d56302aeb09b 0cef3117aac8

C:\DEV\Go\src\godocker>dup

C:\DEV\Go\src\godocker>docker-compose down 删除 godockerAPP ... done 删除 godockerDB ... done 删除网络 godocker_default

C:\DEV\Go\src\godocker>docker-compose build 构建数据库步骤 1/3: FROM mysql:5.7 ---> 718a6da099d8 步骤 2/3:ENV MYSQL_ROOT_PASSWORD=root ---> 使用缓存 ---> 9087b3db47ac 步骤 3/3 : 复制 setup.sql /docker-entrypoint-initdb.d/ ---> 使用缓存 ---> 195614e33d96 成功构建 195614e33d96 成功标记 godocker_db:latest 构建应用程序步骤 1/11 : FROM golang:1.12 ---> ffcaee6f7d8b 步骤 2/11:ENV GO111MODULE=on ---> 使用缓存 ---> 25377bdeb7af 步骤 3/11:ENV CGO_ENABLED=0 ---> 使用缓存 ---> fd86c2a9948c 步骤 4/11:WORKDIR /app/server ---> 使用缓存 ---> 8d59571272b7 步骤 5/11:复制 go.mod。 ---> 使用缓存 ---> d1c8a0f00d33 步骤 6/11:复制 go.sum。 ---> 使用缓存 ---> a1b4b294de83 步骤 7/11:运行 go mod 下载 ---> 使用缓存 ---> 803fd4244374 步骤 8/11:复制。 . ---> 8a1880bb8b56 步骤 9/11:运行 去构建 -o 主要。 ---> 运行在 84f20ebb4606 去除中间 容器 84f20ebb4606 ---> e0304d6454d4 步骤 10/11:暴露 8080:8080 ---> 在 7a0b6392be6e 中运行删除中间 容器 7a0b6392be6e ---> 3b18860bca2c 步骤 11/11:CMD ["./main"] ---> 运行在 018d6769b721 移除中间容器 018d6769b721 ---> bbf448ab621c 成功构建 bbf448ab621c 成功标记 godocker_app:latest

C:\DEV\Go\src\godocker>docker-compose up -d 创建网络 带有默认驱动程序的“godocker_default”正在创建 godockerDB ... 完成创建 godockerAPP ...完成

【问题讨论】:

  • 我在您的 docker compose 文件中看到容器名称是 godockerDB (这不过是您的 db DNS 名称),但在应用程序中尝试连接到 godockerxDB 。你能检查一下你在应用数据库连接字符串中的拼写错误吗?
  • 我添加了 x 以查看它如何改变结果,我现在包含了我的 main.go,您将看到 dodockerDB 作为主机名。
  • 嗯,好的。看起来问题是mysql不允许来自IP的连接。在mysql部署期间,您需要以某种方式将bind-address = 0.0.0.0添加到/etc/mysql/mysql.conf.d/mysqld.cnf文件的[mysqld] 部分。这将允许所有 IP 连接 mysql 服务器。
  • 或者,您可以尝试将 running 'GRANT ALL ON . 添加到 user@'%' IDENTIFIED BY 'password'; ' 部署后的 SQL。其中user 将是您的用户,password 将是 root 密码。
  • '没有这样的主机'不是连接拒绝。清楚。这是一个 DNS 问题。

标签: mysql docker docker-compose


【解决方案1】:

要连接,您必须使用 docker-compose.yml 中声明的服务名称而不是容器名称。

db:3306 // instead of godockerDB:3306

【讨论】:

  • 试过这个没有用,但是现在发现了另一个问题。之前不存在,我将恢复并重试
  • 使用“db”或“godockerDB”不会有任何区别。作为服务名称和容器名称(如果已定义)可以用作 dns 名称。两者都将指向同一个 IP。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-20
  • 1970-01-01
  • 2023-04-03
  • 1970-01-01
  • 1970-01-01
  • 2018-10-23
相关资源
最近更新 更多