Visual Studio Code Remote の Container を使って PHP / Laravel 開発環境を構築する話

発表されてしばらく時間経っていますが、VSCodeの Remote Development 拡張を使うことで、「ローカル」のエディタ(VSCode)を使いながら、直接リモートのソースコードや実行環境を利用することができる、という素晴らしいものが提供されています。

今回は、この拡張に含まれる “Remote – Containers” を使って、ローカルPCのDockerを使った開発環境構築を行なってみます。

目的

  • 複数人で開発する場合の環境の統一
  • 上記準備の手間削減

環境

ローカル

マシン: MacBook Pro 13inch (macOS 10.14.6)
Visual Studio Code: 1.37.1
Docker Desktop (Comunity): 2.1.0.1

Visual Studio Code には Remote Development 拡張と Docker Compose 拡張がインストール済みの前提です。

ターゲット (Container内の環境)

PHP: 7.3-apache-stretch
MySQL: 8.0
Laravel: 5.8

手順

Laravelの準備

composerを使って、Laravelのプロジェクトを新規作成してVSCodeで開きます。

% curl -o composer.phar https://getcomposer.org/download/1.9.0/composer.phar
% chmod 755 composer.phar
% ./composer.phar create-project --prefer-dist laravel/laravel container-sample "5.8.*"
% code container-sample

Docker Compose

Docker Compose を使えるように、諸々ファイルを作成していきます。
用意するファイルと階層は、下記となります。

docker-compose.yml
docker-files/
├── mysql/
│   ├── data/
│   └── docker-entrypoint-initdb.d/
└── php73/
    ├── 000-default.conf
    ├── Dockerfile
    └── docker-php-ext-xdebug.ini

docker-compose.yml

version: "3"

services:
  db:
    image: mysql:8.0
    command: --default-authentication-plugin=mysql_native_password
    ports:
      - 13306:3306
    volumes:
      - ./docker-files/mysql/data:/var/lib/mysql
      - ./docker-files/mysql/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
    environment:
      MYSQL_DATABASE: 'container-db'
      MYSQL_ROOT_PASSWORD: 'root'
  web:
    build: ./docker-files/php73
    ports:
      - 8080:80
    volumes:
      - .:/var/www/html

docker-files/php73/Dockerfile

FROM    php:7.3-apache-stretch
RUN     usermod -u 1000 www-data        \
    &&  groupmod -g 1000 www-data       \
    &&  a2enmod rewrite                 \
    &&  pecl install xdebug-2.7.2       \
    &&  apt-get update -y               \
    &&  apt-get install -y libzip-dev   \
    &&  docker-php-ext-enable xdebug    \
    &&  docker-php-ext-install pdo_mysql mysqli mbstring zip \
    &&  apt-get clean
COPY    000-default.conf /etc/apache2/sites-available/
COPY    docker-php-ext-xdebug.ini /usr/local/etc/php/conf.d/

docker-files/php73/000-default.conf

<VirtualHost *:80>
  ServerAdmin webmaster@localhost
  DocumentRoot /var/www/html/public

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

  EnableSendfile off
</VirtualHost>

docker-files/php73/docker-php-ext-xdebug.ini

zend_extension=xdebug.so
xdebug.remote_host = 127.0.0.1
xdebug.remote_autostart = 1
xdebug.remote_enable = 1
xdebug.remote_port = 9000

Visual Studio Code からの操作

20190827_002

VSCode の左下 >< をクリックします。すると、メニューが開くので、Reopen Folder in Container をクリックします。

引き続きメニューに出てくる From 'docker-compose.yml' をクリックします。

引き続きメニューに出てくる web をクリックします。

一旦 Remote モードに切り替わったVSCodeを確認しましょう。

左下のアイコンに Dev Container と表示されていますし、左側のエクスプローラに bindev といったディレクトリが見えます。これは、コンテナの中を直接みている、という証拠になります。

とはいえ、このままファイル操作するのも不便ですし、そもそも触ってはいけないファイルが見えているのも開発を進める上ではあまりよろしくありません。
そこで、アプリケーションの開発に必要なファイルだけが見える状態に切り替えましょう。

再度、VSCode の左下 >< をクリックします。

メニューの Reopen Folder in Locally をクリックします。

これで、通常のモードに戻りました。
続けて、左側のパネルの Docker Compose タグをクリックします。

