EC2にLaravelプロジェクトをデプロイする

何気にEC2でLaravelアプリをちゃんとデプロイしたことがなかったのでやってみましたが、 デプロイして見れる状態になるまでかなり苦労しました。

一連の流れを書いたつもりですが、長くなってしまい若干殴り書き感あるのはご了承ください

環境・利用ツール

手順

EC2インスタンスの用意

  • AMI: Amazon Linux 2 AMI (HVM), SSD Volume Type - ami-0992fc94ca0f1415a (64 ビット x86)
  • インスタンスはt4g.micro以上がおすすめです
  • ボリューム: 16GBくらい。8だと色々やってるうちに容量不足になってしまいました
  • セキュリティグループ

    • HTTP: 0.0.0.0/0
    • HTTPS: 0.0.0.0/0
    • SSH: 自分のIP

サーバーのセットアップ

sshでEC2インスタンスに入ります。

こちらを全体的に参考にさせていただきました。感謝 https://qiita.com/ntm718/items/f896c8e4fb801777954b

  • sudo yum update -y
  • sudo yum install php-cli php-pdo php-fpm php-json php-mysqlnd php-bcmath php-mbstring php-xml -y

deployのパーミッション付与

sudo mkdir /var/www

groupadd nginx
sudo usermod -a -G nginx ec2-user
sudo chown -R ec2-user:nginx /var/www

sudo chmod 2775 /var/www
find /var/www -type d -exec sudo chmod 2775 {} \;

# /var/www およびそのサブディレクトリのファイル許可を繰り返し変更してグループの書き込み許可を追加します。
find /var/www -type f -exec sudo chmod 0664 {} \;

参考: https://gist.github.com/lostandfound/4bee82837886902e1b14bbf548fe5d1e

nodejs/npmインストール

https://tecadmin.net/install-latest-nodejs-amazon-linux/

sudo yum install -y gcc-c++ make
curl -sL https://rpm.nodesource.com/setup_14.x | sudo -E bash -
sudo yum install -y nodejs

node -v
> v15.6.0

yarnのインストール

curl -o- -L https://yarnpkg.com/install.sh | bash
source .bashrc

参考: https://fukatsu.tech/ec2-yarn

PHPのインストール

PHPバージョンは適宜調整してください。

sudo amazon-linux-extras install php7.4

composerのインストール

https://agohack.com/install-composer-on-aws-linux/

# composer をダウンロードする
curl -sS https://getcomposer.org/installer | php
# PATHを通す
sudo mv composer.phar /usr/local/bin/composer

composer とうって動くのを確認。

php-fpmの起動

  • 起動

    • sudo service php-fpm start
  • 確認

    • sudo systemctl status php-fpm
  • 自動起動

    • sudo systemctl enable php-fpm

最後にphp-fpm -vのバージョンもphp -v と同様であることを確認します

nginxのインストール・設定

sudo amazon-linux-extras enable nginx1
sudo amazon-linux-extras install nginx1 -y

sudo systemctl start nginx
sudo systemctl status nginx
sudo systemctl enable nginx

設定したらブラウザからEC2のURLを叩くとnginxの初期画面が確認できると思います。 例:ec2-*-***-***-***.ap-northeast-1.compute.amazonaws.com

php-fpm設定

sudo vi /etc/php-fpm.d/www.conf

- listen=/var/run/php-fpm.sock
+ listen=/var/run/php-fpm/php-fpm.sock # 更新

- user = apache
+ user = nginx # 更新

- group = apache # 更新
+ group = nginx # 更新
# 下記は追記
listen.owner = nginx
listen.group = nginx
listen.mode = 0660

Gitインストール

sudo yum install git
  • ssh-keygen でsshキー発行
  • vi /home/ec2-user/.ssh/id_rsa.pub で公開鍵を確認し、Githubのユーザー設定からssh keyとして登録します

    • アカウント > Settings > SSH and GPG keys
  • その後 ssh -T git@github.com で疎通確認します

    • Hi (name)! You've successfully authenticated, but GitHub does not provide shell access. と出ればOKです

IPアドレスを固定にする

Elastic IPを利用します。

  • コンソール画面の左側 Elastic IP より、「Elastic IPアドレスの割り当て」で発行したあと、「関連付け」で作ったインスタンスに関連付けします。
  • ダッシュボードでインスタンスを右クリック→「接続」でURLを確認し、新しいURLでnginxの初期画面が表示されることをもう一度確認します。

