AWSのEC2でとりあえずPHP Laravelを動かす

今回はこのEC2インスタンスにPHPとnignxをインストールしてLaravelを動かすまで持っていく。

環境
PHP 7.3
Laravel 5.8
Amazon Linux 2
PHP, nginx, php-fpm のインストール
AWSでLaravelを動かすには当然PHPをインストールする必要がある。また、HTTPリクエストを受け付けるために nginx をインストールし、nginx から PHP を起動するための php-fpm というモジュールをインストールする必要があるので、まずこれらをインストールする。

これらものジュールをインストールする方法はいくつかある

(1) ansibleなどの構成管理ツールを利用する (2) サーバー構築後に直接コマンドを叩いてインストールする (3) CloudFormation の UserData を利用してインストールする

一番理想なのは (1) のansibleなどを利用する方法だが、ちょっと試すには重すぎるので、今回は (2) の直接コマンドを叩いてインストールする。最後に CloudFormation を利用する方法もチラッと紹介する。

PHP と php-fpm を Amazon Linux にインストールする
# PHP 7.3 をインストールする
# 同時に php-fpm もインストールされる
sudo amazon-linux-extras install php7.3 -y

# yumのアップデートをしておく
sudo yum update -y
sudo yum upgrade -y

# PHP Laravel に必要なモジュールをインストールする
sudo yum install php-devel php-opcache php-mbstring php-xml php-mcrypt pyp-mysqlnd -y

# php-fpm を起動する
sudo systemctl start php-fpm.service

# サーバー起動時に php-fpm を自動で起動する
# 必要があればこのコマンドを叩く
sudo systemctl enable php-fpm.service
PHP Laravel に必要なモジュールたちだが、僕は上記コマンドに書いてあるモジュールだけをインストールしたら十分だった。Laravelの機能をフルに使っていなければ必要ないものもあるかもしれないし、Laravel以外のライブラリを導入していると上記以外のモジュールも必要かもしれないが、いれておいて損はないモジュールたちなので、一旦これだけいれておけば大丈夫だろう。

nginx を Amaxon Linux にインストールする
# nginx をインストールする
sudo amazon-linux-extras install nginx1.12 -y

# nginxを起動する
sudo systemctl start nginx.service

# サーバー起動時にnginxを自動的に起動する
# 必要があればこのコマンドを叩く
sudo systemctl enable nginx.service
アクセス権限が正しく設定されていれば、 http://のIP> で nginx のホーム画面が見られるはずだ。

各種設定
nginx の設定
続いてnginxの設定をしていく。今回のConfigファイルたちは以下のリポジトリにすべてまとめられている。


github.com

nginxの設定ファイルは /etc/nginx/ 以下にあり、デフォルトの設定は以下のようになっている。

https://github.com/yoshikyoto/aws-laravel-nginx-php/blob/master/nginx/nginx_default.conf

