VSCode RemoteContainersでmoodleプラグイン開発環境を作った


概要

お仕事でmoodleプラグインを開発するにあたり、ローカルにApacheやらPHPやら色々入れるのが面倒だった1のでVSCode RemoteContainersを使ってサクッと作って壊せる開発環境を作った。

プラグインの開発環境としてだけではなく、ローカルでmoodleを動かす用途にも使えます。

作成したもの

aoisupersix/moodle-plugin-devcontainer

プラグイン自体はmoodle公式のチュートリアルにあった固定のHTMLを表示するブロックプラグインです。

動かし方

  1. Docker,VSCode,RemoteContainersを事前にインストール
  2. リポジトリをローカルに持ってきてVSCodeで開く

    git clone https://github.com/aoisupersix/moodle-plugin-devcontainer
    code moodle-plugin-devcontainer
    
  3. VSCode上でRemote-Containers: Open Workspace in Container...コマンドを実行しコンテナのセットアップを行う

  4. http://localhost:8080を開いてmoodleのインストールを行う

以上。楽ちん。

コンテナの構成

コンテナは

  • Apacheとmoodleを動かすメインのコンテナ(VSCode上で操作するコンテナ)
  • MariaDB
  • phpMyAdmin

の3つに分かれており、それらの定義は .devcontainer/docker-compose.ymlにあります。

version: "3"
services:
  mariadb:
    image: "docker.io/bitnami/mariadb:10.5-debian-10"
    user: root
    environment:
      - ALLOW_EMPTY_PASSWORD=yes
      - MARIADB_USER=moodle
      - MARIADB_DATABASE=moodle_db
    volumes:
      - "./container-volumes/mariadb_data:/bitnami/mariadb"
  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    environment:
      - PMA_ARBITRARY=1
      - PMA_HOST=mariadb
      - PMA_USER=moodle
      - PMA_PASSWORD=
    ports:
      - 8081:80
    volumes:
      - "./container-volumes/phpmyadmin_sessions:/sessions"
    depends_on:
      - mariadb
  moodle:
    build:
      context: ./moodle
      args:
        - MOODLE_VERSION=v3.10.0
    environment:
      - MOODLE_DBTYPE=mariadb
      - MOODLE_DBHOST=mariadb
      - MOODLE_DBNAME=moodle_db
      - MOODLE_DBPORT=3306
      - MOODLE_DBUSER=moodle
      - MOODLE_DBPASSWORD=
      - MOODLE_WWWROOT_URL=http://localhost:8080
    ports:
      - "8080:80"
    volumes:
      - "./moodle/php.ini:/usr/local/etc/php/php.ini"
      - "./moodle/config.php:/var/www/html/config.php"
      - "./container-volumes/moodledata_data:/var/www/moodledata"
      - "./container-volumes/phpunitdata_data:/var/www/phpunitdata"
      - "..:/var/www/html/blocks/simplestatichtml:cached" # Workspace directory in the container. /var/www/html/${plugin_type}/${plugin_name}
    depends_on:
      - mariadb

プラグインのコードが含まれるボリュームは特にDocker for Macで動作が遅くなるのを低減するために:cachedでマウントしてます。

      - "..:/var/www/html/blocks/simplestatichtml:cached"

MariaDBとphpMyAdminは公式で用意されているイメージをそのまま使っているだけですが、moodleについては開発用に適しているイメージが見つからなかったので自前で定義しました。

moodleコンテナ

.devcontainer/moodle/Dockerfile

FROM moodlehq/moodle-php-apache:7.4

ARG MOODLE_VERSION="v3.10.0"

ENV MOODLE_DBTYPE mariadb
ENV MOODLE_DBHOST localhost
ENV MOODLE_DBNAME moodle
ENV MOODLE_DBUSER moodle
ENV MOODLE_DBPASSWORD password
ENV MOODLE_PREFIX mdl_
ENV MOODLE_DBPORT 3306
ENV MOODLE_WWWROOT_URL http://localhost

# Set timezone
ENV TZ Asia/Tokyo
RUN echo "${TZ}" > /etc/timezone \
    && dpkg-reconfigure -f noninteractive tzdata

