【问题标题】:Golang MySQL Docker connection refusedGolang MySQL Docker 连接被拒绝
【发布时间】:2020-10-07 17:29:21
【问题描述】:

我有一个使用 docker-compose 的应用程序,我得到了 phpMyAdmin 和 Golang 的 connection refused。 代码中的cmets中有debug语句。

任何指向我做错了什么?

#docker-compose.yml
version: '3'
services:
  fullstack-mysql:
    container_name: db_mysql
    build:
      context: ./MySQL
    ports:
      - 3306:3306
    volumes:
      - database_mysql:/var/lib/mysql
    networks:
      - fullstack

  app:
    container_name: golang_app
    env_file:
      - ./Go/.env
    build:
      context: ./Go
    ports:
      - 9000:9000
    restart: on-failure
    volumes:
      - api:/usr/src/app/
    depends_on:
      - fullstack-mysql
    networks:
      - fullstack

  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    container_name: phpmyadmin_container
    env_file:
      - ./MySQL/.env
    depends_on:
      - fullstack-mysql
    environment:
      - PMA_HOST=fullstack-mysql #Note the "mysql". Must be the name of the what you used as the mysql service.
      - PMA_USER=root
      - PMA_PORT=3306
      - PMA_PASSWORD=root
    ports:
      - 9090:80
    restart: always
    networks:
      - fullstack

volumes:
  api:
  database_mysql:

networks:
  fullstack:
    driver: bridge
//server.go
package main

import (
    "database/sql"
    "fmt"
    "log"
    "net"
    "net/http"
    "os"
    "os/exec"
    "strconv"
    "strings"

    _ "github.com/go-sql-driver/mysql"
    "github.com/jimlawless/whereami"
)

func setConfig() {
    config = Configs{}
    config.cookieName = os.Getenv("COOKIE_NAME")
    config.cookieValue = os.Getenv("COOKIE_VALUE")
    age, err := strconv.Atoi(os.Getenv("COOKIE_MAX_AGE"))
    if err != nil {
        log.Println(whereami.WhereAmI(), err.Error())
    }
    config.cookieMaxAge = age

    config.cookieHTTPOnly, err = strconv.ParseBool(os.Getenv("COOKIE_HTTP_ONLY"))
    if err != nil {
        log.Println(whereami.WhereAmI(), err.Error())
    }

    config.cookiePath = os.Getenv("COOKIE_PATH")
    config.domain = os.Getenv("DOMAIN")
    config.port = os.Getenv("PORT")
    config.apiKey = os.Getenv("APP_KEY")
    config.apiVersion = os.Getenv("API_VERSION")
    config.apiPath = os.Getenv("API_PATH")
    config.protocol = os.Getenv("PROTOCOL")
    config.mysqlDB = os.Getenv("MYSQL_DATABASE")
    config.mysqlHost = os.Getenv("MYSQL_HOST")
    config.mysqlPassword = os.Getenv("MYSQL_PASSWORD")
    config.mysqlPort = os.Getenv("MYSQL_PORT")
    config.mysqlUser = os.Getenv("MYSQL_USER")
    config.mysqlDriver = os.Getenv("MYSQL_DRIVER")
}

func main() {
    defer recoverPanic()
    setConfig()
    err := db()
    if err != nil {
        //log.Fatal(whereami.WhereAmI(), err.Error())
        log.Println(whereami.WhereAmI(), err.Error())
    }

    fmt.Println(config)
    //{panda 123456987 0 true / 127.0.0.1 :9000 secret-sauce v1 /api/ http:// docker docker 3306 127.0.0.1 test_db mysql}

    routes()
}

func (fs FileSystem) Open(path string) (http.File, error) {
    f, err := fs.fs.Open(path)
    if err != nil {
        return nil, err
    }

    s, err := f.Stat()
    if s.IsDir() {
        index := strings.TrimSuffix(path, "/") + "/index.html"
        if _, err := fs.fs.Open(index); err != nil {
            return nil, err
        }
    }

    return f, nil
}

func db() error {
connStr:=config.mysqlUser+":"+config.mysqlPassword+"@tcp("+config.mysqlHost+":"+config.mysqlPort+")/"+config.mysqlDB
    //Ping Error: dial tcp: lookup db:127.0.0.1:3306: no such host
    //Ping Error: dial tcp 23.195.69.108:3306: connect: connection refused <-- MYSQL_HOST=fullstack-mysql

    //connStr:=config.mysqlUser+":"+config.mysqlPassword+"@tcp(db:"+config.mysqlPort+")/"+config.mysqlDB
    //Ping Error: dial tcp 23.195.69.108:3306: connect: connection refused

    log.Println(connStr)
    //docker:docker@tcp(fullstack-mysql:3306)/test_db
    db, err := sql.Open(config.mysqlDriver, connStr)
    if err != nil {
        log.Println(whereami.WhereAmI(), err.Error())
    } else {
        log.Println(fmt.Sprintf("%s", db), whereami.WhereAmI())
    }
    defer db.Close()

    err = db.Ping()
    if err != nil {
        log.Println("Ping Error: " + err.Error())
    } else {
        dbx.conn = db
    }

    log.Println(fmt.Sprintf("%s", dbx.conn), whereami.WhereAmI())
    log.Println(fmt.Sprintf("%T", dbx.conn), whereami.WhereAmI())
    return err
}

