connection refused with go&mysql&docker - mysql

I'm trying to connect mysqlDB which is created on Docker from my local go file.
main.go
package main
import (
"database/sql"
"fmt"
_ "github.com/go-sql-driver/mysql"
)
func main() {
fmt.Println("Hello")
// All following 4 codes won't connect to the database.
// "db01" is docker container name. "test" is db name.
// db, err := sql.Open("mysql", "root:password#tcp(localhost:3306)/test")
// db, err := sql.Open("mysql", "root:password#tcp(localhost)/test")
// db, err := sql.Open("mysql", "root:password#tcp(db01)/test")
db, err := sql.Open("mysql", "root:password#tcp(db01:3306)/test")
if err != nil {
fmt.Println(err)
}
defer db.Close()
fmt.Println(db)
err = db.Ping()
if err != nil {
fmt.Println(err)
}
}
docker command
docker run --name db01 -dit -e MYSQL_ROOT_PASSWORD=password mysql:latest
error message
when trying with localhost:3306
dial tcp [::1]:3306: connect: connection refused
when trying with db01
dial tcp: lookup db01: no such host
mysql db is created on docker container without any issue, so I think connection between go file and docker container is not going well.
Do I have to create docker-compose.yml file?
I want to connect without it at now.
Thank you.

You created a docker container and ran MySQL in it. That container will have its own network address. You can publish a port of that container on your localhost by running:
docker run --name db01 -p 3306:3306 -dit -e MYSQL_ROOT_PASSWORD=password mysql:latest
This will publish the port 3306 of the container on localhost:3306. Then you can connect to it.
Alternatively, you can get the IP address of the container running using docker inspect <containerId>, and connect to that address:3306.

Related

Unable to ping mysql db docker in golang

I am new to golang, docker and mysql. I am trying to connect to mysql running in docker locally on my macos using golang.
Here is the code:
`package main
import (
"context"
"database/sql"
_ "github.com/go-sql-driver/mysql"
"log"
"time"
)
func dbConn() *sql.DB {
db, err := sql.Open("mysql", "root:Abc123$##tcp(172.17.0.2:3306)/test")
if err != nil {
log.Printf("Error %s when opening DB connection\n", err)
return nil
}
db.SetMaxOpenConns(10)
db.SetMaxIdleConns(10)
db.SetConnMaxLifetime(time.Minute * 2)
ctx, cancelfunc := context.WithTimeout(context.Background(), time.Second)
defer cancelfunc()
err = db.PingContext(ctx)
if err != nil {
log.Printf("Error %s pinging DB", err)
return db
}
log.Print("Connected to the DB successfully\n")
defer func() {
err := db.Close()
if err != nil {
log.Print(err)
}
}()
return db
}
func main() {
db := dbConn()
defer db.Close()
}`
I am running docker with the following command:
docker run --name mysql -e MYSQL_ROOT_PASSWORD=abcd1234 -p 3306:3306 -d mysql:8.0.30
I get the following error:
Error dial tcp 172.17.0.2:3306: i/o timeout pinging DB
docker is running locally. I created a test-db with command-line:
`mysql> create database test_db;`
and then did a
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| test_db |
+--------------------+
6 rows in set (0.00 sec)
Please help me understand my mistake here? Or what am I missing?
I used host.docker.internal in this docker-compose.yml file to create the mysql sever in docker.
version: '3'
services:
mysql-development:
image: mysql:8.0.30
environment:
MYSQL_ROOT_PASSWORD: xyz1234
MYSQL_DATABASE: test
ports:
- "3306:3306"
extra_hosts:
- "host.docker.internal:host-gateway"
Used this to run the docker image:
docker-compose -f docker-compose.yml up
Then connected to docker mysql instance using:
docker exec -it 24f058c73227 mysql -P 3306 --protocol=tcp -u root -p
Then created a separate user and granted all privileges to the new user.
mysql> CREATE user ‘user2’#‘172.19.0.1' IDENTIFIED BY ‘xyz1234’;
mysql> GRANT ALL PRIVILEGES ON *.* TO 'user2'#'172.19.0.1' WITH GRANT
OPTION;
This helped me connect to mysql server running on the docker locally on macos.