# Set locale
RUN echo 'ja_JP.UTF-8 UTF-8' >> /etc/locale.gen \
    && locale-gen \
    && update-locale LANG=ja_JP.UTF-8

# Install composer
COPY --from=composer /usr/bin/composer /usr/bin/composer

# Install xdebug
RUN pecl install xdebug-3.0.4 \
    && docker-php-ext-enable xdebug

USER www-data

# Clone moodle
RUN git clone https://github.com/moodle/moodle -b $MOODLE_VERSION --single-branch --depth 1 .

USER root

ApacheとPHPが入っており、moodleの各種ディレクトリがセットアップ済みのmoodlehq/moodle-php-apacheをベースにしています。

やっていることは

  • タイムゾーンとロケールの設定
  • composerのインストール(PHP_CodeSniffer等のインストールに必要なため)
  • xdebugのインストール
  • moodle本体のclone

です。

環境変数について

moodleの設定で今後変更される可能性がありそうな項目については環境変数として定義してdocker-compose.yml側で変更できるようにしています。

  • .devcontainer/moodle/Dockerfile
ENV MOODLE_DBTYPE mariadb
  • .devcontainer/docker-compose.yml
environment:
      - MOODLE_DBTYPE=mariadb

moodleの設定は.devcontainer/moodle/config.phpで、getenv()を使用して定義した環境変数を設定するようにします。

$CFG->dbtype = getenv('MOODLE_DBTYPE');

moodleインストール前にユーザを変更している理由

.devcontainer/moodle/Dockerfileでは、以下のようにユーザをwww-dataに変更してからmoodleをcloneしてますが、その理由について。

USER www-data

# Clone moodle
RUN git clone https://github.com/moodle/moodle -b $MOODLE_VERSION --single-branch --depth 1 .

USER root

moodleコンテナではApacheの実行ユーザがwww-dataとなっており、デフォルトのユーザであるrootでcloneしてしまうとmoodleディレクトリの書き込み権限がない状態になってしまうためです。

moodleをcloneした後にchown -R www-data:www-data /var/www/htmlを実行する、という方法でも対応可能ですがchownにめちゃくちゃ時間がかかるため上記のユーザを切り替える方法に落ち着きました。

phpMyAdminについて

MariaDBの操作をGUIで行える便利なツールで、開発用コンテナと一緒に動かしています。

http://localhost:8081からアクセスできます。

PHPのコードチェッカーとIntelliSenseのサポート

を使ってます。

これらの拡張機能はdevcontainer.jsonに記載してコンテナ初期化時に自動でインストールするようにしてます。

