作成したアプリ
ふつうのTODOアプリみたいなアプリです。
特段すごい機能があるわけではないので、詳細は割愛します。
技術スタック
- フロントエンド: Vue3, TypeScript
- バックエンド(Web API): Node.js + Express
- DB: PostgreSQL
- 開発環境: docker(フロントエンド, バックエンド, DB)
- サーバー: EC2(AWS)
デプロイの流れ
- AWSアカウント作成〜EC2起動
- ローカルのdockerコンテナ上でWebアプリを実装
- ローカルのWebアプリのファイルをEC2へ転送
- EC2でdocker環境を構築
- EC2でのアプリ動作環境準備
- デプロイ確認
- まとめ
AWSアカウント作成〜EC2起動
1. AWSアカウントの作成
AWSアカウントを作成し、マネジメントコンソールにログイン。
2. ネットワーク設定とEC2インスタンスの作成
VPCの作成
- AMI:Amazon Linux
- インスタンスタイプ:t2micro(無料枠)
- パブリック IP の自動割り当て:有効
サブネットの作成
- 作成したVPCに紐付け
インターネットゲートウェイの作成
- 作成したVPCにアタッチ
ルートテーブルの作成
- ルーティング追加(0.0.0.0/0 → 作成したインターネットゲートウェイ)
- 作成したサブネットに紐付け
EC2インスタンスの作成
- 作成したVPC、サブネットに紐付け
- 自動割り当てパブリックIPを有効化
- キーペアを作成・ダウンロード
以降、ダウンロードしたキーペアを使用してSSH接続するので、必ずダウンロードしてください。
セキュリティグループ設定
- ポート:8080(フロントエンド用) → 自分のIP(MyIP)のみ許可
- ポート:3000(バックエンド用) → 自分のIP(MyIP)のみ許可
- ポート:22(SSH用) → 自分のIP(MyIP)のみ許可
3. EC2インスタンスの起動
設定完了後、EC2インスタンスを起動
ローカルのdockerコンテナ上でWebアプリを実装
開発環境は以下の構成です。
first-moments
├── docker-compose.yml
├── frontend
│ ├── node_modules
│ ├── package.json
│ ├── src
│ ├── Dockerfile
│ └── 他省略
├── backend/
│ ├── node_modules
│ ├── package.json
│ ├── controllers
│ ├── Dockerfile
└── └── 他省略
ソースコードは割愛しますが、下記が大まかな内容です。
- dockerコンテナ1:フロントエンド(Vue.js)
- dockerコンテナ2:バックエンド Web API(Node.js+Express)
- dockerコンテナ3:DB(PostgresSQL)
1. ローカルのWebアプリのファイルをEC2へ転送
1. 転送前準備
ローカルプロジェクトのfrontend,backend内の node_modules を削除
EC2上で再度パッケージインストールするためnode_modulesは不要です。またnode_modulesを転送しようとするとかなり時間がかかります。
2. ファイル転送
プロジェクト構成は下記です。first-momentsフォルダごと転送しました。
first-moments
├── docker-compose.yml
├── frontend
│ └── 省略
├── backend/
└── └── 省略
scpコマンドで転送
※今回はそのまま転送しましたが、圧縮転送した方がいいのかもしれません。
※選択するEC2のマシンイメージによっては「ec2-user」とは別のユーザーを指定する必要があるかもしれません。
scp -i <キーペア名>.pem -r first-moments ec2-user@<EC2-Public-IP>:/home/ec2-user/
EC2でのアプリ動作環境準備
1. EC2にSSH接続
ssh -i <キーペア名>.pem ec2-user@<EC2のパブリックIP>
2. キーペアのパーミッションを変更(エラー回避)
chmod 600 <キーペア名>.pem
3. DockerとDocker-Composeのインストール
sudo yum update -y
sudo yum install -y docker
sudo systemctl start docker
sudo systemctl enable docker
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
4. Dockerを有効化
以降のsudoコマンドを省略するため、ec2-userユーザを追加
sudo usermod -aG docker ec2-user
dockerコンテナに入り直し、dockerコマンドでバージョンが確認できればOK
docker version
docker-compose version
5. DBのセットアップ
PostgreSQLコンテナに接続
docker exec -it <dbコンテナ名> psql -U <ユーザー名> -d <DB名>
ローカルで作成したテーブルの作成(必要に応じてデータ投入も)
CREATE TABLE ...;
6. npmパッケージのインストール
cd /home/ec2-user/first-moments/frontend && npm install
cd /home/ec2-user/first-moments/backend && npm install
7. コンテナの起動
cd /home/ec2-user/first-moments
docker-compose up --build -d
ちなみに今回作成したアプリのdocker-compose.ymlです
services:
db:
image: postgres:latest
container_name: first_moments_db
environment:
POSTGRES_USER: XXXXX
POSTGRES_PASSWORD: XXXXX
POSTGRES_DB: XXXXX
ports:
- '5432:5432'
volumes:
- postgres_data:/var/lib/postgresql/data
networks:
- app-network
frontend:
build:
context: ./frontend
container_name: first_moments_frontend
ports:
- '8080:8080'
volumes:
- ./frontend/src:/app/src # ホストのsrcをコンテナのsrcにマウント
- /app/node_modules # node_modulesはボリュームでマウント
command: npm run serve # 開発モードで起動
networks:
- app-network
environment:
- CHOKIDAR_USEPOLLING=true # ホットリロードを有効にする設定
backend:
build:
context: ./backend
ports:
- '3000:3000'
volumes:
- ./backend:/app # ソースコードをコンテナと同期
- /app/node_modules # node_modules はマウントしない
networks:
- app-network
depends_on:
- db
environment:
- PGUSER=XXXXX
- PGPASSWORD=XXXXX
- PGDATABASE=XXXXX
- PGHOST=db
- PGPORT=5432
restart: unless-stopped # コンテナがクラッシュした場合の自動再起動
volumes:
postgres_data:
driver: local
networks:
app-network:
driver: bridge
動作確認
ローカルPCのブラウザからアクセス
http://<EC2のパブリックIP>:8080
動作確認時にコードの微修正をしようと思い、VSCodeの拡張機能「Remote-SSH」でec2にSSH接続をしようとすると、ec2が動かなくなる事象が発生しました。
調べてみても理由がわからず、一旦今回はec2に直接入りviコマンドで修正を行いました。
まとめ
- AWSの設定は最初はとっつきづらいですが、ドキュメントが豊富で解説記事も多く、そこまでハマるところはありませんでした。
- EC2を起動するだけでも多くの設定が必要ですが、各サービスの役割を理解すれば直感的に進めることができました。