出てきたコンテナ一覧の上の container-sample を右クリックし、メニューの Down をクリックします。

これで、作成されていたコンテナを一旦削除しています。

引き続き、.devcontainer.json が作成されているので、下記のように修正します。

.devcontainer.json

{
    "dockerComposeFile": "docker-compose.yml",
    "service": "web",
    "workspaceFolder": "/var/www/html",
    "extensions": [
        "felixfbecker.php-intellisense",
        "felixfbecker.php-debug",
        "onecentlin.laravel-extension-pack",
        "editorconfig.editorconfig"
    ]
}

これが、 Remote モードに切り替わった時の初期動作を定義することになります。

workspaceFolder を指定することで、アプリケーションのファイルだけが見える状態にしています。
extensions は、Remote モード切り替え後に使用する拡張を記載することができます。ただし、この拡張のインストールが “コンテナの作成時” のみなので、先ほど Down でコンテナの削除を行なっていました。

では、再度 Remote モードにしましょう。

左下のアイコンをクリックし、 Reopen Folder in Container をクリックします。

起動できたら、拡張タブをクリックして指定している拡張が有効になっているかを確認しておきましょう。有効じゃなかったら、有効にしておいてください。

動作確認1

http://localhost:8080

では、上記にアクセスしてみてください。
Laravelの初期ページが表示されることが確認できるはずです。

DB接続(マイグレーション)

今度は、コンテナとして起動しているデータベース db への接続ができることも確認していきます。

まずは、 .evn を下記のように修正します。修正箇所は DB_HOSTDB_DATABASEDB_USERNAMEDB_PASSWORD となるはずです。

.env

APP_NAME=Laravel
APP_ENV=local
APP_KEY=[YOUR_KEY]
APP_DEBUG=true
APP_URL=http://localhost

LOG_CHANNEL=stack

DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=container-db
DB_USERNAME=root
DB_PASSWORD=root

BROADCAST_DRIVER=log
CACHE_DRIVER=file
QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120

REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379

MAIL_DRIVER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null

AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=

PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
PUSHER_APP_CLUSTER=mt1

MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"

修正できたら、 artisan コマンドの migrate が使えるようになっているはずです。

VSCodeのターミナルを起動しましょう。

ターミナルが起動できたら、下記コマンドを実行してください。

# php artisan make:auth
# php artisan migrate

php artisan make:auth

こちらは、 Laravel 6 では利用できません。
詳しくは公式ドキュメントを参照してください。

https://laravel.com/docs/6.0/authentication#introduction

動作確認2

http://localhost:8080

再度上記にアクセスしてみてください。
Laravelの初期ページに、ユーザー登録とログイン機能が追加されたことが確認できるはずです。

REGISTER をクリックし、ユーザーを登録してみましょう。

下記のように Dashboard という画面になっていれば、DBを問題なく操作できていることになります。

デバッガ設定

では、デバッガを使ってみましょう。
左側のパネルのデバッガタブをクリックします。

クリックすると、デバッガのプロファイルのドロップダウンのところに “構成がありません” というのが見切れている状態だと思います。
歯車のアイコンに赤いマークが付いているので、こちらをクリックします。

メニューにいくつか選択肢が出てきますが、この中の PHP をクリックします。

launch.json というファイルが開かれて、その中にすでに PHP でデバッグするための設定が入っています。

プロファイルのドロップダウンに設定が反映されているので、 Listen for XDebug を選択し 緑の再生ボタンをクリックします。

VSCodeがデバッガモードで動き出すので、 app/Http/Controllers/HomeController.php を開き、26行目にブレークポイントを設定します。
また、左側のデバッガのブレークポイントで Everythng がすでにチェック済みの状態になっていると思いますが、こちらのチェックは外しておきます。

動作確認3

http://localhost:8080/home

上記にアクセスしてみてください。
ブレークポイントで停止することを確認できたはずです。

まとめ

“Dockerを使った開発環境の構築(デバッガつき)” を、とても簡単にできました。

もちろん、そのための準備として Dockerfiledocker-compose.yml を作るのに手間かかるのですが、作成してしまえばあとは「ローカルPC」ですべて完結しているのと同じ状態で開発を進めていくことができるようになります。

これは、どんどん使っていきましょう。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

*

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください