どーも、yutaです。
Dockerでローカルの開発環境を作るのにDBのコンテナを作成せず、Webサーバ用コンテナからAWSのRDS等、外部のDBへ接続する環境を作りました。
しかもsshポートフォワーディングの踏み台経由していく感じです。
本当はね、ローカル内で収まるようにしたかったのですが、データ量が大きかったりスキーマの管理上やらざるを得なかった等、ちょっと濁しますが面白かったので解説します。
目次
全体構成
構成としては下記です。
ローカルPCで踏み台経由でRDSへ繋ぐとかはありますが、Sequel Proだと下記のようにして繋ぐ感じです。
それではやっていきます。
コンテナの構築
まずはDBに繋ぐコンテナを用意します。
ディレクトリ構成
├── docker-compose.yml
├── php
└── Dockerfile
こんな感じの構成ですが、試し用に作った感じなので結構適当です。
docker-compose.ymlとDockerfile
version: '3'
services:
app:
container_name: php
build: ./php
tty: true
volumes:
- ${PWD}:/var/www/html
ports:
- 80:80
FROM php:7.2-apache
RUN apt-get update && \
apt-get -y install mariadb-client
WORKDIR /var/www/html
EXPOSE 80
上記のファイルをもとにコンテナをbuild&upして作られたか確認します。
% docker-compose up --build -d
% docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
xxxxxxxxxxxx test_app "docker-php-entrypoi…" 36 seconds ago Up 3 seconds 0.0.0.0:80->80/tcp php
接続方法
sshポートフォワーディングの実施
ローカルPC側でsshポートフォワーディングを実行します。これはDBを利用する間は実行が必要になります。
# ホストのローカルPCから実行する
% ssh -i ~/.ssh/nakamura.pem -N -L 3307:rdsのエンドポイント.amazonaws.com:3306 nakamura@踏み台サーバ名
ちなみに好みの問題ですがコンテナ内で実行させるという手もあるかなと。
その場合はpemファイル等の場所をdocker-compose.ymlに記載する必要がある。
あとsshのコネクション切れた時にうっかり気づけない可能性もあるので、取り敢えずローカルPC側で繋ぎました。
コンテナへbashログインでDB接続
% docker exec -it php bash
root@xxxxxxxxxxxx:/var/www/html#
# mysql -utest -P 3307 -h host.docker.internal -p
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
~省略~
MySQL [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| xxxxxxxxx |
+--------------------+
2 rows in set (0.037 sec)
ここで大事なのは、mysqlコマンド実行時に指定する `host.docker.internal` のホスト名ですね。これを利用することでホストへアクセスすることが可能になります。
後はもうアプリケーション側でコマンドで使った接続情報を書けば普通に繋げます。