Windows10のDocker環境で Atom + Xdebug を動作させる

# はじめに
Xdebugを使いたいとずっとふわっと思ってて、過去に何回かチャレンジするもうまくいかず。。
最近やっとこ上手くいったのでまとめます。

自分もDocker初心者なので、Dockerファイルの内容についても色々調べつつ進めていたので、
同じように初心者の方へ参考になれば。

# とりあえずうまくいった設定方法
典型的なLAMPの構成です。

## 構成
myapp(任意のアプリ名)/
　├ docker-db/
　│　└  initdb.d/
　│　　　　└  init.sql　※mysqlの初期流し込みSQL
　├ html/ ※ドキュメントルートに展開されるファイル
　│　└  index.html
　├ log/
　├ 000-default.conf
　├ docker-compose.yml
　├ Dockerfile
　└ php.ini
　

```dockerfile:Dokerfile
# ベースのDockerイメージを指定：DockerHUBからイメージ[php]のタグ[7.1-apache]を指定
# https://hub.docker.com/
FROM php:7.1-apache

# php設定ファイルを独自指定とするため上書き
COPY ./php.ini /usr/local/etc/php/

# サーバー初期処理
# apt-get update : パッケージ情報の更新
# apt-get install : パッケージのインストール/更新
#  git : GIT
#  unzip : ZIPの解凍
#  libzip-dev : zip圧縮の基本ライブラリー
#  libicu-dev : Unicodeと他の文字コードとの間の変換をしてくれるライブラリ
#  libonig-dev : マルチバイト文字をサポートする正規表現関数のために必要なライブラリ
#  vim : テキストエディタ
#  locales : ロケール（言語と地域）設定
# locale-gen ja_JP.UTF-8 : # ロケールを追加
# localedef -f UTF-8 -i ja_JP ja_JP : # ロケール環境の定義
# ここからインストール完了後のゴミデータ削除処理
# apt-get clean : /var/cache/apt/archivesにキャッシュされたパッケージファイルを削除する
# rm -rf /var/lib/apt/lists/* : /var/cache/apt/list にキャッシュされている全てのパッケージリストを削除
# docker-php-ext-install : PHPエクステンションインストール
#  intl : phpの国際化用拡張モジュール
#  pdo_mysql :  PDO MySQL 拡張モジュール
#  mysqli : MySQLi拡張モジュール
#  zip :  zip 拡張モジュール
#  bcmath : bcmath 拡張モジュール
RUN apt-get update && \
  apt-get -y install git unzip libzip-dev libicu-dev libonig-dev vim && \
  apt-get -y install locales && \
  locale-gen ja_JP.UTF-8 && \
  localedef -f UTF-8 -i ja_JP ja_JP && \
  apt-get clean && \
  rm -rf /var/lib/apt/lists/* && \
  docker-php-ext-install intl pdo_mysql mysqli zip bcmath

# ENV <name> <value>でコンテナ内で使える環境変数を指定
ENV DOCUMENT_ROOT=/var/www/html/
# linuxの言語にUTF-8を指定
ENV LANG ja_JP.UTF-8
ENV LANGUAGE ja_JP:ja
ENV LC_ALL=ja_JP.UTF-8

# UTC(協定世界時)→JST(日本時間)に変更
RUN cp -p /usr/share/zoneinfo/Japan /etc/localtime

# composer 2.0 のインストール
COPY --from=composer:2.0 /usr/bin/composer /usr/bin/composer

# ログディレクトリとwebルートディレクトリ作成
RUN mkdir -p /var/www/log /var/www/session \
&& chown -R www-data:www-data /var/www/log/ /var/www/session/ \
&& mkdir -p ${DOCUMENT_ROOT}

# DockerFIleのワークディレクトリを指定
# これ以降の処理のパス指定はここ基準で設定される
WORKDIR ${DOCUMENT_ROOT}

# 開発用にxdebugインストール
RUN pecl install xdebug-2.9.8 && docker-php-ext-enable xdebug

# debian 系の apache で mod_rewrite を有効化する
RUN a2enmod rewrite
# apacheの設定ファイルにhtaccessの許可設定を指定
COPY ./000-default.conf /etc/apache2/sites-available/

# 外部公開するポート
EXPOSE 80
```
Xdebugは、Xdebugがインストールされているサーバー側からローカル側へDebug用のデータを飛ばすので
9000番は外部公開不要です。（その辺の動きも理解出来てなく、色々ハマっていました；）

