windowsのDcokerで構築したlaravelをAWSのEC2にデプロイします。
LEMP(Linux、Nginx、Mysql、Php)環境で構築を行います。
仕様ツール
・AWS Systems Manager
・AWS CloudFormation
・AWS EC2
・AWS RDS
手順
1.AWS EC2 インスタンス作成とssh接続
参考サイト:
https://zenn.dev/mai_mizz/articles/4a6b9e16dca99c
https://qiita.com/tsukamoto/items/1e0f3c8ecf4cba5cf485
https://www.softbank.jp/biz/blog/cloud-technology/articles/202309/cloudformation/
CloudFormationを利用したインスタンスの作成を行います。
CloudFormationとは、プロビジョニング(必要なものを準備すること、ITインフラの調達や設定など)およびサーバー設定のエリアにおける自動化および構成管理のためのサービスです。
分かりやすく言うと、管理画面から行うサーバーの設定を、コード化することができます。
そのコードがあれば、同じ環境を構築するのもとても簡単にできます。
AWS Systems Managerを始める

「Get Started with Systems Manager」ボタンを押します。
設定は以上です。
サーバー設定のテンプレートファイルの作成
「larablog」とEc2ImageIdとEc2KeyNameのdefaultを変更してください。
AWSTemplateFormatVersion: "2010-09-09"
Description: "template on EC2"
Parameters:
ProjectName:
Type: String
Default: larablog
VpcCidrBlock:
Type: String
Default: "10.0.0.0/16"
PublicSubnetCidrBlock1:
Type: String
Default: "10.0.1.0/24"
PublicSubnetCidrBlock2:
Type: String
Default: "10.0.2.0/24"
PrivateSubnetCidrBlock1:
Type: String
Default: "10.0.3.0/24"
PrivateSubnetCidrBlock2:
Type: String
Default: "10.0.4.0/24"
Ec2ImageId:
Type: String
Default: ami-0d7bfdca2fa8d3cc4
Resources:
# VPC
MyVPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: !Ref VpcCidrBlock
EnableDnsSupport: true
EnableDnsHostnames: true
Tags:
- Key: Name
Value: !Sub "${ProjectName}-VPC"
# サブネット
MyPublicSubnet1:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref MyVPC
CidrBlock: !Ref PublicSubnetCidrBlock1
AvailabilityZone: "ap-northeast-3a"
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: !Sub "${ProjectName}-PublicSubnet1"
MyPublicSubnet2:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref MyVPC
CidrBlock: !Ref PublicSubnetCidrBlock2
AvailabilityZone: "ap-northeast-3c"
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: !Sub "${ProjectName}-PublicSubnet2"
MyPrivateSubnet1:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref MyVPC
CidrBlock: !Ref PrivateSubnetCidrBlock1
AvailabilityZone: "ap-northeast-3a"
Tags:
- Key: Name
Value: !Sub "${ProjectName}-PrivateSubnet1"
MyPrivateSubnet2:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref MyVPC
CidrBlock: !Ref PrivateSubnetCidrBlock2
AvailabilityZone: "ap-northeast-3c"
Tags:
- Key: Name
Value: !Sub "${ProjectName}-PrivateSubnet2"
# IGW設定
MyInternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: Name
Value: !Sub "${ProjectName}-IGW"
MyVPCGatewayAttachment:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref MyVPC
InternetGatewayId: !Ref MyInternetGateway
# ネットワーク設定/Public
MyPublicRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref MyVPC
Tags:
- Key: Name
Value: !Sub "${ProjectName}-PublicRouteTable"
MyPublicRoute:
Type: AWS::EC2::Route
DependsOn: MyInternetGateway
Properties:
RouteTableId: !Ref MyPublicRouteTable
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref MyInternetGateway
PublicSubnetRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref MyPublicSubnet1
RouteTableId: !Ref MyPublicRouteTable
MySecurityGroupEC2:
Type: AWS::EC2::SecurityGroup
DependsOn: MyVPC
Properties:
GroupName: MySecurityGroup2
GroupDescription: For EC2
VpcId: !Ref MyVPC
Tags:
- Key: Name
Value: !Sub "${ProjectName}-SecurityGroup-ec2"
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
# EC2定義
NewKeyPair:
Type: AWS::EC2::KeyPair
Properties:
KeyName: !Sub "${ProjectName}-key"
MyEC2Instance:
Type: AWS::EC2::Instance
Properties:
ImageId: !Ref Ec2ImageId
KeyName: !Ref NewKeyPair
InstanceType: t2.micro
NetworkInterfaces:
- AssociatePublicIpAddress: true
DeviceIndex: 0
SubnetId: !Ref MyPublicSubnet1
GroupSet:
- !Ref MySecurityGroupEC2
Tags:
- Key: Name
Value: !Sub "${ProjectName}-EC2"CloudFormationで構築
上記で作成した「ec2.yml」ファイルをアップロードします。

