docker-composeによる、mysqlのセットアップ例

docker-composeによる、mysqlのセットアップ例

はじめに

※ この記事の内容は、Ghost CMSとは直接関係なので、mysqlだけが欲しい人でも使えると思う。
※ そのCMSを建てるためにmysqlを建てたという経緯があるので、ところどころにCMSがどうとかって書いてるけど、mysqlだけが欲しい人はスルーして読むといいと思う。

MySqlはいいからGhost CMSの記事を読ませろって人は、以下の記事をどうぞ。
docker-composeによる、Ghost CMSのセットアップ例

docker-composeによる、Ghost CMSのセットアップ例
技術メモなんかをつけるためにCMSを探してたら、いい感じなものがあったので、Ghost CMSというものをdocker-composeで組み立ててみた。 そのCMSの前提にMySQLを求められたので、けど、公式のdocker-composeのように、本体とDBをひとくくりにしたくなかったので、Ghostを単体で建てるおはなし。

技術メモなんかをつけるためにCMSを探してたら、いい感じなものがあったので、Ghost CMSというものをdocker-composeで組み立ててみた。
そして、組み立てたもののテストを兼ねて、この記事を書いてる。
ghostというCMSを使おうと思ったんだけど、前提条件としてmysqlが必要だったので、まずはそちらを準備する。

書いてる人は、フロントエンドの人間なので、ツメが甘いところがあるかもしれないけれど、そのあたりはご容赦を。

概要

能書き

とりあえず、CMSの本体はさておき、mysqlを組み立てる。

ghost公式の情報によると、mysqlとghost本体を同じcomposeに入れてしまってるんだけど、複数のトピックを別のシステムとして管理したい、または、他のシステムでmysqlを利用しているという事情の場合、これらを分離した方が効率がいいこともあるので、分離した例。

構成図

mysql/
    .env
    docker-compose.yml
    start.sh
    volume/
        _init/
            0_init.sh
            0_init.sql
        conf/
            custom.cnf
        log/
            (error.log)
            (slow.log)
        mysql/

下準備

docker-compose.yml

特段変わったことはしてない。強いて言えば、networksnameを指定することで、ネットワーク名を固定し、他のコンテナからのアクセスを容易にしてる。

また、MYSQL_ROOT_PASSWORDをべた書きするのは憚られたので、.envで管理してる。

services:
  mysql:
    container_name: example.mysql
    image: mysql:latest
    ports:
      - "3306:3306"
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} # <- .envから読み出し
      MYSQL_DATABASE: 'init'
    restart: always
    networks:
      - mysql-network
    volumes:
      - ./volume/log:/var/log
      - ./volume/mysql:/var/lib/mysql
      - ./volume/conf:/etc/mysql/conf.d
      - ./volume/_init:/docker-entrypoint-initdb.d
networks:
  mysql-network:
    name: service.mysql # <- ネットワーク名を固定
    driver: bridge

.env

mysqlのルートユーザのパスワードを生成して書いておく。

MYSQL_ROOT_PASSWORD=<password>

自分で書かなくても、こんな感じのコマンドで自動生成してもいいかもしれない。

$ echo "MYSQL_ROOT_PASSWORD=$(tr -dc A-Za-z0-9 </dev/urandom | head -c 13)" >> .env

start.sh

起動前にログ関係を退避させておきたかったので、起動スクリプトに追加してる。
docker-entrypoint-initdb.dで動かしてもいいけど(後述)、新しいコンテナでの情報が過去ログに入ることがあるため、動作前に退避させてる。

#! /bin/bash

## mv log files
time=$(date +%Y%m%d%H%M%S)
if [ -f ./volume/log/slow.log ]; then
  mv ./volume/log/slow.log ./volume/log/slow_"${time}".log
fi
if [ -f ./volume/log/error.log ]; then
  mv ./volume/log/error.log ./volume/log/error_"${time}".log
fi

## up
docker compose up -d

volume/_init/0_init.sh

mysql立ち上がり後、volume/_init/に入ってるものが、名前順に実行される。
先ほどのstart.shのログ移動なんかはこちらに書いても、機能的には問題ない。

#! /bin/bash

# 初期化するときに何かしたいならここに書く。

volume/_init/0_init.sql

docker-compose.ymlMYSQL_DATABASEで指定したスキーマを破棄してきれいな状態にしてる。

初期化を各サービスごとに行うという方針なので、一旦まっさらな状態にしているが、必要なければ行う必要はないし、mysql側ですべてのサービスの初期化を一括管理してもよいかもしれない。

DROP SCHEMA IF EXISTS init;

起動

エラーを吐かないことを祈りながら、スタートしましょ。

mysqlのスタート

start.shも権限をつけとかないと怒られることがあるので一応つけとく。

$ cd mysql/
$ chmod u+x start.sh
$ ./start.sh

もし、ログファイルがどうとか、permissionがどうとかって怒られたら以下でもいいのかもしれない。

$ sudo sh start.sh

これで、mysqlが起動したはず。