※インスタンスが停止中に料金が発生するので注意してください。

nginx設定

sudo vi /etc/nginx/nginx.conf

root /var/www/laravel-deploy-sample/current/public; でlaravelのpublic/index.phpを起動するようにします

ひとまずhttpについて設定を変更します。

server { の箇所を下記のように置き換えます。ここでrootはプロジェクトのパスに書き換えてください

 server {
        listen       80;
        listen       [::]:80;
        server_name  _;
        root         /var/www/{project_name}/current/public;
        index  index.php index.html index.htm;

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

        location ~ \.php$ {
            # root           /var/www;
            root /var/www/{project_name}/current/public;
            fastcgi_pass   unix:/run/php-fpm/php-fpm.sock;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
            include        fastcgi_params;
        }
}

更新したら再起動します sudo service php-fpm restart && sudo service nginx restart

うまくいかなくて困ったらログをみます tail -f /var/log/nginx/error.log

swap有効化

t4g.microなどメモリ1G以下だとビルド中にエラーが出てしまうので、swapを有効化します

sudo su
dd if=/dev/zero of=/swapfile bs=1M count=1024
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile

(必要に応じて)package.jsonの yarn production でメモリ割り当てを指定するオプションを追記します

    "scripts": {
    ...
        "production": "NODE_OPTIONS=\"--max-old-space-size=1024\" cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
}

Laravelプロジェクトの準備(ローカル)

  • ローカルにてデプロイするLaravelプロジェクトに対して準備していきます。

(新しくプロジェクトを用意する場合のみ)

composer create-project --prefer-dist laravel/laravel laravel-deploy-sample`
npm install
composer install

artisan servelocalhost:8000 で初期ページが見れることを確認します。

Deployerの導入・設定

(2021/11) Deployerのバージョンが7系に移管中だったりするのでこちらも暫定になります。

Deployerのインストール & 設定

グローバルかプロジェクトにインストールするのかは任意です。 https://deployer.org/docs/7.x/installation

  • dep init でLaravelを選択すると、 deploy.php ができます。

deploy.php の変更箇所は一旦こんな感じです。

set('branch', 'develop');

add('shared_dirs', ['vendor', 'node_modules']); // 共有ディレクトリ

host('{IP address or domain}')
    ->user('ec2-user')
    ->identityFile('{.pemファイルの場所}')
    ->stage('staging')
    ->roles('app')
    ->set('deploy_path', '/var/www/{project_name}');

deploy

  • dep deploy または php vendor/bin/dep deploy
  • 設定ファイルはローカルの現在のブランチのものが使われます。
  • 基本的には設定した認証情報でsshに入って作業を代行しているだけなので、エラーが出たら手動で確認してみてください。

エラー

  • FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory

    • メモリが足りてないです。swapがちゃんと設定できることを確認します(スペックアップでもよいです)
  • 途中で落ちてlockされてしまったら、下記でunlockします

    • php vendor/bin/dep deploy:unlock

.envの設定

  • deployが通ったら.envの設定が必要です。
  • vi /var/www/{project}/current/.env で開いて、ローカルの.env.exampleをはっつけます
  • そのあと php artisan key:generate で.envのAPP_KEYを更新させます。
  • service nginx restart で再起動したら、EC2のURLでアプリが表示できるはずです。

はまったこと

index.phpが実行ではなくダウンロードされてしまう

nginx.confのlocationがおかしいかも。

ドメイン対応

必要に応じて実施。route53からドメイン発行、関連付けを行います。ここでは割愛します:bow:

下記を参考にしました(感謝)

SSL対応

nginx.confの設定

sudo vi /etc/nginx/nginx.conf

  • 取得したドメイン名を下記のserver_name に記述しておきます。

    server {
        server_name  stage.testdomain.com;

Let’s Encrypt と cert bot で証明書を発行する

下記手順で発行 & 自動更新設定をします。 https://qiita.com/ntm718/items/37d1d0a7de2d1edb4e7c

設定するとcert botが下記の設定を追記してくれるため自動でhttpsにリダイレクトされるようになっています。すごいですね

 server {
    if ($host = stage.address-reconfirmation.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


        listen       80;
        listen       [::]:80;
        server_name  stage.address-reconfirmation.com;
    return 404; # managed by Certbot


}}

これでhttpsで表示できるはずです!


Written by@macaron
ゲームが好きなWebエンジニアのBlogです。