背景
環境
- macOS Monterey 12.3.1
- Docker for Mac 4.7
以下のようなdocker-compose.ymlでdocker-compose up
したい
version: '3.8'
services:
app:
build:
context: .
dockerfile: ./docker/php-apache/Dockerfile
ports:
- '30080:80'
depends_on:
- db
volumes:
- ./src:/var/www/html
networks:
- docker_network
db:
image: 'mysql/mysql-server:8.0.28'
ports:
- '33306:3306'
environment:
MYSQL_ROOT_HOST: '%'
MYSQL_ROOT_PASSWORD: 'password'
volumes:
- ./docker/mysql/data:/var/lib/mysql:delegated
networks:
- docker_network
networks:
docker_network:
phpのDockerfileやその他設定ファイルは今回は関係なさそうなので省略します。
内容
dbコンテナが立ち上がらない。コンテナのログをみると・・・
[System] [MY-013602] [Server] Channel mysql_main configured to support TLS. Encrypted connections are now supported for this channel.
[ERROR] [MY-010270] [Server] Can't start server : Bind on unix socket: Operation not permitted
[ERROR] [MY-010258] [Server] Do you already have another mysqld server running on socket: /var/lib/mysql/mysql.sock ?
[ERROR] [MY-010119] [Server] Aborting
[System] [MY-010910] [Server] /usr/sbin/mysqld: Shutdown complete (mysqld 8.0.28) MySQL Community Server - GPL.
上記のエラーで落ちる。
マウントしているホスト側ディレクトリ(./docker/mysql/data)の削除、ディレクトリの権限変更、Dockerの再起動、Macの再起動など試しても効果なし。
原因
今回使っているmysql-serverイメージの説明にこんなことが
Warning
The MySQL Docker images maintained by the MySQL team are built specifically for Linux platforms. Other platforms are not supported, and users using these MySQL Docker images on them are doing so at their own risk. See the discussion here for some known limitations for running these containers on non-Linux operating systems.
LinxuOS以外はサポートされていない
さらに、
If you are bind-mounting on the container's MySQL data directory (see Persisting Data and Configuration Changes for details), you have to set the location of the server socket file with the --socket option to somewhere outside of the MySQL data directory; otherwise, the server fails to start. This is because the way Docker for Windows handles file mounting does not allow a host file from being bind-mounted on the socket file.
コンテナのMySQLデータディレクトリにバインドマウントする場合、--socketオプションでサーバのソケットファイルの場所をMySQLデータディレクトリ以外の場所に設定する必要があり、さもなければサーバの起動に失敗します。これは、Docker for Windowsのファイルマウント処理では、ホストファイルをソケットファイルにバインドマウントすることができないためです。
とのこと。
今回、自分はmacOSで、
~~~
volumes:
- ./docker/mysql/data:/var/lib/mysql:delegated
~~~
ここでホスト側のディレクトリを、コンテナのmysqlディレクトリにバインドマウントしているので、ソケットファイルを別の場所に指定しないといけないっぽいです。
(実際、このエラーはLinux OSでは起こらないそうです)
対応策
- --socketオプションでsockの場所を変える
指示通り--socketで指定してあげます。
~~~
db:
image: 'mysql/mysql-server:8.0.28'
ports:
- '33306:3306'
environment:
MYSQL_ROOT_HOST: '%'
MYSQL_ROOT_PASSWORD: 'password'
volumes:
- ./docker/mysql/data:/var/lib/mysql:delegated
command:
["mysqld", "--socket=/tmp/mysql.sock"]
networks:
- docker_network
2.バインドマウントをやめて名前付きボリュームにする
バインドマウントしたらこの問題が発生するようなので、名前付きボリュームに変えてみると動きました。
~~~
db:
image: 'mysql/mysql-server:8.0.28'
ports:
- '33306:3306'
environment:
MYSQL_ROOT_HOST: '%'
MYSQL_ROOT_PASSWORD: 'password'
volumes:
- db-data:/var/lib/mysql:delegated
networks:
- docker_network
~~~
volumes:
db-data:
3.mysqlイメージにする
MySQLのdockerイメージには、Docker公式のmysqlと、Oracleが出してるmysql/mysql-serverの2種類あります。
後者のイメージでこの問題が起きるようです。mysqlイメージの方では問題なく起動することができました。
根本的な解決ではないですが、特にイメージを選ぶ理由がなければ一案としてあるかなと思います。
~~~
db:
image: 'mysql:8.0.28'
ports:
- '33306:3306'
environment:
MYSQL_ROOT_HOST: '%'
MYSQL_ROOT_PASSWORD: 'password'
volumes:
- ./docker/mysql/data:/var/lib/mysql:delegated
networks:
- docker_network