🦔

LaravelをAWS EC2とRDSを組み合わせてデプロイ(nginx)

2023/08/08に公開

AWS EC2 RDS Laravel デプロイ

laravelで開発したものをAWS EC2へデプロイする方法を備忘録として残します。
細かい説明とかは省いてなるべく実行手順のみ記載しています!
今回は固定IPの設定(Elastic IP)、独自ドメインの設定(Route53)、SSL認証取得(Certificate Manager)は行っておりません。
必要な方はそれぞれそんなに難しくなく設定できるので調べてみてください。
声があれば時間があれば記事に残そうと思っています。

使用技術

PHP8.1
Laravel10
MySQL

デプロイ環境

デプロイ先:AWS EC2
DB: RDS
サーバー:nginx

1 EC2インスタンス作成

1.AWSからログインしてEC2画面にアクセス。

2.画面右上のリージョンを「東京or大阪」に。

3.「インスタンスを起動」をクリック。

4.マシンイメージで「Linux」を指定 (無料枠のため指定しています)

5.キーペアの作成(新しいキーペアの作成)
今回は.pemを指定
作成したキーペアは紛失すると再発行ができなくてログインできなくなるので、扱いには注意が必要です。
「○○.pem」の形式でファイルとしてダウンロードされます。
この作成された.pemファイルは後ほど使用するので必ず大切に管理してください。

6.インスタンスタイプで「t2.micro」を選択 (無料枠のため指定しています)

7.ネットワーク設定で「HTTP(80)」と「HTTPS(443)」を追加

8.「インスタンスを起動」をクリック

9.SSH接続に使用する情報を確認する
表示された情報を使用し、SSH接続をする

10.確認した情報をもとにリモート接続ができるか確認してみる

#ターミナルをスタート地点へ
$ cd 

#.sshディレクトリを作成 すでに存在するならしなくて良い
$ mkdir ~/.ssh   

#mvコマンドで先ほどダウンロードした「キー.pem」を.sshディレクトリに移動
$ mv Downloads/sample-key.pem .ssh/ 

#.sshにディレクトリ移動
$ cd .ssh/ 

#pemファイルが存在するか確認。「sample-key.pem」が存在すればOK
.ssh $ ls 

#キーファイル(○○○.pem)のパーミッションを変更
#このコマンドを実行して、キーが公開されていないことを確認している
$ chmod 400 sample-key.pem 

##ログイン(AWS 接続画面記載のコードをコピペ)
$ ssh -i "sample-key.pem" ec2-user@ec2-??-??-???-???.ap-northeast-1.compute.amazonaws.com

Last login: Thu Dec  2 06:14:35 2021 from p3014131-ipoe.ipoe.ocn.ne.jp

       __|  __|_  )
       _|  (     /   Amazon Linux 2 AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-2/

初めてリモート接続を行う場合は下記の文が出ますが「yes」を入力してください。

$ ssh -i "sample_key.pem" ec2-user@ec?-??-???-??-?.ap-northeast-3.compute.amazonaws.com
The authenticity of host 'ec2-??-???-??-?.ap-northeast-3.compute.amazonaws.com (??.???.??.?)' can't be established.
????????? key fingerprint is 
?????:???????????????????????????????.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])?

これは、SSH(Secure Shell)を使用してリモートサーバーに接続しようとした際に表示されるメッセージです。SSHは、セキュアなリモートアクセスとデータ通信を提供するためのプロトコルです。
このメッセージは、初めてその特定のリモートサーバーに接続しようとしたときに表示されるものです。メッセージの内容は以下の通りです。
ホスト名とIPアドレスが表示されます。
サーバーの公開鍵のフィンガープリントが表示されます(ED25519アルゴリズムを使用して計算されたSHA256ハッシュ値)。
その公開鍵に関連する名前がわからないことが記載されています。
"yes"を入力すると、サーバーへの接続を続行します。これにより、このサーバーの公開鍵がクライアント側で記憶され、今後の接続時に確認のプロンプトは表示されなくなります。
"no"を入力すると、接続を中止します。
"fingerprint"を入力すると、指紋を確認するための再表示が行われます。これは、指紋が正しいかどうかを確認する際に役立ちます。
このメッセージは、セキュリティの観点から重要です。指紋を確認し、サーバーへの接続が正当であることを確認することで、中間者攻撃などのリスクを軽減できます。接続先のサーバーが正当であることを確認した場合にのみ、"yes"を入力して接続を続行してください。
下記のように表示されれば、問題なくログイン完了です

