[Ubuntu] docker内のxdebug.remote_hostを自動で設定するには

Docker for Macの場合

Dockerコンテナ内からDockerホストは、host.docker.internalで参照できます。

15-xdebug.inixdebug.remote_hostには、次のように書きます。

xdebug.remote_host = host.docker.internal

Ubuntuの場合

残念ながら、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

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

Dockerfileのどこか終わり付近で、編集済みの15-xdebug.iniをDockerコンテナにコピーします。

COPY 15-xdebug.ini /etc/php.d/ CMD ["/usr/sbin/httpd", "-D", "FOREGROUND"]

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

この「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

Dockerコンテナ内の/etc/php.d/15-xdebug.ini を編集します。

xdebug.remote_host = host.docler.internal

httpdを再起動します。

[root@869574d22dc0 /]# /usr/sbin/httpd -k restart

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"]
# 修正後 RUN yum install -y iproute # ipコマンドのインストール。Dockerfileのどこに挿入してもかまいません COPY init.sh /root/init.sh CMD "/root/init.sh"

init.sh

次に、init.shを作ります。これまでDockerfileCMDで実行していた内容に合わせて、置き換えてください。

#!/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

Dockerイメージをビルドして、起動します。

$ sudo docker-compose build $ sudo docker-compose up -d $ sudo docker-compose ps

Dockerコンテナにbashでログインします。

docker-compose.ymlで、container_name: php72.hoge.docker と設定しているなら、

$ sudo docker exec -it php72.hoge.docker bash [root@869574d22dc0 /]#

/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

無事、最後の行に「192.168.192.1 host.docker.internal」が追加されました。このdockerコンテナ内から、host.docker.internal で、起動元のPCが見えるようになりました。

15-xdebug.ini

これで、15-xdebug.inixdebug.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

これでgitcommitできるね

DockerfileRUN sedしてもいいし、

さっき作った、init.shで、sedしてもいいわね

タイトルとURLをコピーしました