Golang MySQL Docker连接被拒绝

时间:2020-06-17 19:16:27

标签: mysql docker go docker-compose

我有一个使用docker-compose的应用程序,并且phpMyAdmin和Golang都得到connection refused。 在代码的注释中有调试语句。

是否有任何指向我做错事情的指针?

#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:connect:连接被拒绝<-MYSQL_HOST = fullstack-mysql

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

将连接字符串更改为:

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

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

用户docker应该具有所有特权。

1 个答案:

答案 0 :(得分:3)

您的Go应用正在尝试通过值MYSQL_HOST连接到127.0.0.1的MySQL。您需要将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