Warning: Permanently added 'ec2-??-???-??-?.ap-northeast-3.compute.amazonaws.com' (ED25519) to the list of known hosts.

       __|  __|_  )
       _|  (     /   Amazon Linux 2 AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-2/

Warningとでていますが、.sshディレクトリに存在する"known hosts" リストにこのサーバーが正式に追加されたことを示しています。

nginxをセットアップ

今回はnginxをセットアップします。

#EC2インスタンスは、nginxのyum intstallが有効になっていない為、有効化。
[ec2-user@ip-???-??-??-?? ~]$ sudo amazon-linux-extras enable nginx1

[ec2-user@ip-???-??-??-?? ~]$ sudo yum -y install nginx #インストール

[ec2-user@ip-???-??-??-?? ~]$ sudo nginx -v #バージョン確認

[ec2-user@ip-???-??-??-?? ~]$ sudo systemctl enable nginx #nginx自動起動化

[ec2-user@ip-???-??-??-?? ~]$ sudo systemctl start nginx.service #起動

[ec2-user@ip-???-??-??-?? ~]$ sudo systemctl status nginx.service #起動確認

AWSインスタンス一覧画面から作成したインスタンスにチェック
画面下のインスタンス情報内のパブリックIPv4アドレスからアクセス
サーバーの初期画面が表示されればインスタンスの作成とサーバーのセットアップが完了です!
現在はhttpでのアクセスしかできませんので注意してください。
httpsでのアクセスもできるようにしたい場合はSSL認証をしなければなりません。

RDSを作成

1.RDS画面にアクセス。

2.データベースページに移動し、データベースの作成をクリック。

3.エンジンは各々使用されているものを選択してください。今回はMySQLを使用しています。
注意することは使用しているバージョンに必ず合わせること!!
MySQLのバージョンを確認するコマンド

#開発したところまで移動し、下記コマンドを入力
$ mysql --version


4.今回はテンプレートを無料利用枠に指定

5.接続までデフォルトのままスクロール。写真の箇所を入力。

6.追加設定でデータベース名を入力する。

7.一番下の「データベースの作成」ボタンをクリック。

8.数分後データベースが作成完了する。そして、作成したDB(database-1)をクリック。

9.VPCセキュリティグループをクリック。

10.「セキュリティグループ」をクリック→「インバウンドのルールを編集」をクリック。

11.EC2インスタンス作成時に設定したセキュリティグループを選択。
赤字でエラーメッセージが出た場合は、削除を押し、ルールを追加し、入力しなおすことで正常に指定できました。

接続

1.ターミナルからインスタンスに接続。

$ ssh -i "sample-key.pem" ec2-user@ec2-??-??-???-???.ap-northeast-1.compute.amazonaws.com

2.パッケージのアップデート

$ sudo yum update -y
読み込んだプラグイン:extras_suggestions, langpacks, priorities, update-motd
amzn2-core                                 | 3.7 kB  00:00:00
No packages marked for update

3.MySQL、Git、Apache、cURLをインストール

$ sudo yum -y install mysql git httpd curl
・・・ #省力
完了しました!

4.MySQLに接続
database-1.cveawoxgeidk.ap-northeast-3.rds.amazonaws.comの部分は自分のエンドポイントを指定してください。
エンドポイントの確認は画像で選択している箇所です。

$ mysql -h database-1.cveawoxgeidk.ap-northeast-3.rds.amazonaws.com -P 3306 -u admin -p
#パスワードはDBを作成するときに自分で入力したマスターパスワード

Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 24
Server version: 8.0.23 Source distribution

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MySQL [(none)]> show databases; #DB確認
+--------------------+
| Database           |
+--------------------+
| information_schema |
| name                         |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.00 sec)

