EC2にLaravelプロジェクトをデプロイする
何気にEC2でLaravelアプリをちゃんとデプロイしたことがなかったのでやってみましたが、 デプロイして見れる状態になるまでかなり苦労しました。
一連の流れを書いていこうと思いますが、思い出しながらなので抜け漏れあるかもしれませんがご了承ください。
環境・利用ツール
- Laravel 8.x
- laravel-deployer
手順
EC2インスタンスの用意
- AMI: `Amazon Linux 2 AMI (HVM), SSD Volume Type - ami-0992fc94ca0f1415a (64 ビット x86)
- インスタンスはt4g.micro以上がおすすめです
- ボリューム: 16GBくらい。8だと何回かやってるうちに容量不足になってしまいました
- セキュリティグループ
サーバーのセットアップ
こちらを全体的に参考にさせていただきました。感謝 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の設定
最後に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
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.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 serve
で localhost: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がおかしいかも。
- nginxのtry_filesわかりにくすぎ問題
ドメイン対応
必要に応じて実施。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で表示できるはずです!