william205
william205

Reputation: 688

Unable to connect to mysql server with go and docker - dial tcp 127.0.0.1:3306: connect: connection refused

I have Mysql Community Server installed on my mac, it is set up and is working, I can connect to it on localhost:3306 using Navicat for MySQL. However, whenever I try and connect to the database from my go app which is running using docker-compose, I get the following error:

dial tcp 127.0.0.1:3306: connect: connection refused

This is my go code:

// dbUser, dbPassword, & dbName are all variables that definitely contain the correct values
db, err = sql.Open("mysql", dbUser+":"+dbPassword+"@tcp(localhost:3306)/"+dbName)

if err != nil {
    panic(err.Error())
}

defer db.Close()

query, err := db.Query("INSERT INTO test_table(test_field) VALUES(This is a test)")

if err != nil {
    panic(err.Error())
}

defer query.Close()

and I am importing:

"database/sql"
_ "github.com/go-sql-driver/mysql"

Any help would be really appreciated, thank you.

Upvotes: 10

Views: 34615

Answers (5)

Teocci
Teocci

Reputation: 8955

I think the best way to handle this is using the docker iptables.

If your docker-composer.yml

version: '3.9'
services:
    api:
        container_name: webapi
        restart: on-failure
        depends_on:
            - mariadb
        ...
   db:
        image: mariadb
        container_name: mariadb
        volumes:
            - database:/var/lib/mysql
        ports:
            - 3306:3306
        ...

You can use the container_name of the db service like this.

func main() {
  dsn := "user:pass@tcp(mariadb)/dbname?charset=utf8"
  db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})

  if err != nil {
    panic(err.Error())
  }
}

Super easy, this is recommend if you db service has a dynamic IP.

Upvotes: 1

Hashir Labs
Hashir Labs

Reputation: 320

i used my local machine ip address to fix the issue , this is to connect to my mysql server running on my local from a docker-compose

Upvotes: 1

Jake Boomgaarden
Jake Boomgaarden

Reputation: 3606

My solution ended up being a combination of the answers on this page. I was receiving the error:

dial tcp 127.0.0.1:3306: connect: connection refused

And my connection was constructed like so:

db, err := sql.Open("mysql",  "root:password@/mydbname?parseTime=true")

I read what @Cosmic Ossifrage had wasn't sure how to implement it so i applied the answer given by Vitah. this did not work because mysql:3306 was not a location that docker understood so connection failed. I then applied @Cosmic Ossifrage's solution with Vitah's to get a working setup.

db, err:= sql.Open("mysql", "root:password@tcp(docker.for.mac.localhost:3306)/mydbname?parseTime=true")

Hope this helps anyone searching for the answer! Thank you to the other contributors for helping me piece it together

Upvotes: 1

Vitah
Vitah

Reputation: 137

You should open like this:

db, err := sql.Open("mysql", "root:root@tcp(mysql:3306)/GoLife")

mysql is docker-compose service name.

Upvotes: 12

Cosmic Ossifrage
Cosmic Ossifrage

Reputation: 5379

You can't connect to localhost from Docker (especially on a Mac, where Docker runs in a Linux VM under the surface) and expect to access the services provided by the host machine.

However, there is functionality to access the host machine by IP address using the special hostname docker.for.mac.localhost. Absent any other Docker networking issues, amending your connection string to use docker.for.mac.localhost:3306 should resolve this issue and permit access to services on the host machine.

(More details about this workaround available in the Docker docs.)

Upvotes: 15

Related Questions