まかろぐ

PCゲームのこととかWeb関連のこと

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

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について設定を変更します。

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

 server {
        listen       80;
        listen       [::]:80;
        server_name  _;
        root         /var/www/laravel-deploy-sample/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/laravel-deploy-sample/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.jsonyarn 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/5/3追記)

Laravel Deployerを使っていたのですが、本家Deployerに統合されるとのことで、Deployerを使った手順です。

細かい設定は下記で丁寧に解説されています。 https://lorisleiva.com/deploy-your-laravel-app-from-scratch/install-and-configure-deployer

Deployerのインストール

version7系をインストールします。プロジェクト内でもよいです。

https://deployer.org/docs/installation.html

Host 設定

ローカルからEC2にSSH接続できるように、Hostを定義します。

*のところは適宜書き換えてください。

vi ~/.ssh/config

Host ec2-test
  User ec2-user
  Port 22
  HostName ec2-**-***-***-***.ap-northeast-1.compute.amazonaws.com
  IdentityFile ~/.ssh/***.pem
  TCPKeepAlive yes
  IdentitiesOnly yes

この場合 ssh ec2-test で接続できるようになります。

dep init でyaml, laravelを選択し、定義ファイルを作成します。

deploy.yaml の編集

例:

import: 
    - recipe/laravel.php
    - contrib/php-fpm.php
    - contrib/yarn.php

config:
  application: '{project_name}' # 任意
  repository: 'git@github.com:****/****.git'
  remote_user: ec2-user
  deploy_path: '/var/www/{{application}}'
  php_fpm_service: 'php-fpm'

hosts:
  staging: # デプロイ先環境の名前(任意)
    hostname: '***' # ssh設定で定義した名前を指定します
    
tasks:
  yarn:run:prod:
    script:
      - 'cd {{release_path}} && yarn run prod'

after:
  artisan:config:cache:
#    - artisan:migrate
#  artisan:migrate:
    - yarn:install
  yarn:install:
    - yarn:run:prod
  deploy:publish:
    - php-fpm:reload
  deploy:failed: deploy:unlock

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対応

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

下記手順で発行 & 自動更新設定をします。(ありがとうございます。) qiita.com

nginx.confの設定

sudo vi /etc/nginx/nginx.conf

{project_name}, {domain_name} をそれぞれ置き換えてください

server {
    listen 80;
    server_name localhost;
    return 301 https://$host$request_uri;
}

 server {
    listen 443 default ssl;
    server_name  localhost;
    root /var/www/{project_name}/current/public;
    ssl_certificate /etc/letsencrypt/live/{domain_name}/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/{domain_name}/privkey.pem; # managed by Certbot
    ssl_session_cache shared:SSL:1m;
    ssl_session_timeout  10m;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;
    index index.php;
    charset utf-8;
#
#        Load configuration files for the default server block.
#        include /etc/nginx/default.d/*.conf;
#
    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; }
    error_page 404 /index.php;
    location ~ \.php$ {
      fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
      fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
      include fastcgi_params;
    }
#    location ~ /\.(?!well-known).* {
#      deny all;
#    }
}

sudo service nginx restart

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