title: Golang MySQL Docker connection refused
body: <p>I have an application that used docker-compose and I get <code>connection refused</code> for both phpMyAdmin and Golang.
  There are debug statements in the comments in the code.</p>
  
  <p>Any pointers to what I do wrong?</p>
  
  <pre><code>#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
  </code></pre>
  
  <pre><code>//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 &lt;-- 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...")
          }
      }
  }
  </code></pre>
  
  <pre><code>//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
  }
  
  </code></pre>
  
  <pre><code>#./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", "."]
  </code></pre>
  
  <pre><code>#./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
  </code></pre>
  
  <pre><code>#./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
  </code></pre>
  
  <pre><code>#./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://
  </code></pre>
  
  <p>This is how I create the database</p>
  
  <pre><code>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 ;
  </code></pre>
  
  <p>I tried using: MYSQL_HOST=fullstack-mysql</p>
  
  <p>Code updated above.</p>
  
  <p>Ping Error: dial tcp 23.195.69.108:3306: connect: connection refused &lt;-- MYSQL_HOST=fullstack-mysql</p>
  
  <p>Connection string:
  <code>docker:docker@tcp(fullstack-mysql:3306)/test_db</code></p>
  
  <p>After changing the connection string to:</p>
  
  <p><code>docker:docker@tcp(db_mysql:3306)/test_db</code></p>
  
  <p>Ping Error: Error 1044: Access denied for user 'docker'@'%' to database 'test_db'</p>
  
  <p>User docker should have all privileges.</p>