はじめに
Go(Echo)を用いたAPIサーバを構築したい方向けとなっております。
この記事では、Docker上でGoとMySQlを接続できる所まで説明しています。
間違いや改善点などあればお気軽に仰っていただけると幸いです。
環境
- Docker:v24.0.6
- Docker Compose:v2.4.1
最終的な構成図
.
├── docker-compose.yml
├── golang
│ ├── Dockerfile
│ └── app
│ ├── go.mod
│ ├── go.sum
│ └── main.go
└── mysql
├── Dockerfile
└── .env
Docker ComposeでGoとMySQLを接続する
まず初めに、プロジェクト直下にdocker-compose.yml
を作成します。
version: "3.8"
services:
go:
container_name: go
build: ./golang
tty: true
ports:
- "8080:8080"
env_file:
- ./mysql/.env
depends_on:
- db
volumes:
- ./golang/app:/go/src/app
networks:
- golang_test_network
db:
container_name: db
build: ./mysql
tty: true
platform: linux/x86_64
ports:
- 3306:3306
env_file:
- ./mysql/.env
volumes:
- mysql_test_volume:/var/lib/mysql
networks:
- golang_test_network
volumes:
mysql_test_volume:
name: mysql_test_volume
networks:
golang_test_network:
external: true
一つづつ説明していきます。
-
version
- Docker Composeのバージョンです。特にこだわりがなければ最新のものを記述した方が良いと思います。
-
services
- 作成したいサービス(コンテナ)を列挙します。今回は、
go
とdb
の2つのサービスを作成します。
- 作成したいサービス(コンテナ)を列挙します。今回は、
-
container_name
- コンテナの名前です。(無くてもよい)
-
build
- 用意したDockerfileよりビルドする場合、Dockerfileへの相対パスを記述します。
- ここで定義された情報をもとにDockerをビルドし、そのビルドしたイメージからコンテナを起動します。
-
tty
- ttyは標準入出力先のデバイスのことです。
tty:true
とすることでコンテナが正常終了するのを防げるため、コンテナの中に入ってサーバを立てたりすることができます。
- ttyは標準入出力先のデバイスのことです。
-
ports
- ポートの開放を行います。
ホストのポート:コンテナのポート
のように記述します。 - ホストでポートが被らないように、
8081:8080
とするのも良いと思います。
- ポートの開放を行います。
-
env_file
- ファイルに定義された環境変数を読み取り、コンテナへ定義します。
- ymlに直接記述しても出来ますが、個人的には分けた方が可読性も保守性も上がるのでお勧めです。
-
depends_on
- 依存関係を定義してコンテナの起動順序を制御します。
- 上記の例では、dbコンテナが起動した後にgoコンテナが起動されます。
-
volumes
- コンテナの外部に保管し、データを永続化します。
-
ホスト側の相対パス:コンテナの絶対パス
のように記述します。
-
networks
- Dockerコンテナ間で通信を行うためのもので、同名のネットワークが記述されたコンテナ間で通信を行うようになります。
-
platform
- どのプラットフォームに対応したイメージを生成するのか指定します。
Goの設定
次に、Goのディレクトリを作成し、以下の構成にします。
.
├── docker-compose.yml
└── golang
├── Dockerfile
└── app
└── main.go
golang/Dockerfile
FROM golang:1.19.2-alpine
ENV GO111MODULE on
RUN apk update && \
apk --no-cache add git && \
apk add bash
RUN mkdir /go/src/app
WORKDIR /go/src/app
CMD ["go", "run", "main.go"]
- 1行目:Dockerイメージのベースとなるイメージを指定します。
- 2行目:go moduleをONにします。これにより、go.modでパッケージの管理を行うようにします。
- 4~6行目:コンテナ内にgitやbashをインストールします。
- 8~9行目:ディレクトリを作成し、作業スペースとして指定します。
- 11行目:オプションを指定し、コマンドを実行します。
golang直下にappディレクトリを作成し、main.goを作成します。
データベース接続には、GoのORMであるgormを使用しています。
golang/app/main.go
package main
import (
"fmt"
"log"
"os"
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
// MySQLに作成するUserテーブルの定義
type User struct {
// gorm.Modelをつけると、idとCreatedAtとUpdatedAtとDeletedAtが作られる
gorm.Model
Name string
Age int
}
// DBを起動させる
func dbInit() *gorm.DB {
// [ユーザ名]:[パスワード]@tcp([ホスト名]:[ポート番号])/[データベース名]?charset=[文字コード]
dsn := fmt.Sprintf(`%s:%s@tcp(db:3306)/%s?charset=utf8mb4&parseTime=True`,
os.Getenv("MYSQL_USER"), os.Getenv("MYSQL_PASSWORD"), os.Getenv("MYSQL_DATABASE"))
// DBへの接続を行う
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
// エラーが発生した場合、エラー内容を表示
if err != nil {
log.Fatal(err)
}
// 接続に成功した場合、「db connected!!」と表示する
fmt.Println("db connected!!")
return db
}
func main() {
// DB起動
db := dbInit()
// Userテーブル作成
db.AutoMigrate(&User{})
}
os.Getenv(...)
は、後に記述するmysql/.envで記述する環境変数を使用しています。
dbInit()
関数でMySQLのDBに接続を行い、db.AutoMigrate(&User{})
でUserテーブルをMySQL上に作成します。
go.modとgo.sumの作成
cd golang/app
でappディレクトリに移動し、go mod init app
とgo mod tidy
コマンドを実行して2つのファイルを作成します。
MySQL側の設定
次に、MySQL側のディレクトリを作成し、Dockerfileと.envを記述します。
構成はこのようになります。
.
├── docker-compose.yml
├── golang
│ ├── Dockerfile
│ └── app
│ ├── go.mod
│ ├── go.sum
│ └── main.go
└── mysql
├── Dockerfile
└── .env
mysql/Dockerfile
FROM mysql:8.0
ENV LANG ja_JP.UTF-8
mysql/.env
MYSQL_DATABASE=test_database
MYSQL_USER=test_user
MYSQL_PASSWORD=password
MYSQL_ROOT_PASSWORD=root_password
Docker Composeで接続確認
docker compose up
コマンドを実行し、「db connected!!」の記述があるか確認します。
go-practice-go-1 | go: downloading github.com/jinzhu/now v1.1.5
go-practice-go-1 | go: downloading github.com/jinzhu/inflection v1.0.0
go-practice-go-1 | db connected!!
※network golang_test_network declared as external, but could not be found
と出た場合は、docker network create golang_test_network
を実行してネットワークの生成を行います。
実際にテーブルが作成されているか確認
次に、新しいターミナルを起動し、docker compose exec db bash
を実行してdbコンテナ内に入ります。
bash-〇.〇#
と出てくれば成功です。
次に、mysql -u root -p
を実行します。
Enter password:
と出てくるので、mysql/.envに記述したMYSQL_ROOT_PASSWORD
を打ってEnterを押します。
※今回のものをそのまま使用する場合は、root_password
でOKです。
以下のように出ればMySQLに接続できます。
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 9
Server version: 8.0.35 MySQL Community Server - GPL
Copyright (c) 2000, 2023, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
ここで、use test_database;
を実行し使用するデータベースを決めます。
最後に、show tables;
を実行してusersテーブルが作成されているか確認します。
mysql> show tables;
+-------------------------+
| Tables_in_test_database |
+-------------------------+
| users |
+-------------------------+
1 row in set (0.06 sec)
ありました( ´∀` )
これでGoとMySQLの接続を行い、Goからテーブルを作成することができました。
さいごに
ここまで読んでくださり、ありがとうございます。
次回は、Go(Echo)でAPIサーバを構築し、確認する所まで行いたいと思います。
次回:Go(Echo)+MySQLでCRUDを行えるAPIサーバをDocker上で構築する(2)APIサーバを構築する