はじめに
手元の開発環境でプログラムを開発するときに、MySQL に接続したくなる時が有ります。クラウド上でのマネージドサービスを使ってもよいのですが、費用など掛かるためローカルで MySQL を動かしたくなります。そこで、Docker を使って MySQL を動作させる方法がかなりお手軽だと思います。
この記事では、ローカルで MySQL を動かしたうえで、Go言語から接続する手順を残しておきます。
Docker で MySQL を動かす
ECR Public で公開されている Docker Image を使って、ローカル上で MySQL を動かします。Docker Hub でもよいのですが、スロットリングの上限が自分の場合は 6時間につき 100 が上限となっているため、ECR Public を使っていきます。
docker run のコマンド一発でローカル環境で MySQL が動作できます。コンテナサイコー。
- MySQL 8.0 を利用
- MySQL のパスワードなどを指定
docker run \
--name mydb \
-itd \
--hostname my-mysql \
-e MYSQL_ROOT_PASSWORD=mypassword \
-e BIND-ADDRESS=0.0.0.0 \
-p 3306:3306 \
public.ecr.aws/docker/library/mysql:8.0
なお、ここで動作した MySQL コンテナを削除する場合は次のコマンドで削除可能です。
docker kill mydb
docker rm mydb
MySQL が正常に稼働しているか、接続テストを行います。
mysql -u root -h 127.0.0.1 --port=3306 -pmypassword
実行例です。問題なく接続できました。
> mysql -u root -h 127.0.0.1 --port=3306 -pmypassword
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.28 MySQL Community Server - GPL
Copyright (c) 2000, 2021, 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>
SHOW DATABASES
でデータベース一覧も確認してみましょう。正常に見えていますね。
mysql> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.01 sec)
mysql>
テスト用のデータを格納
テスト用のデータ格納します。
CREATE DATABASE sugi01;
USE sugi01;
CREATE TABLE sample(
id INT(11) NOT NULL AUTO_INCREMENT,
name VARCHAR(10) NOT NULL,
PRIMARY KEY (id)
);
INSERT INTO sample(name) VALUES ("MySQLのデータ");
確認
SELECT * FROM sugi01.sample;
実行例
mysql> SELECT * FROM sugi01.sample;
+----+-------------------+
| id | name |
+----+-------------------+
| 1 | MySQLのデータ |
+----+-------------------+
1 row in set (0.00 sec)
mysql>
環境変数の設定
Go言語をつかって動作確認をしていくのですが、接続先の情報は環境変数として渡したいと思います。環境変数化しておくと、なにかと便利です。
Bash
Bash の場合の設定例
export MYSQL_HOSTNAME=localhost
export MYSQL_PORT=3306
export MYSQL_USERNAME=root
export MYSQL_PASSWORD=mypassword
Fish
Fish の場合の設定例
set -x MYSQL_HOSTNAME localhost
set -x MYSQL_PORT 3306
set -x MYSQL_USERNAME root
set -x MYSQL_PASSWORD mypassword
Go から接続
Go 言語用プロジェクト用のディレクトリを作成します。
mkdir ~/godir/app-runner-testapp
cd ~/godir/app-runner-testapp
MySQL 接続用のライブラリを取得します。
go get -u github.com/go-sql-driver/mysql
Goの動作確認用プログラム。このコードは、エラーのハンドリングはまったくしていないので、本番環境での利用はだめです。
- MySQL の接続先に環境変数を利用
- 1行分のみのデータを取得して、標準出力にプリント
package main
import (
"database/sql"
"os"
"time"
_ "github.com/go-sql-driver/mysql"
)
func main() {
mysql_hostname := os.Getenv("MYSQL_HOSTNAME")
mysql_port := os.Getenv("MYSQL_PORT")
mysql_username := os.Getenv("MYSQL_USERNAME")
mysql_password := os.Getenv("MYSQL_PASSWORD")
db, err := sql.Open("mysql", mysql_username+":"+mysql_password+"@tcp("+mysql_hostname+":"+mysql_port+")/sugi01")
if err != nil {
println("MySQL のコネクション接続に失敗")
panic(err)
}
defer db.Close()
// See "Important settings" section.
db.SetConnMaxLifetime(time.Minute * 3)
db.SetMaxOpenConns(10)
db.SetMaxIdleConns(10)
row := db.QueryRow(`select * from sample`)
var id, name string
row.Scan(&id, &name)
println(name)
}
Go の依存関係を管理するための go.mod
を生成
go mod init github.com/Sugi275/app-runner-testapp
動作確認
それでは動作確認をしてみましょう。「MySQLのデータ」と表示されており、正常に表示されることがわかります。
> go run app.go
MySQLのデータ