Docker build時にmysqlで、permission deniedでエラーになる件

docker compose build --no-cacheを実施時のmysql起動時に、ホスト側(サーバー側)のUSERとDockerのコンテナ側のボリュームディレクトリのファイルの所有者、権限周りが異なりエラーになる件です。
エラーとなる流れを見ながら、解決方法について整理していきます。

failed to solve: error from sender: open /docker-mysql/db/data/#innodb_redo: permission denied

1.ボリュームディレクトリのおさらい

dockerを再起動すると、データなどを含むファイル群はリセットされてしまうので、永続化したい場合は、ボリュームディレクトリとして永続化設定をする必要がある。

docker-compose.yml

services:
  # MySQL
  db:
・・・(省略)
    volumes:
    - ./docker-mysql/db/data:/var/lib/mysql 
    - ./docker-mysql/db/my.cnf:/etc/mysql/conf.d/my.cnf 

上記のように設定した場合、dockerコンテナ側で保存されたデータが、サーバー側のとあるファイルに同期され、dockerが再起動されてもデータが永続化されるイメージ。
以下のようなイメージで同期される

[サーバー側] docker-mysql/db/data ->  [dockerコンテナ] /var/lib/mysql 
[サーバー側] docker-mysql/db/my.cnf -> [dockerコンテナ] /etc/mysql/conf.d/my.cnf 
上記「サーバー側」は、dockerFileがあるディレクトリ。

2.permission deniedエラーとなる流れ

2-1.dockerの初回起動時は正常終了する

初期状態は、ボリュームディレクトリがまだ存在していない状態なので、dockerの起動も正常終了しボリュームディレクトリも作成される

2-2.ボリュームディレクトリのファイル所有者は999で作成される

上記ボリュームディレクトリ作成時にファイル所有者がsystemd-timesync(999)で作成される

2-3.dockerを再起動すると所有者が異なりpermission deniedエラーとなる

dockerを停止し、dockerを再起動すると

docker compose build --no-cache
や
docker compose up -d
など

(ホスト側は、例としてuserが1000として稼働)、ホスト側のユーザーと、ボリュームディレクトリのファイル所有者が異なっているため、dockerビルドのmysql起動時にpermission deniedエラーとなってしまう。

3.permission deniedエラーの解決方法

3-1.docker-compose.ymlにてmysqlの起動userを指定する

docker-compose.ymlでuserを指定しないと、dockerのコンテナでmysqlを起動するuserが999になるので、docker-compose.yml側でuserを明示的に指定することで、dockerのmysqlが指定したユーザーで起動されるので、ボリュームファイルも指定したユーザーで作成してくれるということです。

services:
  # MySQL
  db:
・・・(省略)
    volumes:
    - ./docker-mysql/db/data:/var/lib/mysql # DB情報を永続化
    - ./docker-mysql/db/my.cnf:/etc/mysql/conf.d/my.cnf 
    user: 1000:1000 →ここを追加

簡単に解決する場合は、上記の通り、普段サーバーで使用するuserをベタ書きで対応していますが、ちゃんとやるのであれば、動的にuserを取得し、dockerに反映させる形が良いかと思います。

# ユーザーID、グループID、所属グループなどの詳細情報を表示するコマンド
id

UID 1000の補足

通常、UID 1000 はシステム上の最初の通常ユーザーに割り当てられることが多いです。システム管理者(root)の UID は通常 0 で、UID 1~999 はシステムユーザーやデーモン(バックグラウンドプロセス)に予約されることが一般的です。UID 1000 以降は通常の一般ユーザーに割り当てられるため、初めて作成された一般ユーザーがこの UID を持つことがよくあります。

3-2.すでにボリュームディレクトリが作成済みの場合は、所有者を変更する

すでに、ボリュームディレクトリの所有者が999となっている場合は、上記docker-compose.ymlで指定したuserに合わせる形で、ファイルの所有者を変更(chown)していく必要があります。まだボリュームディレクトリが作成されていない場合(まだdockerを1回も起動していない場合)は不要です。

# ホスト側のボリュームディレクトリのファイル所有者がsystemd-timesync(999)になっているので、
# サーバーのuserの所有者にディレクトリごと変更する
# user hogeは1000とした場合の例
sudo chown -R hoge:hoge /docker-mysql/db/data/

上記で解決するはずです!
(トライアンドエラーで色々いじっていたので、途中chmodとかもしたかも。)



いいなと思ったら応援しよう!