ファイルをアップロードして、次へのボタンをクリック

スタック名を記入して、あとは特に変更せずに、進めていきます。

作成を実行して、上の様な画面になれば成功です。
EC2のインスタンス一覧を見ると、問題なく実行されています。

ペアキーの確認
最近になって、CloudFormationでsshに必要なキーペアの追加もできるようになりました。
本来であれば、インスタンス作成時一回のみキーペアをダウロードすることができます。
CloudFormationで構築したときには、キーペアがダウンロードされることはありません。
パラメータストアから取得可能です。


赤い枠をクリックして、秘密鍵を取得します。
それを「~.pem」として、sshディレクトリに保存します。
SSHで接続
sshのキーを所定のディレクトリに移動して、権限の変更を行い、SSH接続を行います。
# sshのディレクトリにキーの移動
# sshの保存先に移動
cd C:\Users\user\.ssh
# AWSで権限の変更を下記コマンド実行を促されます。
chmod 400 sample-key.pem
# しかしwindows環境ではchmodは使用できないので、
$path = ".\sample-key.pem"
# 対象ファイルの既存の権限をリセットする
icacls.exe $path /reset
# 操作ユーザに読み取り権限(chmod 400)を付与
icacls.exe $path /GRANT:R "$($env:USERNAME):(R)"
# AWSに接続
ssh -i "sample-key.pem" ec2-user@ec0000-000-000-000.ap-northeast-1.compute.amazonaws.com
# 下記の画面になれば接続成功です。
, #_
~\_ ####_ Amazon Linux 2023
~~ \_#####\
~~ \###|
~~ \#/ ___ https://aws.amazon.com/linux/amazon-linux-2023
~~ V~' '->
~~~ /
~~._. _/
_/ _/
_/m/'
[ec2-user@ip-00-00-000~]$上記の情はインスタンスの接続から確認できます。

