状況
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コンテナを指定する場合はlocalhost
や127.0.0.1
ではなく<コンテナ名>
を指定する。
今回はコンテナ名がapp-db
なので
PROTOCOL := "tcp(app-db:3306)"
とすれば良い。