docker-compose.ymlを使ったAWS ECS+Fargate構築・デプロイ

# docker-compose.ymlを使ったAWS ECS+Fargate構築・デプロイ

DockerとAWSが提携したことによりdocker-compose.yamlでECS+Fargate構築ができるようになったので試してみた、恐らく現状一番簡単にECS+Fargate構築する方法だと感じた

# 導入確認

### Amazon ECS用のコンテキスト作成

AWS認証は既存Profileを使う

```bash
$ docker context create ecs docker-lamp-ecs
? Create a Docker context using: An existing AWS profile
? Select AWS Profile toyscreation-sandbox
Successfully created ecs context "docker-lamp-ecs"
```

コンテキスト確認

```bash
$ docker context ls
NAME                TYPE                DESCRIPTION                               DOCKER ENDPOINT               KUBERNETES ENDPOINT   ORCHESTRATOR
default *           moby                Current DOCKER_HOST based configuration   unix:///var/run/docker.sock                         swarm
docker-lamp-ecs     ecs
```

コンテキスト切替

```bash
$ docker context use docker-lamp-ecs
docker-lamp-ecs
```

サンプル用 docker-compose.yml

※ Fargateの仕様でポートは合わせないとダメ

```docker
version: '3'
services:
  web:
    image: nginx:alpine
    ports:
      - "80:80"
```

### デプロイ

初回はネットワークやLB作成で完了まで数分必要

```bash
$ docker compose up
[+] Running 14/14
 ⠿ docker-lamp-ecs           CreateComplete                                                                                                               214.0s
 ⠿ LogGroup                  CreateComplete                                                                                                                 3.0s
 ⠿ DefaultNetwork            CreateComplete                                                                                                                 6.0s
 ⠿ Cluster                   CreateComplete                                                                                                                 7.0s
 ⠿ WebTCP80TargetGroup       CreateComplete                                                                                                                 2.0s
 ⠿ CloudMap                  CreateComplete                                                                                                                47.0s
 ⠿ WebTaskExecutionRole      CreateComplete                                                                                                                20.0s
 ⠿ DefaultNetworkIngress     CreateComplete                                                                                                                 1.0s
 ⠿ Default80Ingress          CreateComplete                                                                                                                 0.0s
 ⠿ LoadBalancer              CreateComplete                                                                                                                93.0s
 ⠿ WebTaskDefinition         CreateComplete                                                                                                                 3.0s
 ⠿ WebServiceDiscoveryEntry  CreateComplete                                                                                                                 2.0s
 ⠿ WebTCP80Listener          CreateComplete                                                                                                                 3.0s
 ⠿ WebService                CreateComplete
```

起動確認

```bash
$ docker compose ps
NAME                                                    SERVICE             STATUS              PORTS
task/docker-lamp-ecs/fe7462a926564eebb687108072cad1ce   web                 Running             docke-LoadB-16JYFI6MV3SFP-1588601394.ap-northeast-1.elb.amazonaws.com:80->80/http
```

```bash
$ curl http://docke-loadb-16jyfi6mv3sfp-1588601394.ap-northeast-1.elb.amazonaws.com
<!DOCTYPE html>
<html>
~略~
</html>
```

 削除（コンテナ、LB全てが削除、注意が必要）

```bash
$ docker compose down
[+] Running 14/14
 ⠿ docker-lamp-ecs           DeleteComplete                                                                                                                54.0s
 ⠿ DefaultNetworkIngress     DeleteComplete                                                                                                                 1.0s
 ⠿ WebService                DeleteComplete                                                                                                                 2.0s
 ⠿ Default80Ingress          DeleteComplete                                                                                                                 1.0s
 ⠿ WebTCP80Listener          DeleteComplete                                                                                                                 2.0s
 ⠿ WebTaskDefinition         DeleteComplete                                                                                                                 2.0s
 ⠿ Cluster                   DeleteComplete                                                                                                                 2.0s
 ⠿ WebServiceDiscoveryEntry  DeleteComplete                                                                                                                 1.0s
 ⠿ CloudMap                  DeleteComplete                                                                                                                47.0s
 ⠿ LogGroup                  DeleteComplete                                                                                                                 2.0s
 ⠿ WebTaskExecutionRole      DeleteComplete                                                                                                                 2.0s
 ⠿ WebTCP80TargetGroup       DeleteComplete                                                                                                                 0.0s
 ⠿ LoadBalancer              DeleteComplete                                                                                                                 1.1s
 ⠿ DefaultNetwork            DeleteComplete
```

# 自分のDockerイメージでデプロイ

素のnginxコンテナを作成しても意味が無いので
作成したDockerイメージを使いデプロイを行う

### Dockerfile

