GCE上のDockerコンテナ内のMySQLへ、一発で接続


やりたいこと

GCE上にDockerを使ってWebとDBのサーバーを動作させている。

アプリケーションは、お馴染みのWordPressとする。

手元のPCから、直接MySQLにログインしたい。

現状

手元のPCからMySQLにログインするには、以下の3ステップが必要。

  1. GCEへSSHログイン
  2. DB Serverとして起動しているDockerコンテナへログイン
  3. MySQLへログイン

この1~3を一発で行いたい。

1. SSHログイン

SSH鍵が未作成なら、以下コマンドで作成

(外部PC)$ ssh-keygen -t rsa -b 4096 -C "[email protected]"

cf. お前らのSSH Keysの作り方は間違っている - Qiita

公開鍵を登録

手元のSSH鍵でサーバーへログインできるように登録する必要がある。
以下の操作を、権限のある人に依頼する。

Compute Engine > Metadata > SSH Keys
で上の公開鍵を追加する。
(メールアドレスの @より前がユーザー名。)

SSH接続確認

(外部PC)$ ssh -i ~/.ssh/id_rsa [username]@[IP]

ログインできたらOK。

2. Dockerコンテナへログイン

まずはDockerでWordPressが起動していることを確認する。
以下はWordPress公式のdocker-compose.yml

docker-compose.yml
version: '3.1'

services:

  wordpress:
    image: wordpress
    restart: always
    ports:
      - 8080:80
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: exampleuser
      WORDPRESS_DB_PASSWORD: examplepass
      WORDPRESS_DB_NAME: exampledb
    volumes:
      - wordpress:/var/www/html

  db:
    image: mysql:5.7
    restart: always
    environment:
      MYSQL_DATABASE: exampledb
      MYSQL_USER: exampleuser
      MYSQL_PASSWORD: examplepass
      MYSQL_RANDOM_ROOT_PASSWORD: '1'
    volumes:
      - db:/var/lib/mysql

volumes:
  wordpress:
  db:

起動できた。

コンテナへのログインはこのコマンド。

(GCE)$ docker exec -it [コンテナID] bash
root@[コンテナID]:/var/www/html#

ログインできた。(プロンプトが切り替わってる)

(Ctrl + C でログアウトしておく。)

3. MySQLへログイン

(GCE)$ docker exec -it [コンテナID] mysql -u exampleuser -pexamplepass
mysql>

cf. Docker上でMySQLにログインする - Qiita

ログインできた。

実行してみる

DB接続は、Sequel Proというツールを使っている。

接続失敗!

ログを見てみると、SSHログインできているけど、 127.0.0.1 port 3306 への接続で失敗しているみたい。

...
debug1: Connection established.
...
debug1: Authentication succeeded (publickey).
...
debug1: Connection to port 53983 forwarding to 127.0.0.1 port 3306 requested.
...
open failed: connect failed: Connection refused

原因はPort

MySQLが動作しているのは、Dockerコンテナ内の3306番ポート。
アクセスしようとしていたのは、GCEの3306番ポート。
この2つを繋ぐ必要があった。
cf. Dockerでポートフォワーディング解説 - Qiita

以下のように修正。

docker-compose.yml
version: '3.1'

services:

  wordpress:
    image: wordpress
    restart: always
    ports:
      - 8080:80
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: exampleuser
      WORDPRESS_DB_PASSWORD: examplepass
      WORDPRESS_DB_NAME: exampledb
    volumes:
      - wordpress:/var/www/html

  db:
    image: mysql:5.7
    restart: always
    ports:
      - 3306:3306 # 追加した
    environment:
      MYSQL_DATABASE: exampledb
      MYSQL_USER: exampleuser
      MYSQL_PASSWORD: examplepass
      MYSQL_RANDOM_ROOT_PASSWORD: '1'
    volumes:
      - db:/var/lib/mysql

volumes:
  wordpress:
  db:

再起動させる。

(GCE)$ docker-compose down
(GCE)$ docker-compose up

プロセスを表示すると、Portsの表示が変わった。
0.0.0.0:3306->3306/tcp になってる。

変更前
(GCE)$ docker-compose ps
      Name                    Command               State          Ports
--------------------------------------------------------------------------------
test_db_1          docker-entrypoint.sh mysqld      Up      3306/tcp, 33060/tcp
test_wordpress_1   docker-entrypoint.sh apach ...   Up      0.0.0.0:8080->80/tcp
変更後
(GCE)$ docker-compose ps
      Name                    Command               State                 Ports
---------------------------------------------------------------------------------------------
test_db_1          docker-entrypoint.sh mysqld      Up      0.0.0.0:3306->3306/tcp, 33060/tcp
test_wordpress_1   docker-entrypoint.sh apach ...   Up      0.0.0.0:8080->80/tcp

再実行

接続できた!🎉