目次
はじめに
Next.jsで作成したアプリケーションをAWS
ECSにデプロイさせていきます。
でいる限り、コマンドライン上で操作できるように調べながらやっていきたいと思います。
Next.js アプリケーションの準備
まず、Next.jsアプリケーションを作成します。
「npx create」コマンド実行時に聞かれる質問は基本デフォルトでOK。
npx create-next-app@latest my-nextjs-app
cd my-nextjs-app
npm run build
Dockerコンテナの作成
1.Dockerfileの作成
次に、Next.jsアプリケーション用のDockerfileを作成します。
C:.
│ .gitignore
│ Dockerfile ←新規作成
│ next-env.d.ts
│ next.config.mjs
│ package-lock.json
│ package.json
│ README.md
│ tsconfig.json
├─.next
├─node_modules
├─public
└─src
ファイル中身
FROM node:14-alpine
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm install
COPY . .
RUN npm run build
EXPOSE 3000
CMD ["npm", "start"]
FROM | ベースとなるコンテナイメージを指定している |
WORKDIR | コンテナ内で作業するディレクトリを指定している |
COPY | ホストマシンからコンテナ内にファイルをコピーしている |
EXPOSE | コンテナが使用するポートを指定している |
ENTRYPOINT | コンテナが起動する際に実行されるコマンドを指定します。この場合は、npm startが実行される |
2. Dockerイメージのビルドとコンテナの起動
Dockerイメージをビルドし、Next.jsアプリケーションをDockerコンテナ内で実行します。
docker build -t my-nextjs-app .
docker run -d -p 3000:3000 --name my-nextjs-container my-nextjs-app
3. ブラウザでアクセス
ブラウザで以下のURLにアクセスすると、Next.jsアプリケーションが表示されます。
http://localhost:3000
Amazon ECR リポジトリの作成(オプション)
AWS Management ConsoleでECRリポジトリを作成します。コマンドラインから作成する場合:
aws ecr create-repository --repository-name ${REPOSITORY_NAME}
aws ecr create-repository --repository-name my-repo
Dockerイメージのプッシュ
Amazon ECR レジストリに対して Docker を認証する
get-loginコマンドは非推奨になったみたいです。
aws ecr get-login-password | docker login --username AWS --password-stdin 0xxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/my-repo
–password-stdin パスワードを標準入力から読み取る
{0xxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/my-repo}の部分は先ほど作成した、repositoryUri
DockerイメージをECRにプッシュします。
リポジトリにイメージをプッシュできるように、イメージにタグを付けます。
docker tag my-repo:latest 0xxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/my-repo:latest
新しく作成した AWS リポジトリにこのイメージをプッシュ
docker push 0xxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/my-repo:latest
VPCとパブリックサブネットの作成
VPCの作成
aws ec2 create-vpc --cidr-block 10.1.0.0/16 --tag-specifications 'ResourceType=vpc,Tags=[{Key=Name,Value=MyVPCForECS}]'
インターネットゲートウェイの作成とアタッチ
インターネットゲートウェイの作成
aws ec2 create-internet-gateway --tag-specifications 'ResourceType=internet-gateway,Tags=[{Key=Name,Value=MyInternetGatewayForECS}]'
作成されたインターネットゲートウェイのIDを取得
IGW_ID=$(aws ec2 describe-internet-gateways --query 'InternetGateways[?Attachments[0].VpcId==`null`].InternetGatewayId' --output text)
インターネットゲートウェイをVPCにアタッチ
{VPC_ID}のところは、先ほど作成したVpcIdに置き換える
aws ec2 attach-internet-gateway --vpc-id {VPC_ID} --internet-gateway-id $IGW_ID
パブリックサブネットの作成
aws ec2 create-subnet --vpc-id <VPC_ID> --cidr-block 10.1.1.0/24 --availability-zone <Your_AZ> --tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=MyPublicSubnet}]'
ルートテーブルの作成とルート追加
ルートテーブルの作成
aws ec2 create-route-table --vpc-id <VPC_ID> --tag-specifications 'ResourceType=route-table,Tags=[{Key=Name,Value=MyRouteTable}]'
作成されたルートテーブルのIDを取得
ROUTE_TABLE_ID=$(aws ec2 describe-route-tables --filters "Name=vpc-id,Values=<VPC_ID>" "Name=association.main,Values=false" --query 'RouteTables[0].RouteTableId' --output text)
ルートテーブルにインターネットゲートウェイへのルートを追加
aws ec2 create-route --route-table-id $ROUTE_TABLE_ID --destination-cidr-block 0.0.0.0/0 --gateway-id $IGW_ID
ルートテーブルをサブネットにアソシエート
aws ec2 associate-route-table --subnet-id <SUBNET_ID> --route-table-id $ROUTE_TABLE_ID
セキュリティグループの作成
aws ec2 create-security-group --group-name MySecurityGroup --description "My security group" --vpc-id {VPC-ID}
セキュリティグループの設定
# インバウンドルールを追加 (例: HTTPアクセス許可)
# my-ipはコマンドラインで「curl -s http://checkip.amazonaws.com/」を実行するとipアドレス分かります
aws ec2 authorize-security-group-ingress --group-id {Your-Security-Group-ID} --protocol tcp --port 3000 --cidr {my-ip}/32
AWS ECS クラスターの作成
aws ecs create-cluster --cluster-name MyCluster
タスク定義の作成
タスク定義にはDockerイメージ、メモリ、CPU、ネットワーク設定などを指定します。JSON形式で設定し、ECS Management ConsoleやCLIを使用して登録します。
aws ecs register-task-definition --cli-input-json file://taskdef.json(以下のタスク定義ファイルパス)
タスク定義ファイル(taskdef.json):
{
"family": "my-task-def",
"networkMode": "awsvpc",
"containerDefinitions": [
{
"name": "my-app",
"image": "0xxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/my-repo:latest",
"essential": true,
"memory": 512,
"cpu": 256,
"portMappings": [
{
"containerPort": 3000,
"hostPort": 3000
}
]
}
],
"requiresCompatibilities": ["FARGATE"],
"executionRoleArn": "arn:aws:iam::0xxxxxxxxx:role/ecsTaskExecutionRole",
"cpu": "256",
"memory": "512"
}
サービスの作成
ECSサービスはタスクを実行し、スケーリングを管理します。サービスを作成し、クラスター、タスク定義、デプロイメントオプション(例: ロードバランサーの設定)を指定します。
[subnet-xxxxx]と[sg-xxxxxx]は、「VPCとパブリックサブネットの作成」で作成したvpc-id、subnet-idに置き換える
aws ecs create-service --cluster MyCluster --service-name my-service --task-definition my-task-def --desired-count 1 --network-configuration "awsvpcConfiguration={subnets=[subnet-xxxxx],securityGroups=[sg-xxxxxx],assignPublicIp=ENABLED}" --launch-type FARGATE
動作確認
AWSコンソールにアクセスし、作成したタスクの詳細ページを開き、「パブリックIPのオープンアドレス」を確認する。
ブラウザで、「確認したipアドレス:3000」にアクセスする。
おわりに
一旦、ECSにデプロイできました。
本当は、スケーリングの設定や障害復旧の確認までしたいのですが、今回はここまでにします。