Docker 上の MySQL に外部からアクセス可能な user を作成 (して Emacs で接続するまで)
これまで docker も sql もあまり触っていなかったので使い始めるまでの流れをまとめた。 また Emacs から接続するのにかなり時間がかかったのでこれの流れについても備考としてまとめた。
Docker の MySQL のインストールと接続
https://github.com/docker-library/docs/tree/master/mysql
Docker の mysql 用の image が公開されている。 docker-compose などは利用せず単に起動した docker 内の mysql サーバーにコマンドライン等からアクセスすることを想定している。
起動から接続
基本的に README の通り
# dcoker の mysql image を DL $ docker pull mysql # docker mysql をベースに mysqld という名前で test_db というデータベースを作成しながらコンテナを起動 # <password> は任意のパスワード $ docker run --name mysqld -e MYSQL_ROOT_PASSWORD=<password> -e MYSQL_DATABASE=test_db -d mysql # 上の mysql に接続 $ docker run -it --link mysqld:mysql --rm mysql sh -c 'exec mysql -h"$MYSQL_PORT_3306_TCP_ADDR" -P"$MYSQL_PORT_3306_TCP_PORT" -uroot -p"$MYSQL_ENV_MYSQL_ROOT_PASSWORD"'
これでコマンドラインからの接続はできた。
外部から接続できる user を追加する
-- 上で mysql に接続した状態で -- どこからでも接続可能を意味する "%" で test_user をパスワード psword で追加 mysql> create user test_user@"%" identified by 'psword'; -- 権限を追加し確認後終了する mysql> grant all privileges on *.* to test_user@'%'; mysql> select host, user from mysql.user; +-----------+------------------+ | host | user | +-----------+------------------+ | % | root | | % | test_user | | localhost | mysql.infoschema | | localhost | mysql.session | | localhost | mysql.sys | | localhost | root | +-----------+------------------+ mysql> ^Dbye
# docker を再起動 $ docker restart mysqld # 新しい user で接続 $ docker run -it --link mysqld:mysql --rm mysql sh -c 'exec mysql -h"$MYSQL_PORT_3306_TCP_ADDR" -P"$MYSQL_PORT_3306_TCP_PORT" -utest_user -ppsword'
備考: bind-address
何かエラーがでた時に検索すると大抵 bind-address
が云々という記事が出てくるが基本的に docker 経由の場合は別な原因が殆である可能性が高い。
少し待ったり(!) docker を再起動したりすると問題が解決することがあった。
備考: Docker 上の MySQL に Emacs から接続する
普段 Emacs を利用しているので Emacs からも接続できるようにしたい。 まず以下のサイトの通りに始めはやってみたのだがうまくいかなかった。
http://rebeja.eu/use-emacs-sql-mode-to-connect-to-database-on-a-docker-image/
そのためいろいろ試した結果以下の流れでできた。
まず Docker で起動する時に -p でポートを指定する必要がある。
この時 -p 3306:3306
とローカル側の port を固定するとうまくいかなかったので -p 3306
としてローカル側のポートは自動的に割り振られるものを利用する。*1
# Docker 側の Port のみを指定して起動 $ docker run --name mysqld -e MYSQL_ROOT_PASSWORD=<password> -e MYSQL_DATABASE=test_db -p 3306 -d mysql # Port の確認 $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 6b098b7aeca6 mysql "docker-entrypoint.s…" 16 seconds ago Up 15 seconds 33060/tcp, 0.0.0.0:32771->3306/tcp mysqld
Emacs では sql-mysql
を利用するのだが、Port 指定がそのままではできないので以下を init.el
などに追加する。
ただし変数 sql-mysql-login-params
が一度 sql-mysql
を起動しなければ作られないので use-package
の :config
などで起動後に評価される必要がある。
(use-package sql :config (setq sql-mysql-login-params (append sql-mysql-login-params '(port))))
その後以下で接続する。
M-x sql-mysql User: root Password: <password> Database: test_db Server: 0.0.0.0 Port: 32771
おまけ
Docker 内のファイルに tramp 形式で簡単にアクセスできる拡張があり便利だった。
https://github.com/emacs-pe/docker-tramp.el
*1:毎回ポートを確認するのが面倒なので固定してうまくいく方法が知りたいです。