作成したDB(name)が存在してれば問題なし!

GitHub接続

1.EC2インスタンスにSSH接続している状態で、Gitのユーザー名とEmailアドレスを設定。
※設定するユーザー名とEmailアドレスは自身のGithubアカウントに登録しているデータを入力してください。

[ec2-user@ip-???-??-??-?? ~]$ git config --global user.name "ユーザー名"
[ec2-user@ip-???-??-??-?? ~]$ git config --global user.email メールアドレス

環境作成

1.amazon-linux-extrasコマンドを利用してPHPをインストール。

[ec2-user@ip-???-??-??-?? ~]$ amazon-linux-extras list #利用できるパッケージが一覧で見ることが出来る

[ec2-user@ip-???-??-??-?? ~]$ sudo amazon-linux-extras install -y php8.2 #今回開発したものがPHP8.2だから

2.Composerをインストールし、パスを通す。

[ec2-user@ip-???-??-??-?? ~]$ curl -sS https://getcomposer.org/installer | php
All settings correct for using Composer
Downloading...

Composer (version 2.5.8) successfully installed to: /home/ec2-user/composer.phar
Use it: php composer.phar

[ec2-user@ip-???-??-??-?? ~]$ sudo mv composer.phar /usr/local/bin/composer

3./var/wwwディレクトリの所有者とグループを変更。

[ec2-user@ip-???-??-??-?? ~]$ cd /var/www

[ec2-user@ip-???-??-??-?? www]$ sudo chown ec2-user:ec2-user /var/www

4.デプロイしたいLaravelのプロジェクトをclone。

[ec2-user@ip-???-??-??-?? www]$ git clone https://github.com/???????.git

5.Composerのパッケージをインストールするために必要なライブラリをインストール。

[ec2-user@ip-???-??-??-?? www]$ sudo yum install -y php-xml
・・・ #省力
完了しました!

6.パッケージのインストール。

[ec2-user@ip-???-??-??-?? www]$ cd アプリディレクトリ
[ec2-user@ip-???-??-??-?? (アプリディレクトリ)]$ composer update
[ec2-user@ip-???-??-??-?? (アプリディレクトリ)]$ composer install

7.他に必要なパッケージをインストール。
Webサーバーにnginxを採用した場合、PHPを実行するために設定が必要です。
拡張機能を下記コマンドで確認する。(今回はphp8.2を使用している)

[ec2-user@ip-???-??-??-??? (アプリディレクトリ)]$ cd ../

[ec2-user@ip-???-??-??-??? www]$ sudo yum list php* | grep amzn2extra-php8.2
php-cli.x86_64                   8.2.3-1.amzn2                @amzn2extra-php8.2
php-common.x86_64                8.2.3-1.amzn2                @amzn2extra-php8.2
php-fpm.x86_64                   8.2.3-1.amzn2                @amzn2extra-php8.2
php-mysqlnd.x86_64               8.2.3-1.amzn2                @amzn2extra-php8.2
php-pdo.x86_64                   8.2.3-1.amzn2                @amzn2extra-php8.2
php-xml.x86_64                   8.2.3-1.amzn2                @amzn2extra-php8.2
php.x86_64                       8.2.3-1.amzn2                amzn2extra-php8.2
php-bcmath.x86_64                8.2.3-1.amzn2                amzn2extra-php8.2
php-dba.x86_64                   8.2.3-1.amzn2                amzn2extra-php8.2
php-dbg.x86_64                   8.2.3-1.amzn2                amzn2extra-php8.2
php-devel.x86_64                 8.2.3-1.amzn2                amzn2extra-php8.2
php-embedded.x86_64              8.2.3-1.amzn2                amzn2extra-php8.2
php-enchant.x86_64               8.2.3-1.amzn2                amzn2extra-php8.2
php-gd.x86_64                    8.2.3-1.amzn2                amzn2extra-php8.2
php-gmp.x86_64                   8.2.3-1.amzn2                amzn2extra-php8.2
php-intl.x86_64                  8.2.3-1.amzn2                amzn2extra-php8.2
php-ldap.x86_64                  8.2.3-1.amzn2                amzn2extra-php8.2
php-mbstring.x86_64              8.2.3-1.amzn2                amzn2extra-php8.2
php-odbc.x86_64                  8.2.3-1.amzn2                amzn2extra-php8.2
php-opcache.x86_64               8.2.3-1.amzn2                amzn2extra-php8.2
php-pgsql.x86_64                 8.2.3-1.amzn2                amzn2extra-php8.2
php-process.x86_64               8.2.3-1.amzn2                amzn2extra-php8.2
php-pspell.x86_64                8.2.3-1.amzn2                amzn2extra-php8.2
php-snmp.x86_64                  8.2.3-1.amzn2                amzn2extra-php8.2
php-soap.x86_64                  8.2.3-1.amzn2                amzn2extra-php8.2
php-sodium.x86_64                8.2.3-1.amzn2                amzn2extra-php8.2

