wardenを利用して Magento2ローカル開発環境を構築する


本記事は、[Magento Advent Calendar](https://adventar.org/calendars/4213) 21日目の記事となります。

注: warden解説記事の最新版は[こちら](https://qiita.com/kadowakiverite/items/b2bbd1a949c24e2b7732)です!(2021/3)


本記事では、巷で話題となっているMagentoローカル開発環境を容易に構築できる、[Warden](https://github.com/davidalger/warden)というCLIツールの使い方を紹介したいと思います。

既に実用的でかつ大変便利なツールではあるものの、最近ではAdobe Magento社のDeveloperからもプルリクエストが飛んでいるようで、現在進行形で爆速進化中といった様子です。

Wardenがやってくれること。

・SSLの終端制御とProxy/Routingによる、コンテナへのルーティング
・.testドメインに対するDNSレスポンス
・ローカル環境でのSSL証明書の発行
・Magento2インスタンスの構築

## 仕組み

Wardenは下記の構成で管理されています。

メインのWarden用コンテナが4つ。 Magentoインスタンス用のコンテナが9つ。


◆メイン

・Dnsmasq ・・・ *.testドメインへの名前解決を担当。 (/etc/hostsを手動で変更する必要がなくなる)
・Traefik ・・・ アクセスされたドメイン名を元に、各MagentoインスタンスのVarnishコンテナにルーティング。
・Portainer ・・・ DockerコンテナをGUIから操作できる便利ツール (放置気味。。)
・Sshd ・・・ MysqlWorkBenchなどからコンテナにアクセスするための、SSHトンネル用コンテナ

◆Magento（持て余すほどのフル構成)

- Varnish (ルーティング用にTraefie用のラベルが付けられている)
- Nginx (Cookieの値をみて、PHP-FPMを使い分ける設定がされている)
- PHP-FPM (n98-magerunが標準装備・Mailhogの設定済)
- PHP-FPM(Xdebug用)
- MariaDB (DockerHubの公式イメージ)
- Redis (Session・Cacheの保存用)
- ElasticSearch (検索・インデックス)
- RabbitMQ (非同期のメッセージングサービス)
- MailHog (メール送信テスト環境)

図にまとめてみるとこのような構成。

<img width="822" alt="warden.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/97920/452936a9-e348-6122-c3e4-ad25cebc0474.png">

#### 基本的な動き
ユーザからのhttpsアクセスに対して、dnsmasqコンテナでドメインの名前解決を行い、
Varnishに付与されているラベルを元に、traefikコンテナで各Magentoインスタンスへのリクエストのルーティングを行なっています。

Magentoインスタンスをいくつ増やしても、traefikが自動的にコンテナの生成を検知し、リクエストのルーティングを行ってくれるため、前段のdnsmasq、traefikを一切管理しなくて良いのが良いところ。

#### xdebugの有効/無効の切り替えが容易
wardenでは、php-fpmコンテナを常時二つ稼働させており、片方はxdebugの設定がされています。

CookieにXDEBUG_SESSIONキーが挿入されていると、php-fpm(xdebug用)が使用されるようにnginxで制御されています。

<img width="482" alt="php-fpm.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/97920/b6968e6d-a007-e96c-6bf6-cf3d6bb5962d.png">

#### Mailhogが捗る

デフォルトでPHP-FPMにMailhogの設定がされているため、Warden開発環境で送信されるメールは全てMailhogにプロキシーされます。

プロキシーされたメールは、https://mailhog.{project名}.test/ から確認可能。

使ってみるとこれがかなり便利。

<img width="1913" alt="スクリーンショット 2019-11-22 10.05.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/97920/a1def40d-659d-ed94-1803-3cc1f9eb30a7.png">


wardenの使い方↓

## 使い方 (mac向け)

まずはwardenのインストールと起動。

```
$brew install davidalger/warden/warden
$warden up
```
warden upコマンドで上記のメインとなる４コンテナが起動します。

```
$docker ps
CONTAINER ID        IMAGE                                   COMMAND                   CREATED             STATUS              PORTS                                                 NAMES
b4e8029d5655        jpillora/dnsmasq                        "webproc --config /e…"    23 hours ago        Up 23 hours         127.0.0.1:53->53/udp                                  dnsmasq
0030d07b863f        traefik:v1.7                            "/traefik --api --do…"    23 hours ago        Up 20 hours         127.0.0.1:80->80/tcp, 127.0.0.1:443->443/tcp          traefik
e671dabdd02e        portainer/portainer                     "/portainer"              23 hours ago        Up 23 hours         9000/tcp                                              portainer
ede5a56b6fef        panubo/sshd                             "/entry.sh /usr/sbin…"    23 hours ago        Up 23 hours         127.0.0.1:2222->22/tcp                                tunnel
```

正しく起動できていれば、下記URLでコンテナの稼働状況が確認できます。

- https://traefik.warden.test/
- https://portainer.warden.test/
- https://dnsmasq.warden.test/

Wardenの起動が完了したら、次はMagentoインスタンスを立ち上げていきます。

1.Magentoのソースコードが入ったディレクトリを作成

```
$composer create-project --repository-url=https://repo.magento.com/magento/project-community-edition magento2
```
2.環境設定の初期化: warden env-init [ProjectName] [EnvironmentType]
カレントディレクトリに、warden設定ファイルとなる.envが作成されます。

```
warden env-init project magento2
```
EnvironmentTypesは下記の３つがデフォルトで用意されています。(EnvironmentTypeは追加可能な様子)

- local
- Magento1
- Magento2

3.SSL証明書の作成・設定: warden sign-certificate [ProjectName].test

``` 
warden sign-certificate project.test
```

4.Magentoインスタンスの起動

```
warden env up -d
warden sync start
```

5.コンテナが立ち上がったら、php-fpmコンテナに入ってMagentoのインストール (日本語用)

```
$warden shell (php-fpmコンテナに入る。⇩コンテナ内で実行)
$bin/magento setup:install \
    --backend-frontname=admin \
    --amqp-host=rabbitmq \
    --amqp-port=5672 \
    --amqp-user=guest \
    --amqp-password=guest \
    --db-host=db \
    --db-name=magento \
    --db-user=magento \
    --db-password=magento \
    --http-cache-hosts=varnish:80 \
    --session-save=redis \
    --session-save-redis-host=redis \
    --session-save-redis-port=6379 \
    --session-save-redis-db=2 \
    --session-save-redis-max-concurrency=20 \
    --cache-backend=redis \
    --cache-backend-redis-server=redis \
    --cache-backend-redis-db=0 \
    --cache-backend-redis-port=6379 \
    --page-cache=redis \
    --page-cache-redis-server=redis \
    --page-cache-redis-db=1 \
    --page-cache-redis-port=6379 \
    --es-hosts="elasticsearch" \
    --admin-firstname=admin \
    --admin-lastname=admin \
    --admin-user=admin \
    --admin-email=user@example.com \
    --admin-password=admin123 \
    --language=ja_JP \
    --currency=JPY \
    --timezone=Asia/Tokyo \
    --base-url=https://app.project.test/ \
    --use-rewrites=1 \
    --cleanup-database
```

6.各アプリケーションにアクセス

- (Magento フロント): https://app.project.test/
- (Magento 管理画面): https://app.project.test/backend/
- (MailHog 管理画面): https://mailhog.project.test/
- (Rabbitmq 管理画面): https://rabbitmq.project.test/
- (ElasticSearch 接続先): https://elasticsearch.project:.test/

7.Magentoインスタンスの破棄

```
$warden env down -v #コンテナ・ボリューム・ネットワークの削除
$warden sync stop  #Mutagenセッションの終了
```

## 使用感

MailhogやX-Debug切り替えなど、細かい開発支援機能が散りばめられており、かなり便利な印象。

ファイル共有に[Mutagen](https://mutagen.io/documentation/transports/docker)を使用しており、Docker for MacでもVagrant使用時と変わらない速度感。

EnvironmentTypeを新たに追加することで、独自のMagentoインスタンス用のコンテナ群を構築することが可能です。

今回は触れませんでしたが、使用するPHPやVarnishのバージョンを指定することも出来るようです。

また、プロジェクト毎に使用したいコンテナを差し替えるといったことも出来るようになっているので、柔軟な開発環境が構築できそうです。

## おまけ


### MysqlWorkbenchの設定方法

MysqlWorkbenchの設定方法が少し分かりずらかったので、念のため共有させて頂きます。

<img width="657" alt="mysql.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/97920/a8356ac8-c674-eea0-555b-55c15801e8c3.png">

```
SSH Hostname: tunnel.warden.test:2222
SSh Username: user
SSh Password: なし
SSH Key File: $HOME/.warden/tunnel/ssh_key
Mysql Hostname: project_db_1 (プロジェクトのdbコンテナ名)
Mysql ServerPort:3306
Username : magento
Password : magento
```

### Livereloadの設定方法 (warden V2から利用可能)

1.env.phpに下記の内容を記載し、 bin/magento app:config:importを実行。

```
'system' => [
        'default' => [
            'design' => [
                'footer' => [
                    'absolute_footer' => '
                        <script id="__lr_script__">//<![CDATA[
                            document.write("<script src=\'/livereload.js?port=443\'/>");
                        //]]></script>
                    '
                ]
            ],
        ],
    ],
```

2.livereload.jsの埋め込みが確認できたら、下記のコマンドを実行。

```
warden shell
grunt clean
grunt exec:<theme_name>
grunt less:<theme_name>
grunt watch
```

### 便利コマンド
1. show processlist
watch -n 3 "warden db connect -A -e 'show processlist'"

### 各種コンテナのバージョン変更 (.env)
```
PHP_VERSION=7.1
MARIADB_VERSION=?
ELASTICSEARCH_VERSION=?
REDIS_VERSION=?
VARNISH_VERSION=?
RABBITMQ_VERSION=?
NODE_VERSION=?
```