2.EC2にdockerの構築
Docker Engineをインストールとdockerコマンドの実行
# yumパッケージのアップデート
sudo yum update -y
# Docker Engineをインストール
sudo dnf install -y docker
# システム起動時のDocker自動起動を有効化+起動
sudo systemctl enable --now docker
# Dockerサービスの状態を確認
systemctl status docker
# 下記が表示されれ場成功です。
● docker.service - Docker Application Container Engine
Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; preset: disabled)
Active: active (running) since Wed 2023-11-15 07:59:52 UTC; 6s ago
TriggeredBy: ● docker.socket
# 確認の停止
Ctrl + Z
# ec2-userでroot権限なしでdockerコマンドを操作できるようにする
sudo usermod -aG docker ec2-user
sudo su ec2-user
# バージョンの確認
docker -v
> Docker version 24.0.5, build ced0996Docker Composeをインストール
DOCKER_CONFIG=${DOCKER_CONFIG:-/usr/local/lib/docker}
sudo mkdir -p $DOCKER_CONFIG/cli-plugins
# ここはDocker公式ドキュメント記載の最新バージョンに置き換える
# https://docs.docker.com/compose/install/linux/#install-using-the-repository
sudo curl -SL https://github.com/docker/compose/releases/download/v2.20.3/docker-compose-linux-x86_64 -o $DOCKER_CONFIG/cli-plugins/docker-compose
#docker-composeの実行権限を適用
sudo chmod +x /usr/local/lib/docker/cli-plugins/docker-compose
# Docker Composeのバージョンの確認
docker compose version
> Docker Compose version v2.20.3Gitとプロジェクトのインストール
# Gitのインストール
sudo dnf install -y git
# プロジェクトのクローン
git clone git@github.com:XXXXX/XXXXXX.git
# プロジェクトに移動
cd laravel_project
# Dockerの起動
docker compose up -d
# 起動状況の確認
docker ps3.Laravelの設定
# phpイメージに接続
# phpは環境によって変更してください
docker exec -it php bash
# 接続が成功すると下記になり、lsでファイルの確認
root@000000000:/src# ls
aws docker docker-compose.yml laravel
# laravelに移動
cd laravel
# composerとnpmのインストールと実行
composer install
npm install
npm run build
# .envファイルの作成して、データベースの設定変更
cp .env.example .env
sudo dnf install -y vim-gnome
# シンボリックリンクの設置
chmod -R 777 storage
php artisan storage:link
# マイグレーションとキーの生成
php artisan migrate:fresh --seed
php artisan key:generate上記を実行して、一度以下の赤枠からアクセスしてみます。

このときhttpsにアクセスしますが、httpに変更してください。
以下の画面が表示されれば成功です。

インストールが進まないとき
サーバーのレベルが低いと「npm install」実行時に、動かなくなる時があります。
そんな時は一度、ターミナルやpowershellを終了してください。
「npm install」をもう一度やり直します。
また、sshログインすらできなくなってしまった場合は、以下の紫枠でインスタンスの再起動をします。

再起動を行った場合は、sshの接続情報が変わりますので、接続上の確認をします。

4.RDS(データベース)の作成と接続
既にDockerでデータベースの構築が完了していますので、この設定は必要な場合に行って下さい。
参考サイト:
https://qiita.com/yyy752/items/601646d3683869521f9b
RDSの作成は割愛いたします。
RDSを作り終えた状況からの解説になります。
ターミナルでデータベースの確認
# キーの場所に移動
cd C:\Users\user\.ssh
# AWSに接続
ssh -i "sample-key.pem" ec2-user@ec0000-000-000-000.ap-northeast-1.compute.amazonaws.com
# パッケージのアップデート
sudo yum update -y
# MySQLをインストール
sudo yum -y install mysql
# 上記コマンドで下記コマンドが表示された場合
No match for argument: mysql
Error: Unable to find a match: mysql
# 下記コマンドでMySQLをインストール
sudo dnf -y localinstall https://dev.mysql.com/get/mysql80-community-release-el9-1.noarch.rpm
sudo dnf -y install mysql mysql-community-client
sudo yum install mysql -y
# MySQLのバージョン確認
mysql --version
# MySQLに接続
mysql -h database.000000000.ap-northeast-3.rds.amazonaws.com -P 3306 -u admin -p
# パスワードの入力(RDSで設定したマスターパスワード)
Enter password:
# 下記が表示されれば、接続成功です。
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 177
Server version: 8.0.33 Source distribution
# データベースの確認
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| laravel_blog |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.02 sec)EC2とRDSの接続が確認できれば、Laravelの.envファイルのデータベースの設定を変更します。
DB_CONNECTION=mysql
DB_HOST=database-1.000000000.0000000.rds.amazonaws.com
DB_PORT=3306
DB_DATABASE=larablog-test
DB_USERNAME=admin
DB_PASSWORD=testtest