Dockerでmysqlがrestartingの状態になり立ち上がらない
表題通りですが、Dockerを利用してMySQLサービスを立ち上げようとして、restartingの状態のループになってしまって立ち上がらなかったので、その解決方法を調べました。
環境
マシン
macOS Big Sur
プロセッサ Intel
ディレクトリ
.
├── docker
│ ├── db
│ │ ├── init
│ │ │ └── init.sql
│ │ └── mydata
│ ├── web
│ │ ├── conf
│ │ │ └── my.cnf
│ │ ├── log
│ │ ├── Dockerfile
│ │ └── php.ini
│ ├── .env
│ └── docker-compose.yml
└── www
└── myroot
my.cnf
[mysqld]
character_set_server = utf8mb4
collation_server = utf8mb4_general_ci
[mysql]
default-character-set = utf8mb4
[client]
default-character-set = utf8mb4
Dockerfile
FROM php:apache
COPY ./php.ini /usr/local/etc/php/php.ini
RUN apt-get update \
&& apt-get install -y libonig-dev libzip-dev unzip locales\
# コンテナ内で日本語が打てるようにlocalを変更
&& sed -i -E 's/# (ja_JP.UTF-8)/\1/' /etc/locale.gen \
&& locale-gen \
&& update-locale LANG=ja_JP.UTF-8 \
# 不要ファイルを削除
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* \
# phpのモジュールとxdebug
&& docker-php-ext-install pdo_mysql mbstring zip bcmath\
&& pecl install xdebug\
&& docker-php-ext-enable xdebug
ENV LC_ALL ja_JP.UTF-8
## ドキュメントルートを変更する
RUN sed -ri -e 's!/var/www/html!${DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf
RUN echo 'ServerName localhost' | tee /etc/apache2/conf-available/fqdn.conf
RUN a2enconf fqdn
.env
WEB_PORT=81
DOCUMENT_ROOT_DIR=myroot
DB_DATABASE=mydatabase
DB_ROOT_HOST=%
DB_ROOT_USER=root
DB_ROOT_PASSWORD=myroot
DB_HOST=mydb
DB_PORT=3307
TZ=Asia/Tokyo
PHPMYADMIN_PORT=8081
docker-compose.yml
version: "3.0"
services:
web:
container_name: web
image: php
build:
context: ./web
dockerfile: Dockerfile
ports:
- "${WEB_PORT}:80"
environment:
DOCUMENT_ROOT: "/var/www/html/${DOCUMENT_ROOT_DIR}/"
volumes:
- ../www:/var/www/html/
- ./web/log:/var/log
depends_on:
- db
networks:
- mynetwork
db:
container_name: db
image: mysql:8.0
command: --default-authentication-plugin=mysql_native_password
restart: always
ports:
- "${DB_PORT}:3306"
environment:
MYSQL_DATABASE: "${DB_DATABASE}"
MYSQL_ROOT_HOST: "${DB_ROOT_HOST}"
MYSQL_ROOT_USER: "${DB_ROOT_USER}"
MYSQL_ROOT_PASSWORD: "${DB_ROOT_PASSWORD}"
MYSQL_HOST: "${DB_HOST}"
TZ: "${TZ}"
volumes:
# データ永続化
- ./db/mydata:/var/lib/mysql
# 初期化
- ./db/init:/docker-entrypoint-initdb.d
# 設定
- ./web/conf/my.cnf:/etc/my.cnf
networks:
- mynetwork
phpmyadmin:
container_name: phpmyadmin
image: phpmyadmin/phpmyadmin
ports:
- "${PHPMYADMIN_PORT}:80"
environment:
PMA_HOST: db
depends_on:
- db
links:
- db
networks:
- mynetwork
networks:
mynetwork:
driver: bridge
エラーログのメッセージ
Failed to find valid data directory.
Data Dictionary initialization failed.
Aborting.
行ったこと
- コンテナのストップ&削除
docker-compose down
- 使用していないイメージとボリュームを削除
docker system prune --all
※コマンドライン上で警告が出ますが、他の停止中のコンテナなども削除されるので注意してください。
- mydataディレクトリを削除
cd /path_to_this_root_dir/docker/db
rm -rf mydata
- 起動
docker-compose up -d
不明点...
mysqlのイメージの説明には以下とあります。
注意事項
データの保存場所
重要な注意事項: Docker コンテナーで実行されるアプリケーションで使用されるデータを保存するには、いくつかの方法があります。画像のユーザーは、mysql次のような利用可能なオプションに慣れることをお勧めします。独自の内部ボリューム管理を使用してホスト システム上のディスクにデータベース ファイルを書き込むことにより、 Docker がデータベース データのストレージを管理できるようにします。これはデフォルトで、簡単で、ユーザーにとってかなり透過的です。欠点は、ホスト システム上で直接実行されるツールやアプリケーション、つまりコンテナの外部で実行されるツールやアプリケーションの場合、ファイルを見つけるのが難しい場合があることです。
ホスト システム (コンテナーの外部) にデータ ディレクトリを作成し、これをコンテナー内から見えるディレクトリにマウントします。これにより、データベース ファイルがホスト システム上の既知の場所に配置され、ホスト システム上のツールやアプリケーションがファイルに簡単にアクセスできるようになります。欠点は、ユーザーがディレクトリが存在することを確認する必要があること、およびホスト システム上のディレクトリのアクセス許可やその他のセキュリティ メカニズムが正しく設定されていることなどです。Docker のドキュメントは、さまざまなストレージ オプションとバリエーションを理解するための出発点として最適です。また、この分野について議論し、アドバイスを提供するブログやフォーラムへの投稿が複数あります。ここでは、上記の後者のオプションの基本的な手順を簡単に示します。
ホスト システムの適切なボリュームにデータ ディレクトリを作成します/my/own/datadir。
次のようにコンテナを起動しますmysql。
$ docker run --name some-mysql -v /my/own/datadir:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
-v /my/own/datadir:/var/lib/mysqlコマンドの一部は、基礎となるホスト システムからディレクトリをコンテナ内としてマウントします。/my/own/datadirデフォルト/var/lib/mysqlでは、MySQL がそのデータ ファイルを書き込みます。
データを保存しておくために /my/own/datadir ディレクトリを作成し、コンテナの /var/lib/mysql ディレクトリに紐づけていると思うのですが、僕の場合は上記手順の3を行わないと起動できなかったです。
なんでなんだろう...解決できておりません。
参考
Discussion