今回は以下のパッケージをインストールする

  • php-devel 拡張機能のソースをコンパイルするために必要。
  • php-opcache 処理の高速化のため。
  • php-mbstring マルチバイト文字列関連の関数を使うために必要。
  • php-xml xmlを利用するために必要。
[ec2-user@ip-172-31-45-44 www]$ sudo yum install php php-devel php-opcache php-mbstring php-xml
・・・ #省略
完了しました!

8.php-fpmの自動起動の設定。

[ec2-user@ip-???-??-??-?? www]$ sudo systemctl start php-fpm.service

[ec2-user@ip-???-??-??-?? www]$ sudo systemctl enable php-fpm.service
Created symlink from /etc/systemd/system/multi-user.target.wants/php-fpm.service to /usr/lib/systemd/system/php-fpm.service.

[ec2-user@ip-???-??-??-?? www]$ systemctl status php-fpm.service
● php-fpm.service - The PHP FastCGI Process Manager
   Loaded: loaded (/usr/lib/systemd/system/php-fpm.service; enabled; vendor preset: disabled)
   Active: active (running) since 月 2023-08-07 09:31:08 UTC; 42s ago
 Main PID: 1045 (php-fpm)
   Status: "Processes active: 0, idle: 5, Requests: 0, slow: 0, Traffic: 0req/sec"
   CGroup: /system.slice/php-fpm.service
           ├─1045 php-fpm: master process (/etc/php-fpm.conf)
           ├─1046 php-fpm: pool www
           ├─1047 php-fpm: pool www
           ├─1048 php-fpm: pool www
           ├─1049 php-fpm: pool www
           └─1050 php-fpm: pool www

 8月 07 09:31:08 ip-172-31-46-197.ap-northeast-3.compute.internal systemd[1]: Starting The PHP FastCGI Process Manager...
 8月 07 09:31:08 ip-172-31-46-197.ap-northeast-3.compute.internal systemd[1]: Started The PHP FastCGI Process Manager.

9.php-fpmとnginxの接続設定
参考記事:https://knmts.com/become-engineer-30/

php-fpmから設定します。
viモードはrootユーザーでないとファイルに書き込みができないので、書き込みをするときはec2ユーザーからrootユーザーにスイッチしてください。

[ec2-user@ip-???-??-??-??? www]$ sudo su - #rootにスイッチ

[root@ip-???-??-??-??? ~]# cd /etc/php-fpm.d/

[root@ip-???-??-??-??? php-fpm.d]# sudo cp www.conf www.conf_bk_yyyyMMdd #念の為バックアップ

[root@ip-???-??-??-??? php-fpm.d]# vim www.conf

vimで開いたら、「i」で挿入モードにして以下の箇所を変更。
変更したら「etc」で通常モードにして「:wq」で保存して終了。