ここで重要なのは、この部分である。

    include /etc/nginx/conf.d/*.conf;

    server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  _;
        root         /usr/share/nginx/html;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location / {
        }

        error_page 404 /404.html;
            location = /40x.html {
        }

        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
}
include /etc/nginx/conf.d/*.conf は /etc/nginx/conf.d 以下に .conf で終わるようなファイルがあると自動的に読み込む設定である。基本的にアプリケーションごとの設定はここに置くことになる。また、意図せずここに .conf で終わるファイルをおいてしまうとその設定が読み込まれてしまうので注意が必要。

server はデフォルトで書かれているサーバーの設定である。これがあるので、インストール直後にhttpでアクセスするとnginxのページが見られる。この設定の場合は /usr/share/nginx/html/index.html などが表示される。

この設定は不要なのでコメントアウトしてしまう。（includeは残しておくこと）

# デフォルトの設定は不要なのでコメントアウトしてある
#    server {
#        listen       80 default_server;
#        listen       [::]:80 default_server;
#        server_name  _;
#        root         /usr/share/nginx/html;
#
#        # Load configuration files for the default server block.
#        include /etc/nginx/default.d/*.conf;
#
#        location / {
#        }
#
#        error_page 404 /404.html;
#            location = /40x.html {
#        }
#
#        error_page 500 502 503 504 /50x.html;
#            location = /50x.html {
#        }
#    }
コメントアウトした後のファイルがこちら

https://github.com/yoshikyoto/aws-laravel-nginx-php/blob/master/nginx/nginx.conf

続いて /etc/nginx/conf.d/laravel.conf を作成し、以下の内容を設定する。設定は Laravel Homestead で使われている設定を参考にした。

server {
    listen 80;
    server_name _;
    # /home/<username>/<app-directory-name>/public
    root "/home/laravel/laravel-app/public";

    index index.html index.htm index.php;

    charset utf-8;

    location / {
        try_files $uri $uri/ /index.php?$query_string;

    }

    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    access_log off;
    error_log  /var/log/nginx/laravel.error.log error;

    sendfile off;

    client_max_body_size 100m;

    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/var/run/php-fpm/www.sock;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;


        fastcgi_intercept_errors off;
        fastcgi_buffer_size 16k;
        fastcgi_buffers 4 16k;
        fastcgi_connect_timeout 300;
        fastcgi_send_timeout 300;
        fastcgi_read_timeout 300;
    }

    location ~ /\.ht {
        deny all;
    }
}
設定ファイル全体は https://github.com/yoshikyoto/aws-laravel-nginx-php/blob/master/nginx/conf.d/laravel.conf で見られる。重要な点をいくつか説明していく。

server_name
server_name _;
ここは、例えば server_name hoge.fuga.jp などと設定することもできる。server_name hoge.fuga.jp と設定した場合は、 hoge.fuga.jp でアクセスした場合のみこの設定が使われる。1つのサーバーで複数のアプリケーションを管理したいときに使う。

今回設定している _ は全てのホストにマッチする。

root
root "/home/laravel/laravel-app/public";
これが Laravel アプリケーションの public ディレクトリになるように設定する。

fastcgi_pass
最後に重要なのがここ

fastcgi_pass unix:/var/run/php-fpm/www.sock;
Amazon Linux に php-fpm をインストールしたときに、nginx から呼ばれるべき php-fpm のファイルは /var/run/php-fpm/www.sock にあるので、ここを正しく設定してやる。

php-fpm の設定
php-fpmの設定はデフォルトのままでいいが、知っておくべき点があるのでそこについて説明する。ちなみに、 php-fpm の設定は /etc/php-fpm.d/ 以下にある。

デフォルトの設定のままだが、設定ファイルは下記にある。

https://github.com/yoshikyoto/aws-laravel-nginx-php/blob/master/php-fpm/www.conf

ユーザーと権限
知っておかなければハマるのが、nginxとphp-fpmの実行ユーザーである。

nginxの実行ユーザーはデフォルトだと nginx である
php-fpm は nginx ユーザーから実行可能になっていなければならない
php-fpmの実行ユーザーはデフォルトだと apache である
Laravelの public dexirekutoriha apache ユーザーから実行可能になっている必要がある
nginx から php-fpm を実行可能になっていなければならない
nginx の実行ユーザーはデフォルトだと nginx になっている。これは nginx.conf の

user nginx;
この記述で決定されている。

nginxからphp-fpmを実行するという仕組み上、php-fpmはnginxユーザーから実行可能でないといけない。その設定をしているのが、 php-fpmの www.conf の

listen.acl_users = apache,nginx
この記述である。デフォルトでは apache ユーザーと nginx ユーザーから実行可能になっている。nginxの実行ユーザーを変更したい場合は上記2箇所を変更しないといけないが、ここは nginx から変える必要性はあまりないのでそのままでいいだろう。

php-fpm から PHP のコードが実行可能になっていなければならない
続いて、php-fpm の実行ユーザーについてである。最終的に php-fpm が laravel の public/index.php などを実行するので、php-fpm が laravel の php を実行する権限が必要である。php-fpm はデフォルトで apache ユーザーで実行されるようになっているので、この場合2つの方法があり。

laravel のディレクトリに、 apache ユーザーからの実行権限をつける
laravel ディレクトリの所有者と php-fpm の実行ユーザーの所有者を一致させる
前者の方が安全なので、僕は php-fpm の実行ユーザーはデフォルトの apache のまま、laravel ディレクトリに apache ユーザからの実行権限をつける方法を選択した。*1

今回は root /home/laravel/laravel-app/public としてある。 laravel-app ディレクトリはデフォルトでpermission 755 になっているので問題ないが。

/home
/home/laravel
など、親ディレクトリのパーミッションもちゃんと 755 になっていないと死亡するので注意（ここでめっちゃはまった）。

アプリケーションコードは /opt に置く流儀もあったりするのでそのあたりはご自由に。パーミッションだけ正しく指定できていれば問題ない。

動作確認
composer入れて composer install とかして、 .env とか php artisan key:generate とかすれば、Laravelは動作するはずである。