WSL2でlandoローカル開発環境立ち上げ(risepe:acquia)

## はじめに
業務関係でWSL2環境におけるlando(Docker)環境の立ち上げを行いました。
その際の情報をかいつまんで備忘録代わりの記事にします。

Acquiaですでに動作をしているDrupalサイトを利用して、「acli」コマンドによるデプロイまで行えるローカル環境の立ち上げを行います。
BLTは今回使用していません。WSL2なのは私のマシンの都合なのでMac等でも手順は概ね同様と思われます。
また、ある程度Dockerについての知識を要しますので説明不足の点はご容赦ください。
## lando
https://docs.lando.dev/getting-started/
Drupalに限らず様々な環境をDockerで立ち上げられるパッケージツール。CMSのローカル環境構築時に設定が面倒なphpmyadminやMailHod,Xdebugが内包されており、.lando.ymlによる最小限の設定で環境構築が可能です。
欠点としては公式ドキュメントが英語かつ必要情報が不足気味なので、ある程度使い方がわかるまでの学習コストはやや高く、敷居も高いように感じました。
## 前提
https://docs.lando.dev/getting-started/installation.html
最新のlando-x64-v*.debをダウンロードしてローカルマシンのWSL2環境に適用済み
あらかじめローカルにAcquiaアプリケーションのリポジトリをクローンします。WSL2環境上にソースを配置することが前提です。
## プロジェクト構成
立ち上げに関係しないファイルやディレクトリは割愛しています。
```
<ProjectName>_____.devcontainer
                |_.vscode__launch.json
                |        |_php.ini(★今回はここでphpの設定)
                |_.gitignore(★編集)
                |_docroot(最初から存在)__sites__default__setting.php(★編集)
                |                     |                 |_default.setting.php
                |					  |                 |_setting.local.php(★新規追加)
                |                     |_phpmyadmin__phpmyadmin-misc.ini(★場合によっては追加が必要)  
                |                     |_phpinfo.php(★場合によっては追加が必要)  
                |_.lando.yml(★★★≒docker-compose.yml 記述スタイルが異なる) 
```
## .lando.yml
今回はrecipe: acquiaでの立ち上げを行うための設定をします。
参考:https://docs.lando.dev/acquia/config.html

```
name: drupal-lando-appname
recipe: acquia
config:
  acli_version: latest
  ah_application_uuid: <Your Own Acquia application uuid>
  ah_site_group: <Your Own Acquia application name>
  build:
    run_scripts: false
  cache: true
  inbox: true
  composer_version: '2'
  php: '8.0'
　# /app以下に自動的にマウントされます
  webroot: .
  xdebug: true
  config:
    php: .vscode/php.ini
services:
  appserver:
　　# overrides:により一部docker-compose.ymlで出来る指定が.lando.yml内でも行える
    overrides:
      environment:
        XDEBUG_MODE: debug
　　　　# client_host=以降は後述するlaunch.json内の"hostname"と合わせてください
        XDEBUG_CONFIG: "client_host=127.0.0.1"
  database:
    type: 'mysql:5.7'
    portforward: 3309
    overrides:
      container_name: <my_database_container_name>
  phpmyadmin:
    type: 'phpmyadmin:5.0'
    hosts:
      - database
    overrides:
      container_name: <my_phpmyadmin_container_name>
　　　# 今回phpmyadminのインポート容量を変更するために、オーバーライド用の専用ファイルを追加します
      volumes: 
        - ./docroot/phpmyadmin/phpmyadmin-misc.ini:/usr/local/etc/php/conf.d/phpmyadmin-misc.ini
```
## docroot
Drupalプロジェクト内を編集します。setting.phpおよびsetting.local.phpの変更はAcquiaリポジトリにコミットしてしまわないように気を付けてください。
setting.local.phpが存在しない場合は/site/defeult/default.setting.phpをコピーして作成してください。
##### sites>default>files>setting.php      ：設定追記(★必須)
##### sites>default>files>setting.local.php：DB接続設定記述(★必須)
##### phpmyadmin>phpmyadmin-misc.ini       ：phpmyadminの設定を上書きするために必要(必須ではない)
##### phpinfo.php                          ：ローカル上のPHPの設定を確認するために必要(必須ではない)
#### sites>default>files>setting.php 
```
# 777行目付近(コメントアウト解除)
if (file_exists($app_root . '/' . $site_path . '/settings.local.php')) {
  include $app_root . '/' . $site_path . '/settings.local.php';
}
# 800行目付近
if (file_exists('/var/www/site-php')) {
  require('/var/www/site-php/<acquia_enviroment_app_name>/<acquia_enviroment_app_name>-settings.inc');
}
```
#### sites>default>files>setting.local.php
```
# 78行目付近をコメントアウトして以下修正
# ※1.risepe:acquiaの場合は'database''username''password'は全てデフォルトで'acquia'に設定されているため今回はそのまま利用。
# ※2.ポートはコンテナ内部におけるポート番号なので常に3306設定
$databases['default']['default'] = array(
  'database' => 'acquia',
  'username' => 'acquia',
  'password' => 'acquia',
  'prefix' => '',
  'host' => 'database',
  'port' => '3306',
  'namespace' => 'Drupal\\Core\\Database\\Driver\\mysql',
  'driver' => 'mysql',
);
```
#### phpmyadmin>phpmyadmin-misc.ini
```
allow_url_fopen = Off
max_execution_time = 300
max_input_vars=100000
memory_limit = 100M
post_max_size = 100M
upload_max_filesize = 100M
```
#### phpinfo.php 
```
<?php
phpinfo();
?>
```

