本連載では第一線のPerlハッカーが回替わりで執筆していきます。今回のハッカーは、
本稿のサンプルコードは、
リモートの開発環境もDocker化
2013年3月のDockerの登場から7年が経ちました。周辺ツールの充実もあり、
しかし、
Amazon ECS──クラウドで動作するマネージドコンテナサービス
(1)
ECSは、
ECSについて詳しくは、
Amazon ECSにデプロイできるPerlアプリケーションを作ろう
本項では、
アプリケーションのディレクトリ構造
今回は、application以下に、
$ tree -a
.
├── .github
│     └── workflows
│           ├── aws.yml
│           └── perl.yml
├── application
│     ├── Dockerfile
│     ├── app.psgi
│     ├── cpanfile
│     ├── cpanfile.snapshot
│     └── generate-cpanfile-snapshot.sh
├── docker-compose-ecs.yml
├── docker-compose.yml
└── task-definition.jsonPSGIアプリケーションの作成
PSGIアプリケーションは定型文を返すだけのシンプルなもので、app.の内容は次のとおりです。
my $app = sub {
  return [
    200,
    [ 'Content-Type' => 'text/plain' ],
    [ 'Hello, Plack!' ],
  ];
};Dockerfileの作成
Dockerfileの内容は次のとおりです。
FROM perl:5.30
RUN mkdir /app
WORKDIR /app
COPY cpanfile /app/cpanfile
COPY cpanfile.snapshot /app/cpanfile.snapshot
RUN cpanm Carton
COPY app.psgi /app/app.psgi
RUN carton install --deployment
CMD [ \
  "carton", "exec", "--", "plackup", \
  "--app", "app.psgi", "--server", "Starlet", \
  "--port", "80", "--host", "0.0.0.0" \
  ]Cartonをインストールし、plackupDockerfile中ではcpanfile.を変更したくないため、--deploymentオプション付きで起動しています。
docker-compose.ymlの作成と動作確認 
手もとでも起動できることを確認します。
まず、docker-compose.を作成します。
version: "3"
services:
  app:
    build: ./application
    ports:
      - "8000:80"docker-compose.をプロジェクトルートに配置した状態で、
$ docker-compose up
Building app
(省略)
Successfully built c471b02b6fdb
(省略)
app_1 | Plack::Handler::Starlet: Accepting connections at
http://0.0.0.0:80/無事に動作しました。のちほどイメージをECRにpushするために、c471b02b6fdb)
Amazon ECRへのイメージのpush
ECSでアプリケーションを動かすためには、
あらかじめECRにリポジトリを作成しておき、
$ docker tag \
  イメージID \
  AWSアカウントID.dkr.ecr.ap-northeast-1.amazonaws.com/リポジトリ名:latest
$ docker push \
  AWSアカウントID.dkr.ecr.ap-northeast-1.amazonaws.com/リポジトリ名:latestdocker-compose-ecs.ymlの作成 
次項でECSにデプロイするために、docker-compose.を改変したdocker-compose-ecs.を作成します。
version: "3"
services:
  app:
    image: AWSアカウントID.dkr.ecr.ap-northeast-1.amazonaw
s.com/リポジトリ名:latest(実際は1行)
    ports:
      - "80:80"イメージをビルドする代わりに、awsvpcインタフェースではコンテナポートとホストポートが一致している必要があるため、
Amazon ECSへデプロイしよう
では、
ECSにおけるタスク定義は、docker-compose.に該当する概念です。タスク定義は、
以降では、
ecs-cliコマンドのインストール
タスクのECSへのデプロイは、ecs-cliコマンドを用いて行います。公式ドキュメントを参考に、ecs-cliコマンド
プロファイルの設定
次に、ecs-cliコマンドが使うプロファイルを設定し、
$ ecs-cli configure profile \
  --profile-name プロファイル名 \
  --access-key $AWS_ACCESS_KEY_ID \
  --secret-key $AWS_SECRET_ACCESS_KEY
INFO[0000] Saved ECS CLI profile configuration プロファイル名.ECSクラスタの作成
ECSクラスタを事前に作成しましょう。既存のクラスタを使う場合は、
$ ecs-cli up --vpc VPCのID \
  --subnets サブネットID[,サブネットID...] \
  --launch-type FARGATE \
  --region ap-northeast-1 \
  --cluster クラスタ名このクラスタをecs-cliコマンドのデフォルトとして使うことを指定します。
$ ecs-cli configure \
  --cluster クラスタ名 \
  --default-launch-type FARGATE \
  --region ap-northeast-1 \
  --config-name クラスタ設定に付ける名前Amazon ECSタスク定義の作成
そして、ecs-cliコマンドがどのクラスタをコンテナの起動先に指定するのか、ecs-params.に記述します。
version: 1
task_definition:
  # ↓あらかじめ実行ロールを作成しておくこと
  task_execution_role: ecsTaskExecutionRole
  ecs_network_mode: awsvpc
  task_size:
    mem_limit: 0.5GB
    cpu_limit: 256
run_params:
  network_configuration:
    awsvpc_configuration:
      subnets:
        - "subnet-xxxxxx"
      security_groups:
        - "sg-xxxxxxxxxxxx"
      assign_public_ip: ENABLEDこれで、
いざデプロイ
次のコマンドを実行すると、
$ ecs-cli compose \
  -f docker-compose-ecs.yml \
  --project-name サービスに付ける名前 service up \
  --create-log-groups \
  --cluster-config クラスタ設定名 \
  --ecs-profile プロファイル名コンテナが動作しているかを確認しましょう。
$ ecs-cli compose \
  --project-name サービスに付けた名前 service ps \
  --cluster-config クラスタ設定名 \
  --ecs-profile プロファイル名
Name      State    Ports  TaskDefinition  Health
..../app  RUNNING  xxx.yyy.zzz.aaa:80->80/tcp  app:1  UNKNOWN公開IPアドレスが表示されていればアプリケーションはECS上で動作しています。
$ curl http://xxx.yyy.zzz.aaa/
Hello, Plack!<続きの
本誌最新号をチェック!
WEB+DB PRESS Vol.130
2022年8月24日発売
B5判/
定価1,628円
ISBN978-4-297-13000-8
- 特集1
 イミュータブルデータモデルで始める
 実践データモデリング
 業務の複雑さをシンプルに表現!
- 特集2
 いまはじめるFlutter
 iOS/Android両対応アプリを開発してみよう 
- 特集3
 作って学ぶWeb3
 ブロックチェーン、スマートコントラクト、 NFT 



