やりたいこと
ローカルで構築したDockerコンテナをEC2上にデプロイして実行する
材料
- EC2
- FSx for windows
- Docker
- Amazon Elastic Container Registry (ECR)
- ローカルGo環境
- AWS CLI
レシピ
1.AWS CLIをインストール
# 例:Macでhomebrewを使用
% brew install awscli
2.EC2を作成
キーペアを作成した場合はダウンロードしたpemファイルのパーミッションを変更
(ローカル環境)
% chmod 400 keypar.pem
3.必要なパッケージをインストール
(EC2)
# Amazon Linux 2023でDockerとAWS CLIのインストール
$ sudo yum update -y
$ sudo yum install -y docker
$ sudo service docker start
$ sudo usermod -aG docker ec2-user
$ sudo yum install -y aws-cli cifs-utils
4.ローカルGO環境構築
Dockerfileを作成します
# ベースイメージとして公式のGoイメージを使用
FROM golang:1.20
# 作業ディレクトリを作成
WORKDIR /app
次に、docker-compose.ymlを作成します。
version: '3'
services:
app:
build: .
volumes:
- .:/app
ports:
- "8080:8080"
適当なgoファイルを作成
今回は、いつものHello Worldを出力する
package main
import (
"fmt"
)
func main() {
fmt.Printf("Hello World\n")
}
コンテナをビルドします。
ビルドできたらコンテナに入ります。
% docker-compose build
% docker-compose run --rm app sh
goの初期化を実施。
$ go mod init backend
$ exit
goの初期化ができたら、Dockerfileに追記します。
# ベースイメージとして公式のGoイメージを使用
FROM golang:1.20
# 作業ディレクトリを作成
WORKDIR /app
# ここから追記
# ソースコードをコンテナにコピー
COPY . .
CMD ["go", "run", "."]
5.ECRリポジトリ作成
AWS コンソールに戻り、ECRレポジトリを作成します。
適当な名前を登録します。
6.IAMロール作成
次にECR用のIAMロールを作成します。
サービスはEC2を選択。
許可ポリシーにAmazonEC2ContainerRegistryFullAccessを選択。
7.作成IAMロールをEC2にアタッチ
8.DockerイメージをECRにプッシュ
ローカル環境にて行います。
まずは、Dockerへの認証
% aws ecr --region ap-northeast-1 get-login-password | docker login --username AWS --password-stdin https://${AWS_ACCOUNT_ID}.dkr.ecr.ap-northeast-1.amazonaws.com/batch-server
dockerイメージをビルドします。
% docker image build -t batch-server:v1 .
コンテナイメージにタグ付けします。
% AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query 'Account' --output text)
% docker image tag batch-server:v1 ${AWS_ACCOUNT_ID}.dkr.ecr.ap-northeast-1.amazonaws.com/batch-server:v1
ECRへコンテナイメージを登録。
% docker image push ${AWS_ACCOUNT_ID}.dkr.ecr.ap-northeast-1.amazonaws.com/batch-server:v1
9.EC2上でdockerイメージをデプロイ
EC2で行います。
EC2でもDockerへの認証を行います。
$ aws ecr --region ap-northeast-1 get-login-password | docker login --username AWS --password-stdin https://${AWS_ACCOUNT_ID}.dkr.ecr.ap-northeast-1.amazonaws.com/batch-server
このDockerへの認証を忘れるとエラーになります。
Error response from daemon: Head "https://${AWS_ACCOUNT_ID}.dkr.ecr.ap-northeast-1.amazonaws.com/v2/batch-server/manifests/v1": no basic auth credentials
念のため、ビルド済みコンテナイメージの削除
$ docker image rm -f $(docker image ls -q)
docker コマンドでエラーになった場合
sockに権限がないと怒られる
permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get "http://%2Fvar%2Frun%2Fdocker.sock/v1.24/images/json": dial unix /var/run/docker.sock: connect: permission denied
sockのパーミッションを変更
$ sudo chmod 666 /var/run/docker.sock
ECRのイメージをEC2へPULLします。
$ docker image pull ${AWS_ACCOUNT_ID}.dkr.ecr.ap-northeast-1.amazonaws.com/batch-server:v1
イメージを確認
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
${AWS_ACCOUNT_ID}.dkr.ecr.ap-northeast-1.amazonaws.com/batch-server v1 df9fb8e2e9ed About an hour ago 852MB
イメージからコンテナを実行
$ docker container run -it --rm ${AWS_ACCOUNT_ID}.dkr.ecr.ap-northeast-1.amazonaws.com/batch-server:v1
エラー
WARNING: The requested image's platform (linux/arm64/v8) does not match the detected host platform (linux/amd64/v3) and no specific platform was requested
exec /usr/local/go/bin/go: exec format error
どうやらM1 Macの環境のコンテナをそのままEC2上では実行できないらしい
手順8のビルドを以下に変更
$ docker image build --platform amd64 -t batch-server:v1 .
手順をやり直します。
コンテナを実行します。
$ docker container run -it --rm ${AWS_ACCOUNT_ID}.dkr.ecr.ap-northeast-1.amazonaws.com/batch-server:v1
無事にコンテナを実行して結果が出力されました。
Hello World