### 24行目あたり ###
# 変更前
user = apache
# 変更後
user = nginx

### 26行目あたり ###
# 変更前
group = apache
# 変更後
group = nginx

### 48行目あたり ###
# 変更前
;listen.owner = nobody
# 変更後
listen.owner = nginx

### 49行目あたり ###
# 変更前
;listen.group = nobody
# 変更後
listen.group = nginx

### 50行目あたり ###
# 変更前
;listen.mode = 0660
# 変更後
listen.mode = 0660

次にnginxの設定をします。

[root@ip-172-31-45-44 ~]$ ls -l /etc | grep nginx #場所の確認
drwxr-xr-x  4 root root     4096 Aug  7 07:34 nginx

表示された実行結果の各意味について
参考記事:https://eng-entrance.com/linux_command_ls#-l

[root@ip-???-??-??-?? ~]# vim /etc/nginx/nginx.conf

vimで開いたら、「i」で挿入モードにして以下の箇所を変更。
変更したら「etc」で通常モードにして「:wq」で保存して終了。
nginx.confの編集内容は下記のように設定しました。

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 4096;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    include /etc/nginx/conf.d/*.conf;

    server {
        listen       80;
        listen       [::]:80;
        server_name  _;
        root         /var/www/Laravelプロジェクト名/public;

        add_header X-Frame-Options "SAMEORIGIN"; 
        add_header X-Content-Type-Options "nosniff";

        index index.php;

        charset utf-8;

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

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

        location ~ /\.(?!well-known).* {
            deny all;
        }

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

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

        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    }
}

nginxが起動するか確認

[root@ip-???-??-??-?? ~]$ sudo systemctl start nginx.service #nginx起動

[root@ip-???-??-??-?? ~]$ sudo systemctl status nginx.service #起動状態確認

10.クローンしたLaravelのプロジェクトディレクトリ内に移動して.envファイルの作成とAPP_KEYの生成を行う。

[root@ip-???-??-??-?? ~]# cd var/www/Laravelプロジェクト

[root@ip-???-??-??-?? Laravelプロジェクト]# cp .env.example .env #.env.exampleを.envという名前でコピー

[root@ip-???-??-??-?? Laravelプロジェクト]# php artisan key:generate #キーの生成
   INFO  Application key set successfully.

.envファイルの中を見てキーが設定されているか確認。

[root@ip-???-??-??-?? Laravelプロジェクト]# cat .env
APP_NAME=Laravel
APP_ENV=local
APP_KEY=??????????????????????????= #ここで問題なく設定されてますね!
APP_DEBUG=true
APP_URL=http://localhost
...省略

11.DBの接続設定
.envファイルを設定して、RDSとアプリを繋げます。

[root@ip-???-??-??-?? Laravelプロジェクト]# vim .env
#各RDSの設定内容を入力
DB_CONNECTION=mysql
DB_HOST=database-1.??????????.ap-northeast-1.rds.amazonaws.com
DB_PORT=3306
DB_DATABASE=DB名 
DB_USERNAME=admin 
DB_PASSWORD=????? #マスターパスワード

12.migrateしてDBを作成する。
seederを使用している方は忘れずに!

[root@ip-???-??-??-?? Laravelプロジェクト]# php artisan migrate:fresh

本当にテーブルが作成されているか確認する場合はMySQLにアクセスしたりDBeaverなどを使うなりして確認してください。

13.アプリ起動確認
nginxを再起動後パブリックIPv4DNSからアクセスし、アプリの画面が表示されるかブラウザで確認!!
私はファイルの権限周りで少し変更して表示ができました!

終わり

現在はhttpでしかサイトを見れません。
固定IPの設定(Elastic IP)、独自ドメインの設定(Route53)、SSL認証取得(Certificate Manager)までの手順も時間があるときに書きます。
Sailを開発で使用しているので、次回はSailで動かすまでできるようにしようと思っています。
どこかおかしいところやこうした方が良い!という方は遠慮なくサンドバックにしてください!

Discussion