それが僕には楽しかったんです。

僕と MySQL と時々 MariaDB

MySQL を使った最高に頭の悪いポートフォリオを作った話

はじめに

JVM オプションをいい感じに比較してくれるサービスを作ったが、サブドメインに割り当ててしまったので大元の lrf141.dev に何もないという状況はあれだなと思い半年ぐらい前に作った頭の悪いポートフォリオサイトを作ったのでまとめる。

技術スタック

  • Go 1.14
  • React 16.13.1
  • MySQL 8.0.21
  • Redis 6.0.5
  • Docker

作ったもの

https://lrf141.dev/

f:id:RabbitFoot141:20210226000601p:plain

f:id:RabbitFoot141:20210226002414p:plain

f:id:RabbitFoot141:20210226002437p:plain

画面はこんな感じ。どこかでみたことのある画面ですね?

portfolio データベースが存在し、そこにあるテーブルをいい感じに select * from で呼び出すとテーブルのフォーマットのまま表示してくれる。
ポイントはテーブルのフォーマットのまま表示してくれるというところ。

仕組み

Go + Gin で Web バックエンドを作り、フロントエンドは React で作っている。
ここで何が起こっているかというと、SQL をターミナルに入力するとそれを API に飛ばし、APIMySQL の docker コンテナに対して mysql コマンドを実行し
標準出力をアタッチしてそれをレスポンスとして返却している。そのためテーブルのフォーマットで表示されるようになる。

自分は web デザインが苦手なので、この形式であれば css とか描かなくても秩序のあるスタイルで表示してくれるので楽だった。

この時点で非常に頭が悪い。

もっと頭の悪いことは、なんでこんな形にしたかというとポートフォリオサイトをまともに更新したためしがなかったのでマイグレーションを走らせればいい感じにサイトを更新してくれる上に楽という発想。

絶望的に頭が悪い。

技術的な話

docker コンテナに対して何かを実行させる

API がコールされた段階で docker コンテナに対してコマンドを投げるがここは Go で作ったので moby を使っている。
結構便利でコマンドも投げられるし、コンテナ内の標準出力をアタッチする API も用意されていてこれだけでどうにかなった。
Docker Engine API を呼び出しているらしく、この辺りを使えばもっと面白いこともできる。

Redis を使ったキャッシュ

テーブルが3,4つしかないので毎度コンテナに叩きにいかないで同じクエリであれば redis にキャッシュされてるデータを引っ張るようになっている。Redis は最高。

MySQL User の権限を絞る

クエリが投げつけられてなんでも実行されると平気な顔をして破綻するからユーザの権限を絞っている。

CREATE DATABASE IF NOT EXISTS `portfolio`;
GRANT SELECT ON `portfolio`.* TO 'portfolio'@'%';
FLUSH PRIVILEGES;

こんな感じの設定をいくつか追加している。

デプロイ時の色々

Dockerfile で COPY /var/run/docker.sock を突っ込もうと思ったが Dockerfile では Dockerfile のあるディレクトリ以下のディレクトリしか参照できない。これはハマった。
また Dockerfile で CMD をやってしまって /var/run/docker.sock を docker-compose でボリュームマウントしたが認識されなかった。そのため、docker-compose で commands を使って上書きした。面倒だったので。

おわりに

何かまずいところあったら教えてくださいな。