.devcontainer/devcontainer.json

    "extensions": [
        "wongjn.php-sniffer",
        "bmewburn.vscode-intelephense-client",

また、settings.jsonでこれらの拡張機能の設定を記載してます。

.vscode/settings.json

{
    "intelephense.environment.includePaths": [
        "/var/www/html"
    ],
    "phpSniffer.autoDetect": true,
    "phpSniffer.run": "onType",
    "[php]": {
        "editor.defaultFormatter": "wongjn.php-sniffer"
    }
}

intelephense.environment.includePathsにmoodleのルートディレクトリを指定することで、プラグインのコードに限らずmoodleのコード全体のコード補完が効くようにしてます。

コードチェッカーについては、moodleのコーディング規約が独特(ex. メソッドの命名規則がスネークケース等)なため、moodleコードチェッカープラグインのルールセット:ruleset.xmlを使用しています

xdebugでのデバッグ対応

xdebugはPHPのデバッグ等を可能にするツールです。
これを利用することでブレークポイントを貼って変数の中身を確認したり、ということが可能です。

xdebugのバージョンは現時点で最新の3.0.4を使用しています。
2.xと3.xで設定項目が全く異なるので注意が必要。

  1. moodleコンテナにxdebugをインストール

    .devcontainer/moodle/Dockerfile

    RUN pecl install xdebug-3.0.4 \
        && docker-php-ext-enable xdebug
    
  2. php.iniでxdebugのポートや自動起動の設定を行う

    .devcontainer/moodle/php.ini

    [xdebug]
    xdebug.mode=debug
    xdebug.start_with_request=yes
    xdebug.client_port=9000
    xdebug.log=/tmp/xdebug.log
    

    ポートは9000を使用しています。
    また、xdebug.start_with_request=yesを追加してデバッガを常に動かすように設定してます。

  3. VSCodeにxdebugの拡張機能をインストール

    PHP Debugの拡張機能をVSCodeにインストールします。
    今回の環境ではdevcontainer.jsonにPHP Debugの拡張機能を記載してコンテナ初期化時に自動でインストールされるようにしてます。

    .devcontainer/devcontainer.json

    "extensions": [
        "felixfbecker.php-debug",
    
  4. VSCodeからxdebugのポートに接続

    launch.jsonにxdebugのポートに接続する設定を記載します。

    .vscode/launch.json

    "configurations": [
        {
            "type": "php",
            "request": "launch",
            "name": "XDebug on DevContainer",
            "port": 9000,
            "hostname": "localhost",
            "pathMappings": {
                "/var/www/html/blocks/simplestatichtml": "${workspaceFolder}" // Workspace directory in the container. /var/www/html/${plugin_type}/${plugin_name}
            }
        },
    

    後はVSCodeで「Xdebug on DevContainer」を実行するとデバッグを有効にすることが可能です。

デバッグはプラグインのコードのみではなくmoodleの全コードに対して有効です。
例えば、ログイン時の動作を確認したい場合は/var/www/html/login/index.phpを開いてブレークポイントを貼れば処理の動きが確認できます。

moodleの設定

前述の通り.devcontainer/moodle/config.phpに定義しており、コンテナの/var/www/html/config.phpにマウントしています。

デバッグメッセージの表示

以下を追加しておくことで通常は表示されないデバッグメッセージや警告が表示されるようになります。
開発時に便利なので有効にしています。

// Debug display settings
// NOT FOR PRODUCTION SERVERS!
@error_reporting(E_ALL | E_STRICT);
@ini_set('display_errors', '1');
$CFG->debug = (E_ALL | E_STRICT);
$CFG->debugdisplay = 1;

管理者設定

環境作成の度にmoodleのUI上で設定が必要になり面倒な設定項目については、config.php上で定義しています。
例えば、サイトのデフォルト言語や管理者ユーザ名など。

これら以外でも管理者設定項目であれば何でも設定可能(なハズ)です。

// Admin settings
$CFG->lang = 'ja';
$CFG->admin = 'admin';
$CFG->noreplyaddress = '[email protected]';

なお、管理者ユーザのメールアドレスやパスワードもconfig.phpで定義できると便利なんですが、これは不可能だったので毎回手動で設定しています。

メール送信の対応

mailhogコンテナを一緒に動かしてメールサーバの設定を行えばmoodleからメール送信のテストが可能になります。

  • .devcontainer/docker-compose.yml
services:
  mailhog:
    image: 'mailhog/mailhog'
    ports:
      - '8025:8025'
  • .devcontainer/moodle/config.php
$CFG->smtphosts = 'mailhog:1025';

プラグイン種別やプラグイン名の変更

moodleのプラグインは、プラグイン種別ごとにmoodleの指定位置にプラグインを配置することで有効になります。
そのため、プラグイン種別やプラグイン名を変更する場合はそれに伴ってコンテナ等の設定変更が必要になります。

具体的には、以下3箇所の書き換えが必要です。

  • .vscode/launch.json
            "pathMappings": {
                "/var/www/html/blocks/simplestatichtml": "${workspaceFolder}" // Workspace directory in the container. /var/www/html/${plugin_type}/${plugin_name}
            }
  • .devcontainer/devcontainer.json
    "workspaceFolder": "/var/www/html/blocks/simplestatichtml", // Workspace directory in the container. /var/www/html/${plugin_type}/${plugin_name}
  • .devcontainer/docker-compose.yml
    volumes:
      - "..:/var/www/html/blocks/simplestatichtml:cached" # Workspace directory in the container. /var/www/html/${plugin_type}/${plugin_name}

開発環境の初期化

色々試しているうちに環境がグチャグチャになってしまった、等で環境を初期化したい場合について。
コンテナのボリュームが.devcontainer/container-volumesにあるので、それを削除すればOKです。

rm -rf .devcontainer/container-volumes

  1. 開発メンバーによってOSがWindowsだったりmacだったりとバラバラでそれぞれの構築手順を作成するのが面倒だったというのもある