func recoverPanic() {
    if rec := recover(); rec != nil {
        err := rec.(error)
        log.Println(whereami.WhereAmI(), err.Error())

        var l *net.TCPListener
        file, err := l.File()
        if err != nil {
            log.Println(whereami.WhereAmI(), err.Error())
        }

        path := os.Args
        args := []string{"-graceful"}

        cmd := exec.Command(path[0], args...)
        cmd.Stdout = os.Stdout
        cmd.Stderr = os.Stderr
        cmd.ExtraFiles = []*os.File{file}

        err2 := cmd.Start()
        if err2 != nil {
            log.Println(whereami.WhereAmI(), err2.Error())
        } else {
            log.Println(whereami.WhereAmI(), "Restarted...")
        }
    }
}
//structs.go
package main

import (
    "database/sql"
    "net/http"
)

var dbx dbConnection
var config Configs

type FileSystem struct {
    fs http.FileSystem
}

type dbConnection struct {
    conn *sql.DB
}

type Configs struct {
    cookieName     string
    cookieValue    string
    cookieMaxAge   int
    cookieHTTPOnly bool
    cookiePath     string
    domain         string
    port           string
    apiKey         string
    apiVersion     string
    apiPath        string
    protocol       string
    mysqlUser      string
    mysqlPassword  string
    mysqlPort      string
    mysqlHost      string
    mysqlDB        string
    mysqlDriver    string
}

#./Go/Dockerfile
FROM golang:alpine AS builder
ENV GO111MODULE=on
ENV MYSQL_PASSWORD=$(MYSQL_PASSWORD)
ENV MYSQL_USER=$(MYSQL_USER)
ENV MYSQL_DATABASE=$(MYSQL_DATABASE)
ENV MYSQL_PORT=$(MYSQL_PORT)
ENV MYSQL_DRIVER=$(MYSQL_DRIVER)
RUN mkdir /app
ADD . /app/
WORKDIR /app
COPY ./structs.go .
COPY ./handlers.go .
COPY ./server.go .
COPY ./favicon.ico .
COPY ./assets /assets
RUN go mod init stuff.com
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build $(ls -1 *.go)
EXPOSE 9000
CMD ["go", "run", "."]
#./MySQL/Dockerfile
FROM mysql:8.0
ENV MYSQL_PASSWORD=$(MYSQL_PASSWORD)
ENV MYSQL_USER=$(MYSQL_USER)
ENV MYSQL_DATABASE=$(MYSQL_DATABASE)
ENV MYSQL_PORT=$(MYSQL_PORT)
ENV MYSQL_DRIVER=$(MYSQL_DRIVER)
COPY test.sql /docker-entrypoint-initdb.d/test.sql
EXPOSE 3306
#./Mysql/.env
MYSQL_ROOT_PASSWORD=root
MYSQL_PASSWORD=docker
MYSQL_USER=docker
MYSQL_DATABASE=test_db
MYSQL_HOST=127.0.0.1
MYSQL_PORT=3306
MYSQL_DRIVER=mysql
#./Go/.env
MYSQL_ROOT_PASSWORD=root
MYSQL_PASSWORD=docker
MYSQL_USER=docker
MYSQL_DATABASE=test_db
MYSQL_HOST=fullstack-mysql
MYSQL_PORT=3306
MYSQL_DRIVER=mysql

COOKIE_NAME=panda
COOKIE_VALUE=123456987
COOKIE_MAX_AGE=0
COOKIE_PATH=/
COOKIE_HTTP_ONLY=true
DOMAIN=127.0.0.1
PORT=:9000
API_PATH=/api/
API_VERSION=v1
APP_KEY=secret-sauce
PROTOCOL=http://

这就是我创建数据库的方式

CREATE DATABASE IF NOT EXISTS test_db;

CREATE USER IF NOT EXISTS 'root'@'%' IDENTIFIED BY 'root';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;

CREATE USER IF NOT EXISTS 'docker'@'%' IDENTIFIED BY 'docker';
GRANT ALL PRIVILEGES ON *.* TO 'docker'@'%' WITH GRANT OPTION;

SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";

CREATE TABLE IF NOT EXISTS `colors` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `name` (`name`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

我尝试使用:MYSQL_HOST=fullstack-mysql

上面更新了代码。

Ping 错误:拨打 tcp 23.195.69.108:3306:连接:连接被拒绝

连接字符串: docker:docker@tcp(fullstack-mysql:3306)/test_db

将连接字符串改为:

docker:docker@tcp(db_mysql:3306)/test_db

Ping 错误:错误 1044:用户 'docker'@'%' 拒绝访问数据库 'test_db'

用户 docker 应该拥有所有权限。

【问题讨论】:

  • 您的 Go 应用程序 MYSQL_HOST 是 localhost。将其更改为 fullstack-mysql

标签: mysql docker go docker-compose


【解决方案1】:

您的 Go 应用程序正在尝试连接到位于 MYSQL_HOST 的 MySQL,其值为 127.0.0.1。您需要将 MYSQL_HOST 设置为 container_name,即 Go 应用程序的 db_mysql

修正MYSQL_HOST后,尝试连接字符串如下:

// Connecting string: docker:docker@tcp(db_mysql:3306)/test_db")
connStr:=config.mysqlUser+":"+config.mysqlPassword+"@tcp("+config.mysqlHost+":"+config.mysqlPort+")/"+config.mysqlDB

【讨论】:

  • 啊,好吧,你正在使用container_name: db_mysql。尝试使用db_mysql 作为主机名而不是fullstack-mysql
猜你喜欢
  • 1970-01-01
  • 2020-07-04
  • 2018-06-08
  • 2020-01-19
  • 2016-03-08
  • 2020-10-08
  • 1970-01-01
  • 2017-10-01
  • 2021-06-24
相关资源
最近更新 更多