Golang not connecting to MySQL thought jinzhu/gorm and hosted by Docker

Basically:

dsn := fmt.Sprintf(
	"%s:%s@db:3306/%s?charset=utf8&parseTime=True&loc=Local",
	os.Getenv("DB_USER"),
	os.Getenv("DB_PASS"),
	os.Getenv("DB_NAME"),
)

log.Println(dsn)

db, err := gorm.Open("mysql", dsn)

if err != nil {
	log.Fatal(err)
}

I’m getting:

app_1  | 2016/08/08 19:52:57 gosql:gosql@db:3306/gosql?charset=utf8&parseTime=True&loc=Local
app_1  | 2016/08/08 19:52:57 default addr for network 'db:3306' unknown

My docker-compose.yml

version: '2'
services:
    db:
        image: mysql:5.7
        environment:
            - MYSQL_RANDOM_ROOT_PASSWORD=yes
            - MYSQL_DATABASE=${DB_NAME}
            - MYSQL_USER=${DB_USER}
            - MYSQL_PASSWORD=${DB_PASS}
        volumes:
            - ./db/data:/var/lib/mysql
    app:
        build: .
        links:
            - db

Golang container isn’t finding MySQL at db :frowning:
Any hints?

As db is a link at app it should be already a dependency, right? Should I do something to make sure that MySQL container will start and be ready before Golang’s container?

Ps.: I’m using the official image. 1.6-onbuild.

EDIT

Ok, got it. Its about two factors.

First: it was missing a tcp() wrapper thing, DNS should be:
gosql:gosql@tcp(db:3306)/gosql?charset=utf8&parseTime=True&loc=Local

But this wasn’t all.

Second: dependency on Docker doesn’t necessary handles “ready” state.
MySQL does starts before Golang, but, Golang is faster about trying to connect to the DB, since it isnt waiting for a HTTP call, for example.

Solution: https://docs.docker.com/compose/startup-order/

But, since this post is up and Docker recommends this to be handled by the application.

Does anyone know a good solution for TCP connection retries?

2 Likes

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.