How to connect dockers with compose, mysql, and golang

huangapple go评论150阅读模式
英文:

How to connect dockers with compose, mysql, and golang

问题

我有一个名为mariadb的数据库docker,还有一个使用golang的web docker。我想要做的是使用compose将这两个docker连接起来,但是在我的golang代码中,我需要提前知道数据库docker的IP地址。

Golang main.go:

db, err := sql.Open("mysql", 
"root:passsword@tcp(<应该是数据库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

再次强调,我不能简单地将主机设置为localhost,因为我使用的数据库在一个docker中,通常是类似于172.17.0.2或.3,但有时会发生变化。谢谢!

英文:

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(&quot;mysql&quot;, 
&quot;root:passsword@tcp(&lt;should_be_database_docker_ip&gt;:3306)/database&quot;)

Docker-compose.yml

version: &#39;3&#39;

services:
  web:
    image: web_docker
    ports:
      - &quot;8080&quot;
    depends_on:
      - database

  database:
    image: mariadb
    ports:
      - &quot;3306&quot;
    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!

答案1

得分: 2

你可以直接使用Docker服务名称database,而不是容器IP。

更新:
你还应该共享端口,例如:

"3306:3306"

否则端口将会随机映射。

查看以下命令的输出:

docker-compose ps

更新2:
根据MySQL Docker镜像文档,你还需要定义更多的环境变量,例如MYSQL_DATABASE

英文:

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

UPD
You also should share ports like

&quot;3306:3306&quot;

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

答案2

得分: 2

你也可以考虑将它们放在一个网络中。这样,你就可以从你的 Web 容器中访问数据库 database:3306。

这种方法的优点是数据库不会暴露给外部世界(你的本地机器),只有 mynet 网络上的容器才能看到它。

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"

(代码未经测试)

英文:

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: &#39;3&#39;

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: &quot;bridge&quot;

(code not tested)

答案3

得分: 0

不需要默认添加网络,它们由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

这样你就可以使用 mariadb,Docker的iptables将充当DNS服务器。因此,在Go代码中,将ipport替换为container_name,如下所示:

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

    if err != nil {
        panic(err)
    }
    ...
}
英文:

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

version: &#39;3.9&#39;
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 := &quot;user:xxxx@tcp(mariadb)/dbname?charset=utf8&quot;
    db, err := gorm.Open(mysql.Open(dsn), &amp;gorm.Config{})

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

huangapple
  • 本文由 发表于 2017年8月17日 21:40:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/45736762.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定