1. ホーム
  2. ドッカー

docker-composeはmysqlをボリュームでデプロイする際のパーミッション拒否の問題を解決します。

2022-03-03 04:39:48
<パス

質問

全体的な状況としては、mysqlのコンテナとしてdockerを使い、docker-composeで他のサービスと一緒に組み合わせて起動し、テーブルの構築やユーザー権限の設定を一度に行うために、mysql setup.sh, schema.sql, privileges.sql これらのカスタムスクリプトもDockerfile構築でラップし、今のところうまく動いている状態です。

しかし、コンテナがダウンするたびにmysqlのデータが失われ、永続化できないため、docker-compose.ymlでvolumeパラメータを設定すると、デバッグ時も含めて以下のエラーが発生します。

まずは、これに関連するエラー報告として考えられるものをいくつか挙げてみましょう。

問題1:mysqld: ファイル '/var/lib/mysql/is_writable' への作成/書き込みができない (Errcode: 13 - Permission denied)。

問題2:Dockerの「su」コマンドは「ターミナルから実行する必要があります」と返される

問題3./usr/bin/mysqld_safe: 637: /usr/bin/mysqld_safe: cannot create /var/lib/mysql/c0ce8fdc06d0.err: パーミッションが拒否されました。

上記の問題は、すべてデバッグ中に報告されたエラーで、以下の方法で解決しました。

1. docker-compos.yml に追加する。

user:"1000:50"

2. ボリューム構成が /var/lib/mysql/data よりも深い /var/lib/mysql ディレクトリに対応することを確認します。

3. Dockerfileにchmodのようなパーミッションのコマンドを追加して、ファイルのパーミッションを変更します。

上記の方法はどれもうまくいかないので、本当の解決策を挙げる前に、私の重要な設定ファイルをいくつかリストアップしておきます。

  • docker-compose.yml
plate-nginx:
build: . /nginx
container_name: plate-nginx
links:
- plate-client:plate-client
- plate-server:plate-server
ports:
- "80:80"
- "443:443"
- "7000:7000"
plate-client:
build: . /client
container_name: plate-client
volumes:
- "/home/picture:/app/client/app/upload"
ports:
- "3000:3000"
- "3001:3001"
plate-server:
build: . /server
container_name: plate-server
ports:
- "7001:7001"
plate-mysql:
build: . /mysql
container_name: plate-mysql
volumes:
- "/home/data:/var/lib/mysql"
ports:
- "3306:3306"
environment:
MYSQL_USER: root
MYSQL_ROOT_PASSWORD: 123456
phpmyadmin:
image: phpmyadmin/phpmyadmin
container_name: phpmyadmin
links:
- plate-mysql:plate-mysql
ports:
- "8888:80"
environment:
MYSQL_USER: root
MYSQL_ROOT_PASSWORD: 123456
PMA_HOST: plate-mysql
PMA_PORT: 3306


  • mysqlの下のDockerfile
FROM mysql:5.6

# Set password-free login
ENV MYSQL_ALLOW_EMPTY_PASSWORD yes

#Put the required files into the container
COPY setup.sh /mysql/setup.sh
COPY schema.sql /mysql/schema.sql
COPY privileges.sql /mysql/privileges.sql

# Set the command to execute when the container starts
CMD ["sh", "/mysql/setup.sh"]


  • setup.sh
#! /bin/bash
set -e

# Check the status of the mysql service for easy debugging, this statement can be removed
echo `service mysql status`

echo '1. Starting mysql ....'
# Start mysql
service mysql start
sleep 3
echo `service mysql status`

echo '2. Start importing data from ....'
#import data
mysql < /mysql/schema.sql
echo '3. Importing data is complete ....'

sleep 3
echo `service mysql status`

#reset mysql password
echo '4. Started changing password ....'
mysql < /mysql/privileges.sql
echo '5. Finished changing password ....'

#sleep 3
echo `service mysql status`
echo `mysql container started, and data imported successfully`

tail -f /dev/null

解決方法

本当の問題は、サーバー上のボリューム・ディレクトリ /home/data とコンテナ・ディレクトリ /var/lib/mysql の所有者が同じでないことなので、所有者を確認するために、以下のディレクティブを使用する必要があります。

  • コンテナ内の /var/lib/mysql の所有者を確認する場合
docker run -ti --rm --entrypoint="/bin/bash" plate_plate-mysql -c "ls -la /var/lib/mysql"

<イグ 画像から、このディレクトリのオーナーはmysqlのユーザーグループであることがわかります。

  • サーバー上の/home/dataの所有者を表示します。
ls -la /home/data

<イグ

systemd-bus-proxyでこの場所は、もともとルートだった、私はそのように変更されたため、ここでは、パーミッションの問題によって引き起こされる別の所有者の2つのディレクトリは、今彼らのIDは、コンテナ内のmysqlユーザーグループIDを見つける必要がある前に統一され、統一することができますし、ユーザーグループIDの下にサーバーの/home/データを変更することができます

  • コンテナ内のmysqlユーザーグループIDを確認する
docker run -ti --rm --entrypoint="/bin/bash" plate_plate-mysql -c "cat /etc/group"

<イグ

mysql のユーザーグループ ID が 999 であることがわかります。

  • サーバーファイルのユーザーグループIDを変更する
chown -R 999 /home/data

<イグ

999は、許可ID内のドッカーコンテナではなく、サーバーなので、サーバーは自然を認識していない、その後再起動すると、実装は、上記と同じように見に行った後、パーミッションは、それがmysqlにならなかった理由として、systemd-バス-プロキシとなった。

docker-compose build && docker-compose up -d

エラーレポートが表示されなくなります