Drupal9からDrupal10へバージョンアップする

***この記事ではDrupal9からDrupal10へバージョンアップする方法についてご紹介します。***

私はこれまで10サイトのバージョンアップを実施してきました。
この記事では実際の経験を踏まえてDrupalのバージョンアップについて説明します。

:::note warn
この記事で説明するバージョンアップとは
メジャーバージョンを上位互換する作業を指します。
例）Drupal8 → Drupal9
　　※以下のケースは対象外です。
　　　Drupal9.5 → Drupal9.7
:::

# バージョンアップの目的
バージョンアップをする目的は2点です。
- サイトの安全性を担保するため
- より効率的な操作を実現するため

Drupal10の場合は非推奨のコードが削除されたり要件であるPHPのバージョンが上がっています。
このような対応をすることで脆弱性を高めることができ、安全にサイトを利用することができます。

またコアテーマが刷新したりこれまでコントリビュートモジュールであったモジュールがコアテーマに変更されるため、
開発者やサイトを利用するエンドユーザーの利便性にもつながります。

# 環境要件（前提）
使用している環境がバージョンアップを実行できる(= Drupal10を利用できる)環境であるか確認します。

WebサーバーやPHPなど一部のミドルウェア等はDrupalの管理画面から確認することができます。
[ログイン後]レポート > サイトの状態
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622183/3a8bbcf7-ca59-7c34-efdf-f4957ca995a4.png)

## ブラウザ
以下ブラウザの最新メジャーバージョン

- Google Chrome
- FireFox
- Safari
- Safari for iOS
- Microsoft Edge
- Opera

## データベース
以下のDBMSおよびバージョンが推奨されています。

- MariaDB 10.3.7+
- MySQL/Percona 5.7.8+

また次の構成が推奨されています。

- プライマリストレージエンジンとしてInnoDBを採用していること
- PDOデータベース拡張機能

MySQLやMariaDBを使用する場合、
推奨されているトランザクション分離レベルは「 ***READ COMMITTED*** 」です。
デフォルトは「REPEATABLE READ」ですがデッドロックが発生してサイトアクセスに影響が及ぶ可能性があります。
***非推奨のレベルは利用可能ですがサポートされていないことにご注意ください。***

## Webサーバー
後述のPHPバージョンの要件を満たすPHPが搭載されているWebサーバーで動作します。
- Apache 2.4.7+
- Nginx 0.7.x, 0.8.x, 1.0.x, 1.2.x, 1.8.x, 1.9.x
- MS IIS 5,6,7,8,10

## PHP
DrupalはPHPで動作しています。
以下のPHPバージョンであればDrupal10に対応しています。
- PHP8.1.x以上（推奨はPHP8.1.6）

## Composer
Drupalのパッケージ管理はComposerを使用します。
以下のComposerであればDrupal10に対応しています。
- Composer 2.3.6以上

# バージョンアップをするための準備
## Drupal9.4または9.5系にバージョンアップする
環境が確認出来ても、もし利用しているDrupalがバージョン9.3以下の場合、
一度Drupal9.4または9.5以上にバージョンアップする必要があります。

## コントリビュートテーマ/モジュールをアップデートする
DrupalのCoreをバージョンアップする前に、
サイトにインストールされているコントリビュートテーマやモジュールをDrupal10に互換性のあるバージョンにアップデートします。

Drupal10に互換性のあるバージョンが存在するかどうかはUpgrade Statusモジュールを使用します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622183/b8b284dc-d7ee-8c22-4f8b-9fb9df996f5a.png)

https://www.drupal.org/project/upgrade_status

このモジュールはサイトにインストールされている / インストール可能なモジュールが上位メジャーバージョンに対応しているかどうかをチェックしてくれます。
互換性のないモジュールについては作成者に互換バージョンの作成を依頼する必要があります。
※ただし多くの場合は互換性のあるバージョンが公開されていることが多いです。

## カスタムテーマ/モジュールをアップデートする
カスタムテーマ / モジュールを使用している場合は
コードにDrupal10系で廃止されたコードが無いことを確認する必要があります。
カスタムテーマ / モジュール内のコードについても、上述のUpgradeStatusがチェックしてくれます。

## 非推奨のモジュールやテーマの使用を停止する
もしDrupal10で廃止されたモジュールやテーマを使用している場合はアンインストールしてください。

# バージョンアップを実施
ここまで準備できたらいよいよバージョンアップを実施します。
具体的な実行手順は次の通りです。（パスについては環境に応じて変更してください。）

## 設定ファイルに一時的に書き込み権限を付ける
Drupalの設定を管理するファイルを一時的に書き込みできるようにします。
```
chmod 777 web/sites/default
chmod 666 web/sites/default/*settings.php
chmod 666 web/sites/default/*services.yml
```

## composerを使ってパッケージを取得する
パッケージ間の依存関係が相互に合わないことを回避するために必ず--no-updateオプションを付けます。
```
composer require 'drupal/core-recommended:^10' 'drupal/core-composer-scaffold:^10' 'drupal/core-project-message:^10' --update-with-dependencies --no-update
```

もしdrupal/core-devを使用している場合は以下も実行します。
```
composer require 'drupal/core-dev:^10' --dev --update-with-dependencies --no-update
```

## モジュールやテーマのコードをDrupal10向けにアップデートする
```
composer update
```

## データベースをDrupal10向けにアップデートする
コードをアップデート出来たらDBもアップデートします。
```
drush updatedb
```

## 設定ファイルを読み取り専用に戻す
手順の最初に書き込みを許可した設定ファイルは読み取り専用ファイルに戻します。
```
chmod 755 web/sites/default
chmod 644 web/sites/default/*settings.php
chmod 644 web/sites/default/*services.yml
```

## 管理画面でバージョンを確認する
サイトの状態でバージョンを確認してDrupal10になっていればバージョンアップ完了です！
お疲れさまでした！

# バージョンアップを通してつまずいたところ
## コントリビュートモジュールがDrupal10でサポートされていない時の対応
サイトに導入されているモジュールの中にはDrupal9でサポートが終了しており、
後方互換版がリリースされていないモジュールもありました。

このような場合、検討した対応案としては以下の2つでした。

issueを作成して後方互換版をリリースしてもらう
代用可能なモジュールを採用する
→　全てのケースで2.を実施

1.についてはissueをあげたとしてもコントリビューターが必ずしも対応するとは限らないですし時間もかかることが予想されました。

そのため代用できるモジュールがないか探してそれをバージョンアップ後にインストールすることで対応しました。

## コードをアップデートするときに依存関係エラーが多発し、それを解消したこと
Drupalのモジュールには依存関係というものがあります。

例えば
モジュールAを使うにはモジュールBもインストールしなければならない。
というような事象です。

この場合は
モジュールBをバージョンアップした後にモジュールAをバージョンアップすれば問題ありません。

多くの場合は片一方から依存されているのですが、中にはお互いに依存しているケースもありました。

例えば
モジュールAを使うにははモジュールBをインストールしなければならない。
かつ、モジュールBを使うにもモジュールAをインストールしなければならない。
というようなケースです。

この場合はcomposer.json上でDrupal10に対応したバージョンを記載し、
***composer update実行時に–lockオプションをつけて実行しました。***

# さいごに
今回はDrupal9からDrupal10へバージョンアップする方法についてご紹介しました。
Upgrade Statusモジュールが大部分をチェックしてくれるのでかなり効率よくバージョンアップ作業ができるかなと思います。

最短で2024年7月29日にDrupal11がリリースされる予定です。
Drupal11についてもバージョンアップの概要が発表され次第、記事書こうかなと思っています。