```docker
FROM nginx:alpine

COPY settings/default.conf /etc/nginx/conf.d/default.conf
COPY settings/nginx.conf /etc/nginx/nginx.conf
COPY project/html /var/www/html
```

サンプルHTML

```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>TEST</title>
</head>
<body>
TEST
</body>
</html>
```

### ECRにレジストリ作成

```bash
$ aws ecr create-repository --repository-name nginx --region ap-northeast-1 --profile toyscreation-sandbox
{
    "repository": {
        "repositoryArn": "arn:aws:ecr:ap-northeast-1:689371460795:repository/nginx",
        "registryId": "689371460795",
        "repositoryName": "nginx",
        "repositoryUri": "689371460795.dkr.ecr.ap-northeast-1.amazonaws.com/nginx",
        "createdAt": "2021-05-22T15:37:22+09:00",
        "imageTagMutability": "MUTABLE",
        "imageScanningConfiguration": {
            "scanOnPush": false
        },
        "encryptionConfiguration": {
            "encryptionType": "AES256"
        }
    }
}
```

### コンテナビルド

上記で作成したリポジトリ名と同じになるようにビルド
タグ（latest）は適時変更、このイメージが実行環境

```bash
$ docker build -t 689371460795.dkr.ecr.ap-northeast-1.amazonaws.com/nginx:latest -f Dockerfile .
```

```bash
$ docker images
REPOSITORY                                                TAG       IMAGE ID       CREATED        SIZE
689371460795.dkr.ecr.ap-northeast-1.amazonaws.com/nginx   latest    ba6f4a7d15cf   22 hours ago   22.6MB
```

### ECRにログイン

```bash
$ aws ecr get-login-password --region ap-northeast-1 --profile toyscreation-sandbox | docker login --username AWS --password-stdin 689371460795.dkr.ecr.ap-northeast-1.amazonaws.com
Login Succeeded
```

### ECRにイメージをプッシュ

```bash
$ docker push 689371460795.dkr.ecr.ap-northeast-1.amazonaws.com/nginx:latest
```

確認

```html
$ aws ecr list-images --repository-name nginx --region ap-northeast-1 --profile toyscreation-sandbox
{
    "imageIds": [
        {
            "imageDigest": "sha256:52bf40057dad5518478a8cb5d09bfe2c983165c1138f3541a6fdab8c9b52e44b",
            "imageTag": "latest"
        }
    ]
}
```

### デプロイ

サンプル用 docker-compose-sandbox.yaml

```html
version: '3'
services:
  web:
    image: 689371460795.dkr.ecr.ap-northeast-1.amazonaws.com/nginx:latest
    ports:
      - 80:80
```

デプロイ実行

```html
$ docker compose -f docker-compose-sandbox.yaml up
[+] Running 14/14
 ⠿ sample2                   CreateComplete                                                                                                               172.0s
 ⠿ WebTCP80TargetGroup       CreateComplete                                                                                                                 1.0s
 ⠿ LogGroup                  CreateComplete                                                                                                                 2.0s
 ⠿ DefaultNetwork            CreateComplete                                                                                                                 6.0s
 ⠿ WebTaskExecutionRole      CreateComplete                                                                                                                18.0s
 ⠿ CloudMap                  CreateComplete                                                                                                                47.0s
 ⠿ Cluster                   CreateComplete                                                                                                                 6.0s
 ⠿ DefaultNetworkIngress     CreateComplete                                                                                                                 1.0s
 ⠿ Default80Ingress          CreateComplete                                                                                                                 1.0s
 ⠿ LoadBalancer              CreateComplete                                                                                                                92.0s
 ⠿ WebTaskDefinition         CreateComplete                                                                                                                 3.0s
 ⠿ WebServiceDiscoveryEntry  CreateComplete                                                                                                                 2.0s
 ⠿ WebTCP80Listener          CreateComplete                                                                                                                 3.0s
 ⠿ WebService                CreateComplete
```

起動確認

```bash
$ docker compose ps
NAME                                            SERVICE             STATUS              PORTS
task/sample2/a80d925f7cf34623a89532baef64ae08   web                 Running             sampl-LoadB-1UN021W7UW34O-1036249040.ap-northeast-1.elb.amazonaws.com:80->80/http
```

```bash
$ curl sampl-LoadB-1UN021W7UW34O-1036249040.ap-northeast-1.elb.amazonaws.com
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>TEST</title>
</head>
<body>
TEST
</body>
```

ファイル変更がある場合は新たにコンテナビルドしてECRにプッシュしdocker compose upすれば反映
docker-compose.yaml にECR特有ルールを記述することでVPC指定やオートスケール設定が可能
そこら辺はまた別の機会に

---

いいね！と思ったら LGTM お願いします :clap::clap::clap:

【PR】週末ハッカソンというイベントやってます！ → https://weekend-hackathon.toyscreation.jp/about/