はじめに
一つ前の記事でDocker上でMySQLを使うことが出来なかったので、リベンジです。
mysqlの公式を参考にします
キーワード
MySQL, Docker, docker compose, docker network
目次
- コンテナのシェルから入る
- MySQL コマンド ライン クライアントから MySQL に接続する
- docker-compose経由でMySQLに接続する
- まとめ
- 参考
コンテナのシェルから入る
docker run
はイメージをcreate
とstart
を同時に行います。
$ docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:latest
引数は以下の通りです
- —name
- コンテナの名前を付ける
- -e
- 環境変数の定義
-
- d
- バックグラウンドで実行し、実行後も通常のターミナルとして使える
- detachとatachは対義語
- 中身を見たいときは
docker logs
- d
-dオプションについて
- https://qiita.com/Mi_tsu_ya/items/49a5e983f774f1e932e7
- https://qiita.com/R_R/items/40d256389b59b66eaf6b
- https://maku77.github.io/p/dmpsvz3/
先ほど動かしたdockerコンテナのシェルに入るためのコマンド
$ docker exec -it some-mysql bash
引数は以下の通りです
- exec
- 現在動いているコンテナに対して行うコマンドを渡すコマンド
- https://docs.docker.com/engine/reference/commandline/exec/
- -it
- 標準入出力をコンテナに結びつける(キー入力する場合)。が一番しっくり
- 色々調べた
- -iと-tの二つのコマンドを含む
- -i or -interactiveと -t or -tty
- ttyはUNIXのコマンドで、標準入出力先のデバイスの事をさすみたいです
- https://qiita.com/TaaaZyyy/items/4ecf21f23e6730faf696
- some-mysql
- さきほど作成したコンテナの名前です
- bash
- bashはLinuxの標準シェル
- なんのコマンドを実行してもいい
-
docker exec some-mysql ls
とか打つと、配下のディレクトリが見れる - https://www.memotansu.jp/docker/591/#toc4
-
シェルに入り、mysqlのCLIに入るコマンドを打ちました
bash-4.4# mysql -u root -pmy-secret-pw
成功しました
MySQL コマンド ライン クライアントから MySQL に接続する
$ docker run -it --network some-network --rm mysql mysql -hsome-mysql -uexample-user -p
引数は以下の通りです(前述のものは省略)
- —network
- ネットワークを指定する
- (という事はネットワークが作成されている必要がある)
dockerのnetworkについていろいろ調べた
-
https://qiita.com/TsutomuNakamura/items/ed046ee21caca4a2ffd9
-
-rm
- 終了時に中間コンテナを自動で削除する
-
-h or -hostname
- ホストとなるコンテナ名を指定する
-
-u or -user
- ユーザー名またはUID
-
-p
- パスワードの要求
some-networkという名前のネットワークを作ってみます
正直、bridge,host,noneの違いは説明できないですが、bridgeがdockerの特徴なのかなと思いました。
docker network create -d bridge some-network
docker network ls
を打つとsome-networkが表示されました。
- 参考
https://docs.docker.com/engine/reference/commandline/network/
では、もともとのコマンドを打ってみます
ERROR 2005 (HY000): Unknown MySQL server host 'some-mysql' (-2)
上記のようなエラーが出たのでググると、良さそうなissueが見つかりました
https://github.com/docker-library/mysql/issues/644#issuecomment-664107416
僕はまだネットワークとコンテナを関連付けられていないのかな、という事で下記のコマンドを打ってみました
$ docker network connect some-network some-mysql
docker network inspect some-network
コマンドを打ってみたら、コンテナが含まれています
さて、元のコマンドを再度打ってみます
ERROR 1045 (28000): Access denied for user 'example-user'@'192.168.48.3' (using password: YES)
PWを要求されたので、my-secret-pw
を打ってみたら見覚えのあるエラーが返ってきました!!
rootにすればいいのかな、と思い、-urootに変更して、PWを打ってみます
$ docker run -it --network some-network --rm mysql mysql -hsome-mysql -uroot -p
成功しました
docker-compose経由でMySQLに接続する
- mysql_docker_testフォルダを作成、配下にdocker-compose.ymlファイルを置く
内容は公式の通りにする
# Use root/example as user/password credentials
version: '3.1'
services:
db:
image: mysql
# NOTE: use of "mysql_native_password" is not recommended: https://dev.mysql.com/doc/refman/8.0/en/upgrading-from-previous-series.html#upgrade-caching-sha2-password
# (this is just an example, not intended to be a production configuration)
command: --default-authentication-plugin=mysql_native_password
restart: always
environment:
MYSQL_ROOT_PASSWORD: example
adminer:
image: adminer
restart: always
ports:
- 8080:8080
adminerとは
phpで単一ファイルに書かれたデータベース管理ツールのことらしいです
Adminer (formerly phpMinAdmin) is a full-featured database management tool written in PHP. Conversely to phpMyAdmin, it consist of a single file ready to deploy to the target server. Adminer is available for MySQL, PostgreSQL, SQLite, MS SQL, Oracle, Firebird, SimpleDB, Elasticsearch and MongoDB.
https://hub.docker.com/_/adminer/
なにはともあれ docker compose up
コマンドを打ってみました
ユーザー: root
パスワード: example
adminerコンテナ
http://localhost:8080/を訪れるとまさにデータベース管理ツールが起動されていました。
sequel proとかの一番簡易なものですかね。
ここで上記のユーザー、パスワードを入力すると、ログインできました。
dbコンテナ
docker desktopからターミナルに行き、
mysql -u root -pexample
とmysqlのコマンドラインに入ろうとすると、普通にログイン出来ました。
ここで、前の記事のdocker-compose.ymlファイルと比較して異なるのは以下の指定です。そのため、少し調べてみました
command: --default-authentication-plugin=mysql_native_password
restart: always
docker-compose.ymlにおいて
- command
- デフォルトのコマンドを上書きする
- https://docs.docker.jp/v1.12/compose/compose-file.html#id20
--default-authentication-plugin=mysql_native_passwordについて
- 古いハッシュ化アルゴリズムみたいです
- 現在は非推奨で、ed25519というプラグインが推奨されています
https://mariadb.com/kb/en/authentication-plugin-mysql_native_password/
https://mariadb.com/kb/en/authentication-plugin-ed25519/
- restart
- docker run のコマンドオプションに対応している
- コンテナ終了時の再起動の振る舞いについて規定している
- alwaysは終了ステータスに関わらず再起動する
- https://docs.docker.com/engine/reference/run/#restart-policies---restart
これらを前記事のdocker-compose.ymlファイルに追加したらmysqlが動くようになる・・・?(そんな気はしないですが…)
上記を追加し、以下の手順を試してみました
$ docker volume ls
$ docker volume rm xxx
$ docker compose up -d -build
docker volume ls
でNAMEが表示されなかったのは不便だなと思いました。docker-compose.ymlファイルでvolumeの名前を指定することもできたはずなので指定すべきだなと思いました
docker desktopで調べてみると、関係ないvolumeでした。(volume作成されてない…??)
再度試してみてもやはりうまくいかなかったです。
もはや公式のみを参照するというルールを一度棚に上げておき、ブログ記事の通りにやってみた
普通にうまくいきました。
異なるのはDockerfileぽいですね。
以前のDockerfile
# syntax=docker/dockerfile:1
FROM ruby:3.2
RUN apt-get update -qq && apt-get install -y nodejs default-mysql-client
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
# Add a script to be executed every time the container starts.
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000
# Configure the main process to run when running the image
CMD ["rails", "server", "-b", "0.0.0.0"]
参考にさせて頂いたブログ記事のDockerfile
FROM ruby:3.1
WORKDIR /app
COPY Gemfile /app/Gemfile
COPY Gemfile.lock /app/Gemfile.lock
RUN bundle install
CMD ["rails", "server", "-b", "0.0.0.0"]
ちなみに、postgresqlを使用して成功した時のDockerfileも載せておきます
# syntax=docker/dockerfile:1
FROM ruby:3.2
RUN apt-get update -qq && apt-get install -y nodejs postgresql-client
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
# Add a script to be executed every time the container starts.
COPY entrypoint.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3001
# Configure the main process to run when running the image
CMD ["rails", "server", "-b", "0.0.0.0"]
これらを踏まえると、entrypoint.shが悪さをしているわけではなさそうで、恐らく以下のコードがおかしいのかと予想が付きます
RUN apt-get update -qq && apt-get install -y nodejs default-mysql-client
postgresql-client
ではうまくいき、default-mysql-client
ではうまくいかない。
nodejsはDBとは全く関係なさそうなので無視してます。
psqlコマンドやmysqlコマンドを使用できるように、クライアント-サーバー通信を実現するためのアプリケーションをインストールしよう、というコマンドだと理解してます
もう一度初めから、手順を行ってみました。
なぜかうまくいきました。結局コードは悪くなく、何らかの手順を飛ばしていた可能性がありそうです。
変更した点としては、以下のようにバージョンを明示しました
docker-compose.yml
mysql:8.0.3
Gemfile
gem "rails", "~> 7.0.4"
また、docker compose run --no-deps web rails new . --force --database=mysql
コマンドを打った時に待ちきれずCtrl+cを打つなどをしてしまったかもしれないです
まとめ
一度やり直した方が早いこともある。
回り道をしながら知識を拾っていこう
ではまた。
今度こそmakeツールを使いたい!