```conf:000-default.conf
<VirtualHost *:80>
    # The ServerName directive sets the request scheme, hostname and port that
    # the server uses to identify itself. This is used when creating
    # redirection URLs. In the context of virtual hosts, the ServerName
    # specifies what hostname must appear in the request's Host: header to
    # match this virtual host. For the default virtual host (this file) this
    # value is not decisive as it is used as a last resort host regardless.
    # However, you must set it for any further virtual host explicitly.
    #ServerName www.example.com

    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/html

    # Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
    # error, crit, alert, emerg.
    # It is also possible to configure the loglevel for particular
    # modules, e.g.
    #LogLevel info ssl:warn

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined

    # For most configuration files from conf-available/, which are
    # enabled or disabled at a global level, it is possible to
    # include a line for only one particular virtual host. For example the
    # following line enables the CGI configuration for this host only
    # after it has been globally disabled with "a2disconf".
    #Include conf-available/serve-cgi-bin.conf

    <Directory /var/www/html>
        Options Indexes FollowSymLinks MultiViews
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>
```
```ini:php.ini
[Core]
display_errors = On
error_reporting = E_ALL
error_log = /var/www/log/apache2/error.log
log_errors = On

[Date]
date.timezone = 'Asia/Tokyo'

[mbstring]
mbstring.language = Japanese
mbstring.internal_encoding = auto
mbstring.http_input = auto
mbstring.http_output = auto
mbsting.encoding_translation = Off
mbstring.detect_order = auto

[xdebug]
xdebug.remote_enable=1
xdebug.remote_host=host.docker.internal
xdebug.remote_port=9000
xdebug.remote_handler=dbgp
xdebug.remote_mode=req
xdebug.remote_autostart=1

```

```yml:docker-compose.yml
version: '3.7'
services:
    app:
        container_name: web
        build: .
        image: app_server:lastest
        ports:
            - '8080:80'
        depends_on:
            - db
        volumes: 
            - ./html:/var/www/html
            - ./log:/var/www/log
        privileged: true
        restart: always
    db:
        container_name: db
        image: mysql:5.7.12
        ports:
            - "33306:3306"
        command:
            - --sql-mode=
        volumes:
            # 初期データ流し込み指定フォルダ
            - ./docker-db/initdb.d:/docker-entrypoint-initdb.d
            # Dbデータ永続化するときにマウントするvolume
            - db:/var/lib/mysql
        environment:
            MYSQL_ROOT_PASSWORD: root
        restart: always

# DBはトランザクションデータのため、外部データボリュームに永続化
volumes:
    db:
```
appのポート変換も、app側からローカル側にデータを飛ばすので
```
ports:
    - '9000:9000'
```
のような指定は不要です。

## Xdebugの設定ポイント
Xdebugのインストール

```dockerfile:Dokerfile
# 開発用にxdebugインストール
RUN pecl install xdebug-2.9.8 && docker-php-ext-enable xdebug
```
phpinfoで、Xdebugの項目があればインストールが成功しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171074/8fd342b7-f965-a981-f849-6a656f71ecd6.png)

php.iniでxdebugのパラメータ設定
~~xdebug.remote_hostはhost.docker.internalでいけるみたいな記事もありましたが、
Windows環境だからなのか上手くいかず。作業端末のIPアドレスを指定してやるとうまく通りました。~~
動きを理解して改めて「host.docker.internal」設定してみたらちゃんと通りました。

```ini:php.ini
[xdebug]
xdebug.remote_enable=1
xdebug.remote_host=host.docker.internal
xdebug.remote_port=9000
xdebug.remote_handler=dbgp
xdebug.remote_mode=req
xdebug.remote_autostart=1
```

## Atomの設定
### php-debugの設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171074/6bd03e9e-939c-3bba-64c2-64a1f7cb9cd8.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171074/246469ee-539a-9661-800b-68e974f54e27.png)

## 動作確認
breakpointを付けて、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171074/19113c05-3d79-62e4-6cdb-c4a9e678d74d.png)


Webサーバーにアクセスして、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171074/130d99a8-530f-4f79-58ce-0e80c2d71017.png)


デバッグが始まれば成功です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171074/87006110-0025-42c2-e003-7634823d7c82.png)