0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Docker環境のWebアプリをAWS EC2にデプロイする手順

Posted at

作成したアプリ

ふつうのTODOアプリみたいなアプリです。
特段すごい機能があるわけではないので、詳細は割愛します。

技術スタック

  • フロントエンド: Vue3, TypeScript
  • バックエンド(Web API): Node.js + Express
  • DB: PostgreSQL
  • 開発環境: docker(フロントエンド, バックエンド, DB)
  • サーバー: EC2(AWS)

デプロイの流れ

  1. AWSアカウント作成〜EC2起動
  2. ローカルのdockerコンテナ上でWebアプリを実装
  3. ローカルのWebアプリのファイルをEC2へ転送
  4. EC2でdocker環境を構築
  5. EC2でのアプリ動作環境準備
  6. デプロイ確認
  7. まとめ

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を起動するだけでも多くの設定が必要ですが、各サービスの役割を理解すれば直感的に進めることができました。
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?