ubuntu-20.04 dockerで複数バージョンのmysqlを共存させる

docker

案件によってmysqlのバージョンが5.6だったり、5.7だったり、8.xだったりして切り替えが面倒なので、dockerで複数バージョンのmysqlを立ててポートで切り分けするお話。案件ごとにまるっとLEMPとかLAMPとかの環境を作る場合もあるが、そうしたくない場合もあるので、今回はmysqlだけを切り離す。データ移行のちょっとした検証などに便利。ここではmysql-5.7とmysql-8をそれぞれdockerで起動する。

docker rootlessモードの環境設定については以下を参照。

ubuntu 20.04でdocker rootlessモードを起動する

トラブルシューティング

まず、dockerのrootlessモードで起動する場合、AppArmorの制限に引っかかってmysqlが起動できない。dockerを立ち上げてみた時のエラー内容は以下。

2021-03-17 09:08:58+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.33-1debian10 started.
2021-03-17 09:08:58+00:00 [ERROR] [Entrypoint]: mysqld failed while attempting to check config
        command was: mysqld --verbose --help --log-bin-index=/tmp/tmp.yx08ov34Wl
        mysqld: Can't read dir of '/etc/mysql/conf.d/' (Errcode: 13 - Permission denied)
mysqld: [ERROR] Fatal error in defaults handling. Program aborted!

AppArmorの設定を変更する。今回は検証用なので、まるっとmysqlの設定を除外しているが、細かく設定する場合は、今回作成するmysqlコンテナのパスを記載してあげる必要がある。

$ sudo ln -s /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/
$ sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.mysqld

事前準備

VPSやレンタルサーバなど、グローバルな場所で試す場合、外部からの特定ポートの接続を拒否しておくのがセキュリティ的によいと思う。でないと荒らされるかも・・ubuntuであればufwで設定するが、ここでは省略。

docker-compose.ymlでuidとgidが必要になるので、事前に調べておく

$ id -u
1000
$ id -g
1000

ディレクトリ構成は以下。場所はどこでもよいが、誤って削除しない場所がオススメ。

/data/db
├── mysql-5.7
│   ├── data
│   ├── docker-compose.yml
│   ├── my.cnf
│   └── sql
└── mysql-8
    ├── data
    ├── docker-compose.yml
    ├── my.cnf
    └── sql

dataディレクトリに書き込み権限がないとmysqlが起動しないので、権限を変えておく。

$ chmod 777 /data/db/mysql-5.7/data
$ chmod 777 /data/db/mysql-8/data

mysql-5.7のインストール

まず、mysql-5.7のdocker-compose.ymlを作成する。

$ cd /data/db/mysql-5.7
$ vi docker-compose.yml
version: '3'

services:
  # MySQL
  db:
    # mysql 5.7 のイメージを使用
    image: mysql:5.7
    # uid:gid を指定
    user: "1000:1000"
    # コンテナ名は名前が分かれば何でもよい
    container_name: mysql-57
    environment:
      # rootのパスワード
      MYSQL_ROOT_PASSWORD: root_password
      # その他ユーザが必要な場合はここに記述
      MYSQL_DATABASE: mysql
      MYSQL_USER: mysql
      MYSQL_PASSWORD: password
      # タイムゾーンを設定
      TZ: 'Asia/Tokyo'
    # 起動時のコマンドオプション
    command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
    # データ、設定ファイルの保存先ディレクトリ
    volumes:
    - ./data:/var/lib/mysql
    - ./my.cnf:/etc/mysql/conf.d/my.cnf
    - ./sql:/docker-entrypoint-initdb.d
    # 外部待ち受けポート:コンテナ内待ち受けポート
    ports:
    - 3316:3306

次にmy.cnfを作成する。内容はかなりシンプルなので、必要であれば設定を追記する。

$ cd /data/db/mysql-5.7
$ vi my.cnf
[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci

[client]
default-character-set=utf8mb4

dockerを起動してみる。

$ cd /data/db/mysql-5.7
$ docker-compose up -d

コンテナが立ち上がっているか確認する。

$ docker ps
CONTAINER ID   IMAGE       COMMAND                  CREATED         STATUS         PORTS                               NAMES
15c44a137d11   mysql:5.7   "docker-entrypoint.s…"   3 minutes ago   Up 3 seconds   33060/tcp, 0.0.0.0:3316->3306/tcp   mysql-57

mysqlへ接続できればOK。ポートの部分はdocker-compose.ymlで設定した外部ポートを指定する。

$ mysql -u root -h 127.0.0.1 -P3316 -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.33 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> 

mysql-8のインストール

まず、mysql-8のdocker-compose.ymlを作成する。5.7と異なるのはイメージ、コンテナ名、外部待ち受けポート。データの保存先(volume)も相対パスで記載しているので同様に見えるが、実際の保存先は5.7とは異なる場所なので注意。

$ cd /data/db/mysql-8
$ vi docker-compose.yml
version: '3'

services:
  # MySQL
  db:
    # mysql 8 のイメージを使用
    image: mysql:8
    # uid:gid を指定
    user: "1000:1000"
    # コンテナ名は名前が分かれば何でもよい
    container_name: mysql-8
    environment:
      # rootのパスワード
      MYSQL_ROOT_PASSWORD: root_password
      # その他ユーザが必要な場合はここに記述
      MYSQL_DATABASE: mysql
      MYSQL_USER: mysql
      MYSQL_PASSWORD: password
      # タイムゾーンを設定
      TZ: 'Asia/Tokyo'
    # 起動時のコマンドオプション
    command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
    # データ、設定ファイルの保存先ディレクトリ
    volumes:
    - ./data:/var/lib/mysql
    - ./my.cnf:/etc/mysql/conf.d/my.cnf
    - ./sql:/docker-entrypoint-initdb.d
    # 外部待ち受けポート:コンテナ内待ち受けポート
    ports:
    - 3326:3306

my.cnfを作成する。内容は5.7のものと同一。

$ cd /data/db/mysql-8
$ vi my.cnf
[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci

[client]
default-character-set=utf8mb4

dockerを起動してみる。

$ cd /data/db/mysql-8
$ docker-compose up -d

コンテナが起動しているか確認する。5.7のものも起動しているので2つ起動していればOK。

CONTAINER ID   IMAGE       COMMAND                  CREATED          STATUS          PORTS                               NAMES
0c894a237a4c   mysql:8     "docker-entrypoint.s…"   28 minutes ago   Up 28 minutes   33060/tcp, 0.0.0.0:3326->3306/tcp   mysql-8
15c44a137d11   mysql:5.7   "docker-entrypoint.s…"   35 minutes ago   Up 31 minutes   33060/tcp, 0.0.0.0:3316->3306/tcp   mysql-57

mysqlへ接続してみる。

$ mysql -u root -h 127.0.0.1 -P3326 -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.23 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> 

複数バージョンの環境はあると便利なのでオススメ。

コメント

タイトルとURLをコピーしました