初心者向け！LaravelアプリをAWS EC2で公開する手順

## はじめに
初めまして！
この記事は[G's ACADEMY Advent Calendar 2024]('https://qiita.com/advent-calendar/2024/gsacademy#gs-academy-advent-calendar-2024-')16日目となります。

私がプログラミングを勉強し始めた当初一番苦しんだのはサーバーの公開でした。
レンタルサーバーではPythonの特定の機能が使えなかったり、httpsのために証明書を発行しないといけなかったり、時間を無駄にした経験があります。
初学者のうちはサーバー構築などを敬遠してしまうと思うのですが、サーバーを構築しないとプロダクトが公開できない場面もあると思います。

そんなとにかくサーバーを作って自分のプロダクトを公開したい！という方には是非この記事を読んでサクッとサーバー構築してもらえればと思います。

## 下準備
AWSにて作業を行うにあたって以下の準備をしておいてください。
・[AWSアカウントの作成]('https://signin.aws.amazon.com/signup?request_type=register')
・Laravelアプリ（今回の記事ではアプリの公開手順のみ紹介します）

※今回の手順は全てルートユーザーで行います。

## AWSコンソール上の操作

準備ができたらAWSコンソール上で操作を行なっていきます。
以下の手順に従って、操作を進めてください。

## VPCの作成
まずはVPCを作成します。
コンソールから「VPC」を検索し「VPCを作成」をクリックしてください。

設定は以下のような画面で大丈夫です。

![スクリーンショット 2024-10-22 23.37.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2959999/5a141a1c-69bf-3ac9-7b02-b54fe1cf0d4f.png)


### サブネットの作成
次にサブネットを作成します。
公開用のサブネットのため、publicサブネットと名前付けします。
アベイラビリティゾーンは「大阪・東京」どちらかを選択してください。

![スクリーンショット 2024-10-22 23.44.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2959999/700530c5-680b-c625-1455-518378aa4231.png)

### インターネットゲートウェイ作成・アタッチ

まずはインターネットゲートウェイを作成します。

![スクリーンショット 2024-12-16 19.47.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2959999/d7e02b66-a1e7-3204-cf0d-99856d6b94b4.png)

その後、「アクション」をクリックしてください。
以下の画面から、先ほど作成した「test-vpc」を選択して、VPCにアタッチします。

![スクリーンショット 2024-12-16 19.48.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2959999/f94d91e5-0f7b-6bdc-0732-f3ed9c8eb1f0.png)

### ルートテーブル作成
ルートテーブルを作成して、サブネットの関連付けを行います。

![スクリーンショット 2024-10-22 23.58.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2959999/c80f90c0-2813-3fb5-b9f0-3880db3383c7.png)

次に、ルートにインターネットゲートウェイの接続を追加してください。

![スクリーンショット 2024-10-22 23.59.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2959999/6ca842a4-a96a-aecd-67b1-8463dd889290.png)

### Route53の設定
「Route53」で検索し、「ホストゾーンの作成を」クリックしてください。

![スクリーンショット 2024-12-16 20.33.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2959999/69187f7f-f379-03e0-05e9-db3e4e2e6639.png)

その後、DNSレコードを Route53 に設定し、test-vpcのパブリックIPアドレスにリダイレクトするように設定すればOKです！

## EC2の作成
「EC2」を検索して、「インスタンスを起動」をクリックしてください。
以下の設定でEC2を作成します。

・名前...test-vpc
・イメージ...AmazonLinux2023
・インスタンスタイプ...t2 micro
・キーペア...aws-test（後述）

![スクリーンショット 2024-12-16 19.56.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2959999/bbe0a5f8-da20-6d6a-aada-271cb34607e2.png)

「新しいキーペアを作成」でssh接続のためのキーを作成しておいてください。後ほどこのキーを使ってコマンドラインからec2に接続します。

![スクリーンショット 2024-12-16 19.55.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2959999/d59c284b-8a8b-363d-54e1-ac2565427421.png)

### ファイアウォール設定
「EC2」→「セキュリティグループ」→「インバウンドのルールを編集」から以下のポートを解放しておいてください。
HTTP通信、HTTPS通信をすべてのIPアドレスからアクセスできる設定となっております。（特定のIPアドレスのみにアクセス許可をすることで自分の端末からしかアクセスできないようにすることも可能です。）

![スクリーンショット 2024-12-16 20.06.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2959999/da7243f5-079a-fefe-4b75-66fbc28c77a0.png)


### ssh接続

以下のコマンドラインで test-ec2に接続します
```
// chmod で権限を与える
chmod 600 ~/Downloads/aws-test.pem

// インスタンスのパブリックIPアドレスを取得し、ssh接続
ssh -i ~/Downloads/aws-test.pem ec2-user@(パブリックIPアドレス）

```

## EC2 環境構築
ではこれからEC2の環境構築を行います。
基本コピペしていけばOKです！

[AWSの記事]('https://qiita.com/me-654393/items/504acfbb766eddbf1046')を参考にしておりますので、こちらも読んでみてください。

### 初期設定
```
sudo dnf upgrade -y
sudo dnf install -y httpd wget php-fpm php-mysqli php-json php php-devel
sudo dnf install mariadb105-server

sudo usermod -a -G apache ec2-user
groups
sudo chown -R ec2-user:apache /var/www
sudo chmod 2775 /var/www && find /var/www -type d -exec sudo chmod 2775 {} \;
find /var/www -type f -exec sudo chmod 0664 {} \;
```

### Apache
```
sudo systemctl start httpd
sudo systemctl enable httpd
sudo systemctl status httpd
```

### DB
```
sudo dnf list installed httpd mariadb-server php-mysqlnd
sudo systemctl start mariadb
sudo mysql_secure_installation
sudo systemctl enable mariadb

sudo dnf install php-mbstring php-xml -y
sudo systemctl restart httpd
sudo systemctl restart php-fpm
cd /var/www/html
wget https://www.phpmyadmin.net/downloads/phpMyAdmin-latest-all-languages.tar.gz
mkdir phpMyAdmin && tar -xvzf phpMyAdmin-latest-all-languages.tar.gz -C phpMyAdmin --strip-components 1
rm phpMyAdmin-latest-all-languages.tar.gz

http://[--]/phpMyAdmin
```

### mysql設定
```
mysql -u root -p
```
```
CREATE USER 'test'@'localhost' IDENTIFIED BY 'test1234';
create database test;
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER, DROP, INDEX ON test.* TO 'test'@'localhost';
FLUSH PRIVILEGES;
```

### Git 設定
```
sudo dnf install git -y

// フォルダ権限、実行権限実行
sudo chown ec2-user:apache /var/www
sudo chmod 2775 /var/www
sudo usermod -a -G apache ec2-user

// 鍵の生成
ssh-keygen -t rsa -b 4096
cat /home/ec2-user/.ssh/id_rsa.pub

// git clone
cd /var/www/
// githubからcoloneコマンドを貼り付け
git clone git@github.com:プロダクト名
cd ファイル名
```

### Composer
Laravelの環境構築のため、composerをインストールします。
[公式サイト]('https://getcomposer.org/download/')の手順に準拠しています。
```
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php -r "if (hash_file('sha384', 'composer-setup.php') === 'dac665fdc30fdd8ec78b38b9800061b4150413ff2e3b6f88543c636f7cd84f6db9189d43a81e5503cda447da73c7e5b6') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
php composer-setup.php
php -r "unlink('composer-setup.php');"

//　パスを通す
sudo mv composer.phar /usr/local/bin/composer

// composer を動かすためのインストール
sudo yum install php-gd -y
sudo systemctl restart httpd
```

### Laravel
```
cd /var/www/プロダクト
cp .env.example .env
vim .env

composer install
php artisan key:generate

php artisan migrate:refresh --seed
sudo chmod -R 777 storage
```

### Nodejs
```
sudo yum install -y nodejs
cd /var/www/プロダクト
npm install
npm run build
```

### php-fpm、nginx調整
```
cd /etc/httpd/conf/
sudo cp httpd.conf httpd.conf_org
sudo vi httpd.conf
```

/etc/httpd/conf/httpd.conf に
以下のコードを追加で貼り付け
※ファイル名やドメイン名はご自身で設定をお願いします。

```
<VirtualHost *:80>
    ServerName ドメイン名（test.comなど）
    ServerAlias www.ドメイン名（test.comなど）

    # Laravelのルートディレクトリ
    DocumentRoot /var/www/プロダクト名/public
    <Directory /var/www/プロダクト名/public>
        AllowOverride All
        Options Indexes FollowSymLinks
        Require all granted
    </Directory>

    # phpMyAdminへのエイリアス設定
    Alias /phpMyAdmin /var/www/html/phpMyAdmin
    <Directory /var/www/html/phpMyAdmin>
        AllowOverride None
        Options FollowSymLinks
        Require all granted
    </Directory>

    ErrorLog /var/log/httpd/プロダクト名-error.log
    CustomLog /var/log/httpd/プロダクト名-access.log combined
RewriteEngine on
RewriteCond %{SERVER_NAME} =ドメイン名 [OR]
RewriteCond %{SERVER_NAME} =www.ドメイン名
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>
```


### SSL/TLS
```
sudo dnf install openssl mod_ssl -y
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/pki/tls/private/apache-selfsigned.key -out /etc/pki/tls/certs/apache-selfsigned.crt
// 7個ほど質問があるので答える


sudo systemctl restart httpd

sudo yum install certbot python3-certbot-apache -y
sudo certbot --apache
```

これでhttps://ドメイン名 でLaravelアプリを公開できました！

## 最後に
レンタルサーバーでは公開できないプロダクトなどを、この記事をきっかけに公開して頂けたら嬉しいです。

もし参考になったのであれば、いいねを頂けると励みになります。

最後までありがとうございました！