7
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

Dockerでmysqlに接続できない(GO/gin/GORM)

状況

Dockerで簡単なSPAアプリケーションの作成中にDBサーバとして作成したMySQLコンテナにバックエンドサーバ(GO/gin)がアクセスする際に

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

というエラーが発生する。
以下にエラーが発生したコンテナの情報とソースコードを記載し、最後に解決策を示す。

コンテナの設定

ネットワーク

$ docker network create app-nw

DBコンテナ

# コンテナを作成して起動
$ docker run --name app-db --network app-nw -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root -d mysql
# 作成したMySQLコンテナに入りテーブルとレコードを作成
$ docker exec -it app-db bash
$ mysql uroot proot
mysql > create database shop;
mysql > use shop;
mysql > create table Product (
    -> ID int NOT NULL PRIMARY KEY,
    -> Name varchar(50) NOT NULL,
    -> Author varchar(50) NOT NULL
    -> );
mysql > insert into Product values (1, 'banana', 'tanaka');
# 確認用
mysql> select * from Product;
+----+--------+--------+
| ID | Name   | Author |
+----+--------+--------+
|  1 | banana | tanaka |
+----+--------+--------+
1 row in set (0.00 sec)
mysql > exit;
$ exit

バックエンドコンテナ

# コンテナを作成して起動
$ docker run --name app-webapi --network app-nw -p 8080:8080 -it ubuntu /bin/bash
# 必要なパッケージを導入
$ apt update
$ apt install -y wget
$ apt install -y git
$ wget https://golang.org/dl/go1.15.linux-amd64.tar.gz
$ tar -C /usr/local -xaf go1.15.linux-amd64.tar.gz
$ export PATH=$PATH:/usr/local/go/bin
$ go version
# インストールできていればバージョンが表示される
go version go1.15 linux/amd64
$ go get github.com/gin-gonic/gin
$ go get github.com/go-sql-driver/mysql
$ go get github.com/jinzhu/gorm

ソースコード

main.go

package main

import (
  "fmt"
  "github.com/jinzhu/gorm"
  _ "github.com/jinzhu/gorm/dialects/mysql"
)

type Product struct {
  ID int `gorm:"primary_key;not null"`
  Name string `gorm:"type:varchar(50);packanot null"`
  Author string `gorm:"type:varchar(50);packanot null"`
}

func connect() *gorm.DB {
  DBMS := "mysql"
  USER := "root"
  PASS := "root"
  PROTOCOL := "tcp(localhost:3306)"
  DBNAME := "shop"
  CONNECT := USER + ":" + PASS + "@" + PROTOCOL + "/" + DBNAME
  db, err := gorm.Open(DBMS, CONNECT)

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

  db.Set("gorm:table_options", "ENGINE=InnoDB")
  db.SingularTable(true)
  db.AutoMigrate(&Product{})

  fmt.Println("db connected: ", &db)
  return db
}

func getAllProduct() [] Product {
  db := connect()
  var products []Product
  db.Find(&products)
  defer db.Close()

  return products
}

func main() {
  results := getAllProduct()
  fmt.Println(results)
}

実行結果

# /appにmain.goを作成して実行する
$ go run main.go
panic: dial tcp 127.0.0.1:3306: connect: connection refused

解決策

main.goのconnect関数を以下のように修正する。

func connect() *gorm.DB {
  DBMS := "mysql"
  USER := "root"
  PASS := "root"
  PROTOCOL := "tcp(app-db:3306)"
  DBNAME := "shop"
  CONNECT := USER + ":" + PASS + "@" + PROTOCOL + "/" + DBNAME
  db, err := gorm.Open(DBMS, CONNECT)
}

解説

dockerでgo(gin/gorm)サーバからDBコンテナを指定する場合はlocalhost127.0.0.1ではなく<コンテナ名>を指定する。
今回はコンテナ名がapp-dbなので

PROTOCOL := "tcp(app-db:3306)"

とすれば良い。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
7
Help us understand the problem. What are the problem?