AWS初心者がEC2+RDSにPHPアプリをデプロイしてみた
はじめに
AWSの学習の一環で、自作のアプリをAWSでデプロイしてみました。
PHPで作ったタスク管理アプリをEC2+RDSにデプロイするまでの流れをまとめています。
AWSを自分で触るのは今回が初めてで、Claudeと壁打ちをしながらVPCの作成からアプリの公開まで一通り経験しました。同じようにAWS初心者の方の参考になれば嬉しいです。
対象読者
- AWSを初めて触る方
- ローカルで動くPHPアプリを本番環境に公開したい方
- EC2+RDSの構成を試してみたい方
構成するシステム
インターネット
↓
EC2(Apache + PHP 8.4) ← パブリックサブネット
↓
RDS(MySQL 8.4) ← プライベートサブネット
事前準備
AWSアカウントの作成
以下から新規でAWSアカウントを作成できます。
今回はとにかく無料プラン内でデプロイまで行いたかったので、AWS Free Tierを利用しました。
AWSアカウントの初期設定
アカウントを作成したら、作業を始める前に以下の4つを設定しておくことをおすすめします。後から後悔しないための安全網です。
① 請求アラートの設定
Billing → 予算 → 月$5を超えたらメールで通知するように設定します。無料枠を超えると静かに課金が始まるので必須です。
② ルートアカウントにMFAを設定
IAM → セキュリティ認証情報 → MFAデバイスの割り当て → Authenticatorアプリを選択してスマホで設定します。ルートアカウントが乗っ取られると全リソースを削除・不正利用されるリスクがあるので最初にやっておきましょう。
スマホアプリはGoogle AuthenticatorかMicrosoft Authenticatorが使えます。どちらも無料です。
③ IAMユーザーの作成
ルートアカウントは緊急時専用にして、普段の作業は権限を絞ったIAMユーザーで行います。ルートアカウントは権限が強すぎるため、作業ミスの影響範囲を最小化するためにも重要です。
④ リージョンを東京に固定する
右上のリージョン選択で「アジアパシフィック(東京)ap-northeast-1」を選択します。別リージョンにリソースを作って放置→課金というのがよくある罠なので、作業のたびに確認する習慣をつけましょう。
1:VPC・ネットワーク設定
VPCの作成
VPCはAWS上の「自分専用のネットワーク空間」です。EC2とRDSをこの中に置いて外部から守ります。
VPCのコンソールから「VPCを作成」をクリックし、以下の設定で作成します。
| 項目 | 設定値 |
|---|---|
| 作成するリソース | VPCなど(「VPCのみ」ではない) |
| 名前タグ | task-manager-vpc |
| IPv4 CIDRブロック | 10.0.0.0/16 |
| アベイラビリティーゾーン数 | 2 |
| パブリックサブネット数 | 2 |
| プライベートサブネット数 | 2 |
| NATゲートウェイ | なし(有料なので) |
| VPCエンドポイント | なし |
「VPCなど」を選ぶとサブネット・インターネットゲートウェイ・ルートテーブルまで一括で作成してくれるので便利です。「VPCのみ」を選ぶと全部手動で作る必要があります。
セキュリティグループの作成
セキュリティグループはEC2用とRDS用の2つを作ります。
EC2用セキュリティグループ
EC2 → セキュリティグループ → 「セキュリティグループを作成」
| 項目 | 設定値 |
|---|---|
| 名前 | task-manager-ec2-sg |
| VPC | task-manager-vpc |
| インバウンド① | HTTP(80)/ ソース:0.0.0.0/0 |
| インバウンド② | HTTPS(443)/ ソース:0.0.0.0/0 |
| インバウンド③ | SSH(22)/ ソース:マイIP |
SSHは「マイIP」を選ぶと自分の現在のIPアドレスが自動入力されます。自分以外からのSSH接続を防ぐためにも、0.0.0.0/0(全許可)にはしないようにしましょう。
RDS用セキュリティグループ
| 項目 | 設定値 |
|---|---|
| 名前 | task-manager-rds-sg |
| VPC | task-manager-vpc |
| インバウンド | MySQL/Aurora(3306)/ ソース:task-manager-ec2-sg
|
ソースにIPアドレスではなくEC2のセキュリティグループを指定するのがポイントです。「EC2からのみRDSに接続できる」設定になります。
2:RDSの構築
RDS → データベース → 「データベースの作成」
| 項目 | 設定値 |
|---|---|
| エンジン | MySQL 8.4 |
| テンプレート | 無料利用枠(重要) |
| DBインスタンス識別子 | task-manager-db |
| マスターユーザー名 | admin |
| DBインスタンスクラス | db.t3.micro |
| ストレージ | 20GB |
| VPC | task-manager-vpc |
| パブリックアクセス | なし |
| セキュリティグループ | task-manager-rds-sg |
テンプレートは必ず「無料利用枠」を選択してください。「本番稼働用」を選ぶとMulti-AZ構成になり課金が発生します。
パブリックアクセスは「なし」にします。RDSはEC2経由でのみアクセスさせ、インターネットから直接接続できない構成にするのがセキュリティ上の基本です。
作成には5〜10分かかります。ステータスが「利用可能」になったら次に進みます。
3:EC2のセットアップ
EC2インスタンスの起動
EC2 → 「インスタンスを起動」
| 項目 | 設定値 |
|---|---|
| 名前 | task-manager-ec2 |
| AMI | Amazon Linux 2023 |
| インスタンスタイプ |
t2.micro(無料枠) |
| キーペア | 新規作成(.pem形式) |
| VPC | task-manager-vpc |
| サブネット | パブリックサブネット |
| パブリックIPの自動割り当て | 有効 |
| セキュリティグループ | task-manager-ec2-sg |
⚠️ キーペアの
.pemファイルは絶対に無くさないでください。これがないとEC2に入れなくなります。ダウンロード後はわかりやすいフォルダに保存しておきましょう。
Elastic IPの設定
EC2を再起動するとIPアドレスが変わってしまうため、Elastic IPで固定します。
EC2 → Elastic IP → 「Elastic IPアドレスを割り当てる」→ 作成後にEC2インスタンスに関連付けます。
⚠️ EC2を停止した状態でElastic IPを持ち続けると課金が発生します(約$0.005/時間)。停止するときはElastic IPの関連付けを解除するか、EC2ごと削除するようにしましょう。
4:EC2の環境構築
SSH接続
Windowsの場合(PowerShell):
初回接続時にpermissionエラーが出ることがあります。その場合は以下のコマンドで権限を修正してから再接続してください。
icacls "C:\Users\ユーザー名\Downloads\task-manager-key.pem" /inheritance:r
icacls "C:\Users\ユーザー名\Downloads\task-manager-key.pem" /grant:r "ユーザー名:R"
ssh -i "C:\Users\ユーザー名\Downloads\task-manager-key.pem" ec2-user@EC2のIPアドレス
[ec2-user@ip-xxx ~]$ と表示されれば接続成功です。
PHP・Apache・Gitのインストール
# パッケージを最新化
sudo dnf update -y
# Apache・PHP・Gitをインストール
sudo dnf install -y httpd php php-mysqlnd php-mbstring php-xml php-zip git
# Apacheを起動・自動起動設定
sudo systemctl start httpd
sudo systemctl enable httpd
MySQLクライアントも必要です。Amazon Linux 2023ではmysqlというパッケージ名が存在しないので注意です(後述のハマりポイント参照)。
sudo dnf install -y mariadb105
アプリのデプロイ
cd /var/www/html
sudo git clone https://ユーザー名:トークン@github.com/リポジトリ名.git .
GitHubはパスワード認証が廃止されているので、Personal Access Token(PAT)を使います。以下のURLから直接アクセスして発行できます。
「Generate new token (classic)」→ スコープでrepoにチェック → 生成されたトークンをコピー。トークンは一度しか表示されないので必ずメモしておいてください。
⚠️ Settings → Developer settings → GitHub Appsの画面に飛んでしまう場合があります。上記URLに直接アクセスするのが確実です。
.envの設定
sudo cp .env.example .env
sudo nano .env
RDSの接続情報を設定します。エンドポイントはRDSのコンソール → データベース → 該当DBを選択 → 「接続とセキュリティ」タブで確認できます。
DB_HOST=xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com
DB_PORT=3306
DB_NAME=task_manager
DB_USER=admin
DB_PASS=設定したパスワード
⚠️ .envのキー名はアプリのコードと一致させてください。Laravelの場合は
DB_USERNAMEですが、自作アプリの場合はコードを確認して合わせる必要があります(後述のハマりポイント参照)。
マイグレーションの実行
まずRDSにデータベースを作成します。
mysql -h RDSのエンドポイント -u admin -p
CREATE DATABASE task_manager;
exit
SQLファイルを流し込みます。
mysql -h RDSのエンドポイント -u admin -pパスワード task_manager < database/migrations/001_create_users_table.sql
mysql -h RDSのエンドポイント -u admin -pパスワード task_manager < database/migrations/002_create_tasks_table.sql
Apacheのバーチャルホスト設定
sudo nano /etc/httpd/conf.d/task-manager.conf
<VirtualHost *:80>
DocumentRoot /var/www/html/public
DirectoryIndex index.php
<Directory /var/www/html/public>
AllowOverride All
Require all granted
</Directory>
ErrorLog /var/log/httpd/task-manager-error.log
CustomLog /var/log/httpd/task-manager-access.log combined
</VirtualHost>
# パーミッションの設定
sudo chown -R apache:apache /var/www/html
sudo chmod -R 755 /var/www/html
# Apacheを再起動
sudo systemctl restart httpd
ブラウザで http://EC2のIPアドレス にアクセスしてアプリが表示されれば成功です🎉
ハマったポイント
WindowsのSSHパーミッションエラー
WARNING: UNPROTECTED PRIVATE KEY FILE!
Bad permissions. Try removing permissions for user: ...
Windowsでは.pemファイルのアクセス権限が広すぎると接続を拒否されます。icaclsコマンドで権限を絞ることで解決できます。SSH接続の手順に記載したコマンドを試してみてください。
GitHubのパスワード認証廃止
remote: Invalid username or token. Password authentication is not supported for Git operations.
GitHubはHTTPSでのパスワード認証を廃止しています。Personal Access Token(PAT)を発行して使いましょう。
Amazon Linux 2023でmysqlコマンドが見つからない
-bash: mysql: command not found
No match for argument: mysql
Amazon Linux 2023ではmysqlパッケージが存在しません。代わりにmariadb105をインストールします。
sudo dnf install -y mariadb105
.envのキー名がコードと一致していなかった
.envにDB_USERNAMEと書いていたのに、コードが$_ENV['DB_USER']で読んでいてDB接続エラーになりました。Laravelに慣れている方は特にハマりやすいポイントです。エラーメッセージをよく読んで、コードと.envのキー名を合わせることで解決しました。
完成した構成
インターネット
↓(HTTP:80)
EC2(t2.micro)
├── Amazon Linux 2023
├── Apache 2.4
├── PHP 8.4
└── アプリ(/var/www/html/public)
↓(MySQL:3306 / プライベートネットワーク)
RDS(db.t3.micro)
└── MySQL 8.4
無料枠について
⚠️ 2025年7月15日にAWSの無料枠の仕組みが大きく変わりました。アカウントの作成時期によって適用される内容が異なります。
アカウント作成が2025年7月15日より前の場合(従来の12ヶ月無料枠)
| サービス | 無料枠 |
|---|---|
EC2 t2.micro
|
750時間/月(12ヶ月) |
RDS db.t3.micro
|
750時間/月(12ヶ月) |
| EBSストレージ | 30GB/月 |
| Elastic IP | EC2起動中は無料 |
アカウント作成が2025年7月15日以降の場合(新しいクレジット制)
従来の「サービスごとの12ヶ月無料枠」は廃止され、クレジット制に変わっています。
| 項目 | 内容 |
|---|---|
| サインアップ特典 | $100クレジット自動付与 |
| ボーナス特典 | EC2起動・予算設定などのタスク完了で最大$100追加 |
| 有効期限 | 6ヶ月、またはクレジット消化まで |
| 期限後(無料プランの場合) | アカウントが自動閉鎖(90日以内にアップグレード可) |
私はこちらのクレジット制のアカウントで今回のデプロイを行いました。
どちらのプランでも共通の注意点:
- EC2を停止した状態でElastic IPを保持すると課金が発生します
- 請求アラートを必ず設定しておきましょう
- 最新情報はAWS公式の無料枠ページを確認してください
おわりに
初めてのAWSデプロイでしたが、VPCの概念やセキュリティグループの設定など、インフラの基礎を体験することができました。ローカルで動いていたアプリが実際にインターネットで公開されたときは単純に嬉しかったです。
同じようにAWS初心者でデプロイに挑戦している方の参考になれば幸いです!