Can't connect to RDS mysql in Golang only when ECS

I try to lunch application in ECS.
There is no problem when lunching in my local docker environment.
But it can't accrss to api server in ECS because of rds connection problem.
I use golang in api server and mysql for db.
I call db.go in main.go
func main() {
db := db.NewDatabase(os.Getenv("MYSQL_USER"), os.Getenv("MYSQL_PASSWORD"), os.Getenv("MYSQL_HOST"))
Error occurs when connecting to rds database
func NewDatabase(user, password, host string) *Database {
db, err := sql.Open("mysql", user+":"+password+"#tcp("+host+":3306)/article")
if err != nil {
panic(err.Error())
}
err = db.Ping()
// error occurs here
if err != nil {
panic(err.Error())
}
I deploy it to elastic beanstalk.
I checked environment variables are correctly set.
Here is the full source code:
https://github.com/jpskgc/article
I expect there is no error in elastic beans.
But the actual is not.
I want to know solution for that.
Here is the error log in elastic beanstalk.
-------------------------------------
/var/log/containers/server-4c66c8d1848a-stdouterr.log
-------------------------------------
panic: dial tcp 172.31.26.91:3306: connect: connection timed out
goroutine 1 [running]:
article/api/db.NewDatabase(0xc00002401b, 0x4, 0xc00002a00f, 0xb, 0xc00002800b, 0x3c, 0xdb94f2)
/app/db/db.go:20 +0x3bc
main.main()
/app/main.go:18 +0xee
"connection timed out" means that there are firewall limitation, and you can also check your mysql whitelist, which should has ip of your ECS.

unable to connect to mysql running on my mac

I am using golang app , wrapped up in a docker container to connect to mysql db running on my localhost(not container). Her eis what I tried:
Docker File
FROM artifactory.cloud.com//golang:1.10-alpine3.7
RUN mkdir -p /go/src/github.kdc.mafsafdfsacys.com/perfGo/
WORKDIR /go/src/github.kdc.mafsafdfsacys.com/perfGo
COPY ./ $WORKDIR
RUN apk update && apk upgrade
RUN go build
RUN chmod +x ./entrypoint.sh
RUN ls
RUN chmod +x ./perfGo
ENTRYPOINT ["./entrypoint.sh"]
perfGo.go
package main
import (
"database/sql"
_ "github.com/go-sql-driver/mysql"
)
func main() {
db, err := sql.Open("mysql", "root:#tcp(localhost:3306)/testdb")
checkErr(err)
_,dbErr := db.Exec("USE testdb")
if err != nil {
panic(dbErr)
}
// insert
_, inErr := db.Query("INSERT INTO books VALUES('rewyrewryewwrewyt','dsfdsfs','fdsfasaf','55')")
defer db.Close()
// if there is an error inserting, handle it
if inErr != nil {
panic(inErr.Error())
}
}
func checkErr(err error) {
if err != nil {
panic(err)
}
}
entrypoint.sh
!/usr/bin/env bash
./perfGo
Command am using to build is
docker build .
command used to run the container:
docker run -p 3306:3306 -ti
The error that I see is
panic: dial tcp 127.0.0.1:3306: connect: connection refused
goroutine 1 [running]:
main.main()
/go/src/github.kdc.capitalone.com/midnight-tokens/perfGo/perf.go:22 +0x1d4
If I run the binary without the container, it runs totally fine on my mac, but when I try to run it as part of docker container, it fails to connect
If the application is running in a container, and the database is on the host, then the address of the database from the container is obviously not localhost (That is the loopback device of the container).
If you are using Docker For Mac, then you can use:
"docker.for.mac.localhost:3306" in place of "localhost:3306"

Why connect to Google Cloud SQL failed inside Docker container but success outside Docker container?

I've written a piece of code in Golang to test Google Cloud SQL:
package main
import (
"database/sql"
"flag"
"fmt"
_ "github.com/go-sql-driver/mysql"
)
var addr = flag.String("db", "", "The database address")
func main() {
flag.Parse()
db, err := sql.Open("mysql", *addr)
if err != nil {
fmt.Println("mysql open failed: ", err)
return
}
defer db.Close()
err = db.Ping()
if err != nil {
fmt.Println("mysql ping failed: ", err)
return
}
fmt.Println("mysql ping success")
}
I've tested the above code, the output is mysql ping success
Then I want to test this function inside Docker container, the Dockerfile following:
FROM golang
ADD . $GOPATH/src/github.com/pdu/gcloud-sql-test
RUN go install github.com/pdu/gcloud-sql-test
ENTRYPOINT ["gcloud-sql-test"]
CMD ["-db=\"user:passwd#tcp(gcloud.sql.ip.address:3306)/database\""]
After building the Docker image, and run the container, I got the following output:
mysql ping failed: Error 1045: Access denied for user '"user'#'my.local.ip.address' (using password: YES)
I've already configured that my local IP can access Google Cloud SQL. I don't know why it doesn't work inside Docker container but works outside Docker container.
Updates, I've fixed the issue because of Dockerfile error
FROM golang
ADD . $GOPATH/src/github.com/pdu/gcloud-sql-test
RUN go install github.com/pdu/gcloud-sql-test
CMD ["gcloud-sql-test", "-db=user:passwd#tcp(gcloud.sql.ip.address:3306)/database"]
The main difference is to remove the quotation mark in the Dockerfile:CMD parameter, while you need the quotation mark when you execute the program from Terminal.
Try
FROM golang
ADD . $GOPATH/src/github.com/pdu/gcloud-sql-test
RUN go install github.com/pdu/gcloud-sql-test
CMD ["gcloud-sql-test","-db=\"user:passwd#tcp(gcloud.sql.ip.address:3306)/database\""]
CMD and ENTRYPOINT are different commands
I've fixed the issue because of Dockerfile error
FROM golang
ADD . $GOPATH/src/github.com/pdu/gcloud-sql-test
RUN go install github.com/pdu/gcloud-sql-test
CMD ["gcloud-sql-test", "-db=user:passwd#tcp(gcloud.sql.ip.address:3306)/database"]
The main difference is to remove the quotation mark in the Dockerfile:CMD parameter, while you need the quotation mark when you execute the program from Terminal.

Connecting to mysql database with go

I'm trying to get a basic connect to my mysql server, but I can't seem to get it to actually connect. I know the credentials are valid and have all the permissions they need, but for some reason they're consistently rejected.
package main
import (
"fmt"
"database/sql"
_ "github.com/go-sql-driver/mysql"
"os"
)
func main() {
db, err:= sql.Open("mysql", "user:pass#tcp(localhost:3306)/scf")
if err != nil {
fmt.Println(err)
os.Exit(1)
}
q, err := db.Prepare("SELECT * from logins limit 5")
if err != nil {
fmt.Println(err)
os.Exit(1)
}
rows, err := q.Query()
if err != nil {
fmt.Println(err)
os.Exit(1)
}
i := 0
for rows.Next() {
i++
var title string
err = rows.Scan( &title )
fmt.Printf("Title: %s \n", title)
}
db.Close()
}
Edit:
Apparently I forgot to include the error:
dial tcp 127.0.0.1:3306: connection refused
exit status 1
connection refused generally means the port isn't open or is being blocked by a firewall. A couple things to check:
Is MySQL (on localhost) running? Is it on port 3306?
If you're on Windows, Mac or Linux, is there a firewall that might be blocking port 3306?
If you're on Linux, is SELinux enabled that might be blocking port 3306?
I faced a similar issue. I found out port was different on Mac. I Couldn't find it in my.cnf but the port was set during runtime which you can see using
ps ax | grep mysql