#はじめに
レンタルサーバーから、AWSEC2の移行する際に、苦戦したため、手順を記載します。
移行前は、apacheでPHP7、移行先はnginxでPHP8となっています。
#前提条件
-
VPC,サブネット,EC2,RDSは構築済み
-
移行前
- レンタルサーバー
- PHP7.1
- apache2.4
- Laravel 5.5
- phpmyadmin
-
移行後
- AWS EC2 AmazonLinux2
PHP8.0
nginx
-
Laravel6以上
(PHP8に対して、laravel6以上が対応しているため) - RDS MYSQL
- adminer(phpmyadminでもよい)
- EC2 + RDS + Nginx + PHP8 + Adminer の構築は↓が参考になります。(wordpressのところは省きましょう)
#流れ
- DBを移行
- ディレクトリを移行
- composerとlaravelをインストール
- composer.jsonを修正
- .envファイルを修正
- nginx.conf修正
- パーミッション変更
- エラー集
#DBを移行
移行元のレンタルサーバーのDB管理ツールはphpmyadminが使われていましたので、SQLファイルとしてエクスポートします。
移行先のEC2には、DB管理ツールのadminerが入っていましたので、sqlファイルをインポートするだけです。
adminer導入手順はこちら記事が参考になります。
ダウンロードしたadminerファイル1つを、nginx.confのroot
で設定しているルートディレクトリ配下に設置するだけです。
#ディレクトリを移行
レンタルサーバーのルートディレクトリ配下すべてをEC2サーバーに移します。
ただし、ルートディレクトリ直下のcomposer.lock
とvendorディレクトリ
は入れないでください。
###composer.lockとは
composer.json を元にインストールされたパッケージなどが具体的に記述されています。
この lock ファイルを利用すれば、同じ環境を作ることができます。
###composer.jsonとは
composer.json には、必要とするライブラリの種類と、必要なバージョンの条件が書かれているファイルです。
新しいサーバーには、composer.json を元に、コマンドcomposer install
でLaravelのバージョンやライブラリをインストールします。
しかし、composer.lockも新しいサーバーにある場合、composer.lockをもとにインストールされてしまいますので、移行しないようにしましょう。
コマンド | composer.lock | 動作 |
---|---|---|
composer install | なし | composer.json を元にインストールされ、composer.lock が作成されます |
composer install | あり | composer.lock を元にインストール |
composer update | あり | composer.json を元にアップデートされ、composer.lock が更新されます |
vendorディレクトリ
は、Composer の依存内容をおくところです。
vendor、はサーバにインストールされているPHPのバージョンやPHP拡張によって、中身が変わる可能性があるからです。なので、そのサーバ上でvendor以下を構築する作業(composer install)をしないとまともにLaravelが動かない可能性があります。
#composerとlaravelをインストール
composerインストール方法はこちらの記事が参考になります
laravelのインストールとパスを通します。
$ composer global require "laravel/installer" --prefer-dist
$ export PATH=$HOME/.composer/vendor/bin:$PATH
$ source ~/.bash_profile
#composer.jsonを修正
移行前は、PHP7,Laravel5.5
移行先は、PHP8,Laravel6とします。
移行前のcomposer.jsonを修正して、移行先に置きます。
{
"require": {
"php": ">=7.0.0",
"fideloper/proxy": "~3.3",
"laravel/framework": "5.5.*",
"laravel/tinker": "~1.0"
},
"require-dev": {
"fzaninotto/faker": "~1.4",
"phpunit/phpunit": "~6.0",
},
{
"require": {
"php": ">=7.0.0|^8.0",
"fideloper/proxy": "^4.0",
"laravel/framework": "^6.0",
"laravel/tinker": "^1.0"
},
"require-dev": {
"fakerphp/faker":"^1.9.1",
"phpunit/phpunit": "^9.3",
},
修正が必要な箇所のみ記載しています。
###PHP8の影響
LaravelでPHP8を使用するには、以下のcomposer.jsonファイル3つをバージョンアップする必要があります。
ちなみに、PHP8では、fzaninotto/faker
は使用できないため、fakerphp/faker
を使用します。
php:^8.0
fakerphp/faker:^1.9.1
phpunit/phpunit:^9.3
詳細↓
ただし、移行元でPHP7を使用していたため、影響が出ないよう"php": ">=7.0.0|^8.0"
としています。
3つのバージョンを挙げない場合、
PHP8からgetClass()
メソッドが非推奨になっており、警告出て、php artsan
コマンドが実行できなくなるため必ず記載しましょう。
PHP 8では、ReflectionParameterクラスの次のメソッドは非推奨になりました。
ReflectionParameter::getClass()
ReflectionParameter::isArray()
ReflectionParameter::isCallable()
以下のようなエラーが出ます。
Deprecated: Method ReflectionParameter::getClass() is deprecated in /Users/.../Sites/.../vendor/laravel/framework/src/Illuminate/Container/Container.php on line 871
Deprecated: Method ReflectionParameter::getClass() is deprecated in /Users/.../Sites/.../vendor/laravel/framework/src/Illuminate/Container/Container.php on line 945
Deprecated: Method ReflectionParameter::getClass() is deprecated in /Users/.../Sites/.../vendor/laravel/framework/src/Illuminate/Container/Container.php on line 871
Deprecated: Method ReflectionParameter::getClass() is deprecated in /Users/.../Sites/.../vendor/laravel/framework/src/Illuminate/Container/Container.php on line 945
###laravel6
laravelを5系から6系にアップデートする際、composer.jsonで以下の3つをアップデートする必要があります。
"fideloper/proxy": "^4.0",
"laravel/framework": "^6.0",
"laravel/tinker": "^1.0"
composer.jsonのバージョン表記についてはこちらの記事が参考になります。
#.envファイルを修正
下記の箇所を変更します。
APP_URL=http://IPアドレス ←サーバーのIPにする
DB_CONNECTION=mysql
DB_HOST=←RDSのエンドポイント(auroraの場合、ライターインスタンス)
DB_DATABASE=データベース名
DB_USERNAME=RDS作成時のユーザ名
DB_PASSWORD=設定したパスワード
#nginx.conf修正
以下のように記載しましょう。
nginxのroot
やservername
の箇所は、各々変えましょう。
server {
listen 80;
listen [::]:80;
server_name _;
root /usr/share/nginx/html;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location / {
try_files $uri $uri/ /index.php?q=$uri&$args;
}
error_page 404 /404.html;
location = /404.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
#パーミッション変更
composer installして、composer.jsonを元に、ライブラリ等がインストールされます。
$ composer install
最後に、所有者と権限を変えます。
ルートディレクトリは、/usr/share/nginx/html/laravel6
とします。
ec2-userユーザーでSFTP接続をして開発するため、nginx:ec2-user
としています。
本番時は、権限を狭めましょう。
$ sudo find /usr/share/nginx/html/laravel6 -type d -exec chmod 775 {} +
$ sudo find /usr/share/nginx/html/laravel6 -type f -exec chmod 664 {} +
$ sudo chown -R nginx:ec2-user /usr/share/nginx/html/laravel6
$ sudo chown -R nginx:ec2-user /var/log/nginx
$ sudo chown -R nginx:ec2-user /var/log/php-fpm
以下の記事の権限が良いかもしれません。
では、アクセスすると、サーバー移行が完了していると思います。
エラーが出た場合は、以下のコマンドでログを確認しましょう。
$ sudo cat /usr/share/nginx/html/laravel6/storage/logs/laravel.log
$ sudo cat /var/log/nginx/error.log
#エラー集
私が遭遇したエラーの一部を紹介します。
##bootstrap/cacheのディレクトリがない。権限がない。
作成し、nginxの権限を加えましょう。
laravel.ERROR:
The /usr/share/nginx/html/laravel/bootstrap/cache
directory must be present and writable.
{"exception":"[object] (Exception(code: 0):
The /usr/share/nginx/html/laravel6/bootstrap/cache
directory must be present and writable.
at /usr/share/nginx/html/laravel6/vendor/laravel/framework/src/Illuminate/Foundation/
##TrustProxies.phpファイルを修正
laravel.ERROR: Symfony\Component\HttpFoundation\Request::setTrustedProxies(): Argument #2 ($trustedHeaderSet) must be of type int, array given, called in /usr/share/nginx/html/laravel6/vendor/fideloper/proxy/src/TrustProxies.php on line 54 {"exception":"[object] (Symfony\\Component\\Debug\\Exception\\FatalThrowableError(code: 0): Symfony\\Component\\HttpFoundation\\Request::setTrustedProxies(): Argument #2 ($trustedHeaderSet) must be of type int, array given, called in /usr/share/nginx/html/laravel6/vendor/fideloper/proxy/src/TrustProxies.php on line 54 at /usr/share/nginx/html/laravel6/vendor/symfony/http-foundation/Request.php:574)
App\Http\Middleware\TrustProxies
を書き換えるようにする必要があります
↓以下の記事のTrusted Proxies
の箇所に書いています。
protected $proxies;
protected $headers = [
Request::HEADER_FORWARDED => 'FORWARDED',
Request::HEADER_X_FORWARDED_FOR => 'X_FORWARDED_FOR',
Request::HEADER_X_FORWARDED_HOST => 'X_FORWARDED_HOST',
Request::HEADER_X_FORWARDED_PORT => 'X_FORWARDED_PORT',
Request::HEADER_X_FORWARDED_PROTO => 'X_FORWARDED_PROTO',
];
↓以下のように修正します。
protected $proxies = '*';
protected $headers = Request::HEADER_X_FORWARDED_ALL;
##php artisanコマンド実行時
Call to undefined function str_slug()
というエラーが出ました。
以下の記事が参考になりました。
##ログファイルの権限不足
PHP Fatal error: Uncaught UnexpectedValueException: The stream or file "/usr/share/nginx/html/laravel6/storage/logs/laravel.log" could not be opened in append mode: Failed to open stream: Permission denied in /usr/share/nginx/html/larave6/vendor/monolog/monolog/src/Monolog/Handler/StreamHandler.php:146
ログファイルの権限がないようです。nginxの権限を与えましょう
$ sudo chown nginx:ec2-user /usr/share/nginx/html/larave6/storage/logs/laravel.log