## .vscode .devcontainer
※一部を除き必須ではありません。
##### .vscode>launch.json             ：VSCodeのPHP Debug用
##### .vscode>php.ini　　             ：Xdebug用設定、WSL2環境CA証明設定
##### .devcontainer>devcontainer.json ：VSCodeのRemoteDevelopment開発用
##### .devcontainer>docker-compose.yml：VSCodeのRemoteDevelopment開発用
#### .vscode>launch.json
```
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Listen for XDebug",
            "type": "php",
            "request": "launch",
　　　　　　// landoはXDebug 3を使用しており、デフォルトのポートに9003を指定している
            "port": 9003,
            "log": false,
　　　　　　// landoはXDebug 3を使用しており、デフォルトのポートに9003を指定している
            "hostname": "127.0.0.1",
            "pathMappings": {
                "/app/": "${workspaceRoot}/",
            }
        }
    ]
}
```
#### .vscode>php.ini
```
; Xdebug(lando_acquiarecipe_drupalrecipi_Xdebug_config)
xdebug.max_nesting_level = 256
xdebug.show_exception_trace = 0
xdebug.collect_params = 0
xdebug.mode = debug
xdebug.start_with_request = yes
xdebug.client_host = ${LANDO_HOST_IP}
xdebug.remote_enable = 1
xdebug.remote_autostart = 1
xdebug.remote_host = ${LANDO_HOST_IP}
xdebug.log = /tmp/xdebug.log

; CA(lando_acquiarecipe_acli_config)
; この設定はacliコマンドを実行したデプロイ時に必須となる
openssl.cafile="/etc/ssl/certs/ca-certificates.crt"
openssl.capath="/etc/ssl/certs"
curl.cainfo="/etc/ssl/certs/ca-certificates.crt"

```
#### .devcontainer>devcontainer.json
```
{
	"name": "Existing Docker Compose (Extend)",

	// Update the 'dockerComposeFile' list if you have more compose files or use different names.
	// The .devcontainer/docker-compose.yml file contains any overrides you need/want to make.
	"dockerComposeFile": [
		"docker-compose.yml"
	],

	// The 'service' property is the name of the service for the container that VS Code should
	// use. Update this value and .devcontainer/docker-compose.yml to the real service name.
	"service": "phpmyadmin",

	// The optional 'workspaceFolder' property is the path VS Code should open by default when
	// connected. This is typically a file mount in .devcontainer/docker-compose.yml
	"workspaceFolder": "/app",

	// Set *default* container specific settings.json values on container create.
	"settings": {},

	// Add the IDs of extensions you want installed when the container is created.
	"extensions": [                     
        "felixfbecker.php-debug",
        "coenraads.bracket-pair-colorizer-2",
        "oderwat.indent-rainbow",
        "streetsidesoftware.code-spell-checker",
        "mosapride.zenkaku"
    ],
	// Use 'forwardPorts' to make a list of ports inside the container available locally.
	"forwardPorts": [
		9003
	],
}
```
#### .devcontainer>docker-compose.yml
```
version: '3'
services:
    volumes:
    # Update this to wherever you want VS Code to mount the folder of your project
      - .:/workspace:cached
    # Overrides default command so things don't shut down after the process ends.
    command: /bin/sh -c "while sleep 1000; do :; done"
```
## .gitignore
デプロイに必要のないディレクトリを追加しましょう。
#### .gitignore_例
```
docroot/sites/*/files
docroot/sites/*/private
docroot/sites/*/config
docroot/sites/*/default.services.yml
docroot/sites/*/default.settings.php
docroot/sites/*/services.yml
docroot/sites/*/settings.php
docroot/sites/*/settings.local.php
.lando.yml
.acquia-cli.yml
.vscode/*
.devcontainer/*
docroot/phpmyadmin/*
docroot/phpinfo.php
docroot/xdebug_info.php
```
## 立ち上げ
#### lando start
.lando.ymlが存在するディレクトリ上でコマンドを実行します。
主要なものは以下です。
```
// 新規立ち上げ
lando start
// .lando.yml変更内容等を反映
lando rebuild
// 現在の環境を全削除して立ち上げ
lando destroy -y && lando start
// 立ち上げた環境の動作確認
lando info
```
立ち上げ後は以下のようなプロキシサーバーがプロジェクトのコンテナに加えて立ち上がります。
これはリバースプロキシの役割を果たしており、立ち上げ時に自動的にポートの割り当てをしてくれます。
![dockerdesktop2022-05-10 112153.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273267/c3ab92d9-1cbd-cee0-93e1-68247b415003.png)
#### サイトへのアクセス
立ち上げたアプリケーションは以下のようにポートが自動的に割り当てられています。
80/tcpの方で接続しましょう。
![port 2022-05-10 130404.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273267/9f721c5d-545b-88d0-0d95-a1aa5c2ac6db.png)

