6
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Laravel のサーバー移行手順 ( PHP8)

Last updated at Posted at 2021-12-16

#はじめに
レンタルサーバーから、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のところは省きましょう)

#流れ

  1. DBを移行
  2. ディレクトリを移行
  3. composerとlaravelをインストール
  4. composer.jsonを修正
  5. .envファイルを修正
  6. nginx.conf修正
  7. パーミッション変更
  8. エラー集

#DBを移行
移行元のレンタルサーバーのDB管理ツールはphpmyadminが使われていましたので、SQLファイルとしてエクスポートします。
移行先のEC2には、DB管理ツールのadminerが入っていましたので、sqlファイルをインポートするだけです。

adminer導入手順はこちら記事が参考になります。

ダウンロードしたadminerファイル1つを、nginx.confのrootで設定しているルートディレクトリ配下に設置するだけです。

#ディレクトリを移行
レンタルサーバーのルートディレクトリ配下すべてをEC2サーバーに移します。
ただし、ルートディレクトリ直下のcomposer.lockvendorディレクトリは入れないでください。

###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を修正して、移行先に置きます。

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",
        },
composer.json.移行後
    {
        "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ファイルを修正
下記の箇所を変更します。

.env
APP_URL=http://IPアドレス ←サーバーのIPにする

DB_CONNECTION=mysql
DB_HOST=←RDSのエンドポイント(auroraの場合、ライターインスタンス)
DB_DATABASE=データベース名
DB_USERNAME=RDS作成時のユーザ名
DB_PASSWORD=設定したパスワード

#nginx.conf修正
以下のように記載しましょう。
nginxのrootservernameの箇所は、各々変えましょう。

nginx.conf
    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の箇所に書いています。

app/Http/Middleware/TrustProxies.php
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',
    ];

↓以下のように修正します。

app/Http/Middleware/TrustProxies.php
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
6
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?