この記事は現役ウェブディベロッパーがわかりやすさにこだわって作成しました
残念ながら、host.docker.internal
では、Dockerホストを参照できませんでした。
手動で設定する方法
ipコマンドでローカルPCのIPアドレスを調べます。仮に192.168.11.4
とします。
$ ip a
2: enp3s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
inet 192.168.11.4/24 brd 192.168.11.255 scope global dynamic noprefixroute enp3s0
Code language: Bash (bash)
php-pecl-xdebug
のインストール直後の15-xdebug.ini
をDockerコンテナから取り出しておきます。xdebug.remote_host
の箇所を編集します。その他のxdebug項目も編集しておきます。
;編集前
;xdebug.remote_host = localhost
;編集後
xdebug.remote_host = "192.168.11.4"
xdebug.remote_autostart = 1
xdebug.remote_enable = 1
xdebug.remote_port = 9000
xdebug.idekey = my_project_idekey
Code language: plaintext (plaintext)
Dockerfile
のどこか終わり付近で、編集済みの15-xdebug.ini
をDockerコンテナにコピーします。
COPY 15-xdebug.ini /etc/php.d/
CMD ["/usr/sbin/httpd", "-D", "FOREGROUND"]
Code language: Dockerfile (dockerfile)
git cloneした直後に1回だけやればいいんだけど...
IPアドレスを書いてしまったから、15-xdebug.iniをgit commitできないし
この手順をwikiに書くのも面倒だし、
めったにやらないから、すぐに忘れてしまって、wikiを検索するのも面倒ね
実験
調べると、Dockerコンテナ内で、DockerホストのIPアドレスを調べるには、ip
コマンドとawk
コマンドを使って、
[root@869574d22dc0 /]# ip route
default via 192.168.192.1 dev eth0
192.168.192.0/20 dev eth0 proto kernel scope link src 192.168.192.3
[root@869574d22dc0 /]# ip route | awk 'NR==1 {print $3}'
192.168.192.1
Code language: Bash (bash)
この「192.168.192.1
」と「host.docker.internal
」を /etc/hosts
に追加します。
[root@869574d22dc0 /]# cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
192.168.192.3 869574d22dc0
192.168.192.1 host.docker.internal
Code language: Bash (bash)
Dockerコンテナ内の/etc/php.d/15-xdebug.ini
を編集します。
xdebug.remote_host = host.docker.internal
Code language: plaintext (plaintext)
httpd
を再起動します。
[root@869574d22dc0 /]# /usr/sbin/httpd -k restart
Code language: plaintext (plaintext)
Dockerホスト側のPhpStormで、ブレークポイントで止まりました!
DockerホストのIPアドレスを調べて、host.docker.internal
として、/etc/hosts
に登録する、これを自動で設定したいわけです。
自動で設定する方法
「DockerホストのIPアドレスを調べて、host.docker.internal
として、/etc/hosts
に登録する」処理は、Dockerfile
に記述できません。
Dockerコンテナを起動するたびに、Dockerコンテナのネットワークアドレスが変わるからです。
Dockerコンテナを起動するとき、これまでのCMD
処理は
- Webサーバを起動する
だけでしたが、
- DockerホストのIPアドレスを調べて、
host.docker.internal
として、/etc/hosts
に登録する - Webサーバを起動する
ようにします。
Dockerfile
Dockerfile
を次のように変更します。
# 修正前
CMD ["/usr/sbin/httpd", "-D", "FOREGROUND"]
Code language: Dockerfile (dockerfile)
# 修正後
RUN yum install -y iproute # ipコマンドのインストール。Dockerfileのどこに挿入してもかまいません
COPY init.sh /root/init.sh
CMD "/root/init.sh"
Code language: Dockerfile (dockerfile)
init.sh
次に、init.sh
を作ります。これまでDockerfile
のCMD
で実行していた内容に合わせて、置き換えてください。
#!/bin/sh -ue
# /etc/hostsにDockerホストのIPアドレスを登録する
echo $(ip route | awk 'NR==1 {print $3}') host.docker.internal >>/etc/hosts
# Webサーバの起動
/usr/sbin/httpd -D FOREGROUND
Code language: PHP (php)
Dockerイメージをビルドして、起動します。
$ sudo docker-compose build
$ sudo docker-compose up -d
$ sudo docker-compose ps
Code language: Bash (bash)
Dockerコンテナにbash
でログインします。
docker-compose.yml
で、container_name: php72.hoge.docker
と設定しているなら、
$ sudo docker exec -it php72.hoge.docker bash
[root@869574d22dc0 /]#
Code language: Bash (bash)
/etc/hosts
を表示してみると、
[root@869574d22dc0 /]# cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
192.168.192.3 869574d22dc0
192.168.192.1 host.docker.internal
Code language: Bash (bash)
無事、最後の行に「192.168.192.1 host.docker.internal
」が追加されました。このdockerコンテナ内から、host.docker.internal
で、起動元のPCが見えるようになりました。
15-xdebug.ini
これで、15-xdebug.ini
のxdebug.remote_host
の箇所は、IPアドレスではなく、host.docker.internal
と書くことができます。
xdebug.remote_host = host.docker.internal
xdebug.remote_autostart = 1
xdebug.remote_enable = 1
xdebug.remote_port = 9000
xdebug.idekey = my_project_idekey
この記事についてのご質問またはお困りのことがございましたら、お気軽にお問い合わせください。