53
39

More than 3 years have passed since last update.

Go + gorm + gin と mysqlの環境をDockerで作ったった

Last updated at Posted at 2019-08-13

Go + gorm + gin と mysqlと言うありきたりな組み合わせでDockerの環境作りましたー!

今更ですがDocker触り始めて軽さに感動😭

環境もがっつり作ったのは初めてかも。。

以下の記事参考させていただきました!
Dockerで立てたmysqlにgolangから接続する方法
[golang]gormを使ってローカル環境のMySQLとCRUD操作
他のDockerコンテナからコンテナ内のMySQLに接続する

ディレクトリ構成

こんな感じ

/
├ docker-compose
├ .dockerignore
├ docker/
│ └ api/
│   └ Dockerfile
│ └ db/
│   └ Dockerfile
│   └ conf.d
│     └ mysql.conf 
├ src
   └ api/
      └ main.go
      └ start_app.sh

Dockerfile

docker/api/Dockerfile

どこでも見るような感じになってますが CMD が結構ネックです!


FROM golang:latest

COPY src/api /go/src/api  ← GOROOTが/goになるので

WORKDIR /go/src/api/

RUN go get -u github.com/gin-gonic/gin \  ← gormとginとドライバー
  && go get github.com/jinzhu/gorm \
  && go get github.com/go-sql-driver/mysql
  && apt-get install -y mariadb-client

CMD ["sh", "./start_app.sh"]  ←ハマった。。

docker/db/Dockerfile

こちらもそこまで特筆することはありません!


FROM mysql:5.7

RUN touch /var/log/mysql/mysqld.log ← ログファイル作っときましょう

docker-compose

上で作った2つのコンテナを取り扱う為にdocker-composeを使います。


version: '3'
services:
  api:
    links:
      - mysql ← サービス名(下のmysql)は好きな物で大丈夫です。
    build: ← buildの中にこの2つ書くと一番上のディレクトリから色々弄れる感覚です。
      context: . 
      dockerfile: ./docker/api/Dockerfile
    ports:
      - "8080:8080"
    volumes:
      - ./src/api:/go/src/api
  mysql:
    build: ./docker/db
    image: mysql:5.7
    restart: always
    environment:
      MYSQL_USER: root
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: sample
    hostname: mysql
    ports: 
      - "3306:3306"
    volumes:
      - ./docker/db/conf.d:/etc/mysql/conf.d
      - ./log/mysql:/var/log/mysql

conf.d/mysql.conf

これはmysqlの設定ファイルなんで参考までに!
(丸パクリさせてもらいましたw)


[mysqld]
character-set-server=utf8mb4       # mysqlサーバー側が使用する文字コード
explicit-defaults-for-timestamp=1   # テーブルにTimeStamp型のカラムをもつ場合、推奨
general-log=1                   # 実行したクエリの全ての履歴が記録される(defaultではOFFになっているらしい)
general-log-file=/var/log/mysql/mysqld.log # ログの出力先

[client]
default-character-set=utf8mb4               # mysqlのクライアント側が使用する文字コード

src/start_app.sh

ここすごいハマりました。。
結論から言うとmysqlサーバーが立ち上がる前にapiサーバーが立ち上がってしまうので立ち上がりを待つようにしています。(確実にもっと良い書き方あります。。)


# !/bin/bash

# MySQLサーバーが起動するまで待機する
until mysqladmin ping -h mysql -P 3306 --silent; do
  echo 'waiting for mysqld to be connectable...'
  sleep 2
done

echo "app is starting...!"
exec go run main.go

src/main.go

gormとginを使うとこまでなので多くは書いてません!
なんで他のパッケージに公開してるかは突っ込まないでくださいw


package main

import (
    "github.com/gin-gonic/gin"
    _ "github.com/jinzhu/gorm/dialects/mysql"
)

func main() {
    DBMigrate(DBConnect())
    r := gin.Default()
    r.GET("/ping", func(c *gin.Context) {
        c.JSON(200, gin.H{
            "message": "成功",
        })
    })
    r.Run(":8080")
}

type User struct {
    gorm.Model
    NickName string `json:"nickName"`
}

func DBMigrate(db *gorm.DB) *gorm.DB {
    db.AutoMigrate(&User{})
    return db
}


func DBConnect() *gorm.DB {
    DBMS := "mysql"
    USER := "root"
    PASS := "password"
    PROTOCOL := "tcp(mysql:3306)"   ここのmysqlはサービス名です
    DBNAME := "sample"
    CONNECT := USER + ":" + PASS + "@" + PROTOCOL + "/" + DBNAME + "?parseTime=true"
    db, err := gorm.Open(DBMS, CONNECT)
    if err != nil {
        panic(err.Error())
    }
    return db
}

起動


docker-compose build
docker-compose up

起動が確認できたら


curl http://localhost:8080/ping

で成功が返ってこれば問題ないです!


docker-compose up -d

を使っても良いんですけどどこかミスってて落ちてるの気づけないので最初はupで行きましょう!

終わり

mysqlサーバーとAPIサーバーの立ち上がりの順番でめちゃハマりました。。。

53
39
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
53
39