Lorraine
Lorraine

Reputation: 71

How to connect dockers with compose, mysql, and golang

I have a database docker that we'll call mariadb and I also have an web docker that uses golang. What I'm trying to do is connect the two dockers using compose, but in my golang code, I have to know the database docker's ip address ahead of time.

Golang main.go:

db, err := sql.Open("mysql", 
"root:passsword@tcp(<should_be_database_docker_ip>:3306)/database")

Docker-compose.yml

version: '3'

services:
  web:
    image: web_docker
    ports:
      - "8080"
    depends_on:
      - database

  database:
    image: mariadb
    ports:
      - "3306"
    environment:
      - MYSQL_ROOT_PASSWORD=password
    volumes:
      - /data:/var/lib/mysql

Again for clarification, I cannot simply make the host be localhost because the database I'm using is in a docker and is usually something like 172.17.0.2 or .3 but sometimes it changes. Thank you!

Upvotes: 7

Views: 6077

Answers (3)

Teocci
Teocci

Reputation: 8955

It is not necessary to add the networks by default they are handle by docker.

version: '3.9'
services:
    api:
        container_name: webapi
        build:
            context: .
            dockerfile: Dockerfile
        restart: unless-stopped
        depends_on:
            - mariadb
        ports:
            - 8080:8080
    mariadb:
        image: mariadb
        container_name: mariadb
        restart: unless-stopped
        environment:
            - ROOT_PASSWORD=xxxx
            - MYSQL_USER=user
            - MYSQL_PASSWORD=xxxx
            - MYSQL_DATABASE=dbname
        volumes:
            - database:/var/lib/mysql
        ports:
            - 3306:3306

This way you can use mariadb and the docker iptable will act like a DNS Server. So, in go replace the ip and port with the container_name like this:

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

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

Upvotes: 0

jonathan-dev
jonathan-dev

Reputation: 455

You might also consider putting them together in a network. This way you are able to access the database on database:3306 from your web container. This approach has the advantage that database is NOT exposed to the outside world (your local machine) and only containers on the mynet network are able to see it.

version: '3'

services:
  web:
    image: web_docker
    ports:
      - 8080:8080
    depends_on:
      - database
    networks:
      - mynet

  database:
    image: mariadb
    environment:
      - MYSQL_ROOT_PASSWORD=password
    volumes:
      - /data:/var/lib/mysql
    networks:
      - mynet
 networks:
   mynet:
     driver: "bridge"

(code not tested)

Upvotes: 3

Andrei
Andrei

Reputation: 145

You can just use your docker service name database, instead of container ip

UPD You also should share ports like

"3306:3306"

or ports will maps randomly

see output of

docker-compose ps

UPD2 according to mysql docker image doc you also need to define more environment variables, eg MYSQL_DATABASE

Upvotes: 2

Related Questions