## acliコマンドによるデプロイ
Acquia環境との接続やデプロイはlando acliコマンドを使用して行います。
#### auth:login
Acquia Cloud Platform環境へログインを行う(あらかじめCloud PlatformのAPI Tokens画面から使用できるKEYとSECRETを発行しておく)
![create_token 2022-05-10 131713.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273267/91bf67f3-c28e-370a-7566-a019373d59bc.png)
```
lando acli auth:login -k [KEY] -s [SECRET]
```
#### ssh-key:create-upload
ローカルからの接続認証用の専用キーをAcquia Cloud Platform環境へ登録する
```
lando acli ssh-key:create-upload
```
#### DBデータ、静的ファイルインストール
app_user_nameにはAcquia Cloud Platform対象環境上のユーザ名を入れる
これにより先程のサイトアクセス時はDrupalの新規設定画面であったものがAcquia上のアプリケーションと同期できる。
例：application.dev
```
lando acli pull:database <app_user_name>
lando acli pull:files <app_user_name>
```
#### DBデータ、静的ファイルデプロイ
目標の環境へローカル作業後のDBデータ、静的ファイルを反映させるためにはpull:databaseコマンドを使用する。
ソースのデプロイについてはリポジトリ上から行う。
```
lando acli pull:database <app_user_name>
lando acli pull:files <app_user_name>
```
(参考)
https://www.youtube.com/watch?v=_9uq8Wl8YcA

## その他
以下は立ち上げ後のエラー対応についてです。
【drush crが実行できない】
（git bash）コンテナ内からdrush実行
```
root@7d1466ff19f3:/app/docroot/vendor/bin# drush cr
PHP Warning:  pcntl_exec(): Error has occurred: (errno 13) Permission denied in phar:///usr/local/bin/drush/includes/startup.inc on line 422

Warning: pcntl_exec(): Error has occurred: (errno 13) Permission denied in phar:///usr/local/bin/drush/includes/startup.inc on line 422
Error has occurred executing the Drush script found at /app/docroot/vendor/bin/drush
(errno 13) Permission denied
```
（ubuntu）drushファイルのパーミッション変更
```
chmod 755 drush
```
その後改めてdrush cr
```
root@7d1466ff19f3:/app/docroot/vendor/bin# drush cr
PHP Warning:  pcntl_exec(): Error has occurred: (errno 13) Permission denied in phar:///usr/local/bin/drush/includes/startup.inc on line 422

Warning: pcntl_exec(): Error has occurred: (errno 13) Permission denied in phar:///usr/local/bin/drush/includes/startup.inc on line 422
Error has occurred executing the Drush script found at /app/docroot/vendor/bin/drush
(errno 13) Permission denied
```
改めてdrush cr実行
```
root@7d1466ff19f3:/app/docroot/vendor/bin# drush cr
/usr/bin/env: 'php\r': No such file or directory
```
/docroot/vendor/drush/drush/drushの改行コードをLFに変更します。


【キャッシュクリアを実行できない】
コマンドラインからdrush cr でキャッシュクリアあるいはDrupalの管理タブからキャッシュ操作を行おうとした際に出たエラーです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273267/d7c6cbf5-745d-a1e7-3333-f198ef0fcc39.png)
(Drupal\Core\File\Exception\FileException: Failed to unlink file 'public://google_tag/<site_tag>/google_tag.script.js'.)
#root@drupal_service:/var/www/html/sites/default
次のコマンドでgoogle_tagフォルダーとスニペットファイルの所有権が正しくないという問題が修正されました。
```
sudo chown -R www-data:www-data ./files/google_tag/
```

【コンテナ立ち上げ時】
Cannot create container for service mysql: not a directory
DockerDesktopの再起動で解消

【acliコマンド実行時にローカルDBに接続できない】
Unable to connect to local database using credentials mysql:://acquia:acquia@database.hostname.internal/acquia. ERROR 2005 (HY000): Unknown MySQL server host 'database.hostname.internal' (-2)
ローカルDBのホスト名が異なることが原因。以下修正。
```
database:
    type: 'mysql:5.7'
    portforward: 3309
    overrides:
      #追加
      hostname: <hostname>
```

【WSL2環境DNS解決(composer_require)】
WSL2の設定変更が必要。
参考：https://qiita.com/kkato233/items/1fc71bde5a6d94f1b982