2

I am trying to connect my golang program to a mssql server that I run on a container using docker. the golang is also running on a docker container. the go script seems to be able to successfully connect to the database, but can't perform any operation on it. So,

db, err := sql.Open("mysql","SA:YourStrong!Passw0rd@tcp(127.0.0.1:1433)/")

if err != nil {
    panic(err)
}

defer db.Close()
fmt.Println("Success open database")

This prints out the "success open database", however the next portion of the code throws a panic,

_,err = db.Exec("CREATE DATABASE currency1")
if err != nil {
    panic(err)
}

fmt.Println("Success CREATE database")

After using docker to build and run it, this is what I got

GO MYSQL START
Success open database
panic: dial tcp 127.0.0.1:1433: getsockopt: connection refused

This is the command I used to run the mssql database:

docker run -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=YourStrong!Passw0rd' -e 'MSSQL_PID=Express' -p 1433:1433 --name sql1 -d microsoft/mssql-server-linux:latest
Ntwobike
  • 2,406
  • 1
  • 21
  • 27
user10560513
  • 17
  • 1
  • 4

3 Answers3

1

Maybe you should Ping() the database when you connected it.

db, err := sql.Open("mysql","SA:YourStrong!Passw0rd@tcp(127.0.0.1:1433)/")
if err != nil {
    panic(err)
}
if err := db.Ping();err!=nil{
    panic(err)
}

defer db.Close()
fmt.Println("Success open database")

Open() doesn't mean connected the database correctly.

The otherwise, like Dhama had said, your database host is wrong. Hope this can help you.

Laily
  • 4,024
  • 1
  • 14
  • 14
0

First thing first you should understand how networking in docker works. Every running container will treated as single virtual node. They have their own IP to connect to each other. In your case, there will 2 running container, 1 for Go and 1 for SQLServer. So there is Go container wanted to connect to SQLServer container. The address 127.0.0.1 or localhost means it's for it self(a loopback address). To connect it you can use the container name as the address (because IP is randomly assigned). Actually it converted to IP, docker doing this for you. Based on your docker run above, it should be sql1.

Hope it helps.

Dharma Saputra
  • 1,524
  • 12
  • 17
  • You also need to `docker network create` a network (default options is fine) and `docker run --net` both containers on that network. – David Maze Oct 26 '18 at 01:43
  • Hi, thanks for answering my question. However, I am still having difficulties as it does not seem to work. I used "docker create network my-net". then of course add the line --network=my-net to both my docker run commands. Docker did detect both containers as the command "docker inspect my-net" shows both containers. however, when I used docker to run both the sql and go script, no panic was thrown. it's just "GO MYSQL START Success open database". P.S. I also changed my go script to ==> db, err := sql.Open("mysql","SA:YourStrong!Passw0rd@tcp(sql1.my-net:1433)/") – user10560513 Oct 26 '18 at 11:02
0

Had the same issue otherway around from docker container to local mysql server, the trick was to comment bind-address in my.cnf. Usually its bind only to the loopback address, and refuse connection from outside including docker network. You can give a try to create a my.cnf like below and mount it to mysql config via volume(-v).

#bind-address                   = 127.0.0.1
Ntwobike
  • 2,406
  • 1
  • 21
  • 27