1

I have 2 containers, one for the main logic in my app and another for a mysql db. This is the docker-compose file

version: '3'
services:
    database:
        image: mysql
        container_name: mysql-db
        command: --default-authentication-plugin=mysql_native_password
        restart: always
        env_file:
          - environment-variables.env
        ports:
          - 3306:3306
    logic:
        container_name: main-logic
        build: ./logic/.

The logic is in golang and I am attempting to connect to the database. Here is the go code.

    err := godotenv.Load("/environment-variables.env")
    if err != nil {
        log.Fatalln("Error in fetching environment variables", err)
    }
    dataSourceName := fmt.Sprint("root:", os.Getenv("MYSQL_ROOT_PASSWORD"), "@tcp(docker.for.mac.localhost:3306)/some-db")
    log.Println(dataSourceName)
    db, err := sql.Open("mysql", dataSourceName)
    if err != nil {
        log.Fatalln("Some error in connecting to the database in the method", err)
    }
    db.SetMaxOpenConns(1)
    err = db.Ping()
    log.Println("Error is", err.Error())
    defer db.Close()

Within the environment variables file is

MYSQL_ROOT_PASSWORD=password
MYSQL_DATABASE=some-db

When I attempt to connect, I always get the error:

Error is Error 1045: Access denied for user 'root'@'localhost' (using password: YES)

How to resolve this?

twothreezarsix
  • 375
  • 3
  • 13
  • I see where you're setting `MYSQL_ROOT_PASSSWORD` for mysql, but were are you setting it for `logic` service? Incidentally the mysql image supports creating non-root user automatically; that would be preferred to using root https://hub.docker.com/_/mysql – erik258 Dec 15 '21 at 17:37
  • @DanielFarrell, I don't understand setting password for the logic service. The logic service is basically the golang code. So when the connection is made, the dataSourceName would contain the password right. Also, acc to the docs, it says that setting MYSQL_ROOT_PASSWORD will make it the default password for root, which is what I am doing – twothreezarsix Dec 15 '21 at 17:40
  • What is "the environment variables file" you mention? os.Getenv doesn't read any files. – Jonathan Hall Dec 15 '21 at 17:42
  • I edited the code. Forgot to add it before as it was in a function – twothreezarsix Dec 15 '21 at 17:44
  • @twothreezarsix `os.Getenv("MYSQL_ROOT_PASSWORD")` is used to build the dsn. `os.Getenv` returns empty string for unset environment variables. If you're not setting MYSQL_ROOT_PASSWORD for `logic` service, it will use an empty string as a password. – erik258 Dec 15 '21 at 17:45
  • I am using godotenv.Load for that reason. The env variables are loaded from the environment-variables file. I can see that the log prints the password as "password". This is why I am confused as to why it is still using root@localhost – twothreezarsix Dec 15 '21 at 17:48

1 Answers1

0

Here are the mistakes I made. Firstly, since the database and main logic are in containers, this means that the main logic accesses the database from the network docker creates for it and not from localhost. This is database:3306 and not docker.for.mac.localhost.

Secondly and more importantly, there should be a wait till the database is ready to accept connection. This should be done via a health check. Otherwise the database will always refuse connections.

Here are some links to answers that are useful:

Point 1 : panic: dial tcp 127.0.0.1:3306: connect: connection refused

Point 2 : https://stackoverflow.com/a/42757250/10740241

twothreezarsix
  • 375
  • 3
  • 13