

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 使用 Elastic Beanstalk 主控台建立 ECS 受管 Docker 環境
<a name="create_deploy_docker_ecstutorial"></a>

本教學課程詳細說明使用兩個容器的 ECS 受管 Docker 環境的容器組態和原始程式碼準備。

在 Elastic Beanstalk 環境中的每個 Amazon Elastic Compute Cloud (Amazon EC2) 執行個體上，會同時並列執行容器、PHP 應用程式和 nginx 代理。在建立環境和確認應用程式已執行後，您會連線到容器執行個體，來查看這些項目是否能夠順利共同運作。

**Topics**
+ [定義 ECS 受管 Docker 容器](#create_deploy_docker_ecstutorial_config)
+ [新增內容](#create_deploy_docker_ecstutorial_code)
+ [部署到 Elastic Beanstalk](#create_deploy_docker_ecstutorial_deploy)
+ [連線到容器執行個體](#create_deploy_docker_ecstutorial_connect)
+ [檢查 Amazon ECS 容器代理程式](#create_deploy_docker_ecstutorial_connect_inspect)

## 定義 ECS 受管 Docker 容器
<a name="create_deploy_docker_ecstutorial_config"></a>

建立新 Docker 環境的第一步，就是為您的應用程式資料建立目錄。此資料夾可以置於本機機器的任意位置，並讓您選擇任意名稱。除了容器組態檔案之外，此資料夾也會包含您將上傳到 Elastic Beanstalk 的內容，並部署到您的環境。

**注意**  
在 GitHub 上的 awslabs 儲存庫中 ([https://github.com/awslabs/eb-docker-nginx-proxy](https://github.com/awslabs/eb-docker-nginx-proxy))，提供了此教學課程中的所有程式碼。

Elastic Beanstalk 用來設定 Amazon EC2 執行個體上容器的檔案是名為 `Dockerrun.aws.json` v2 的 JSON 格式文字檔案。ECS 受管 Docker 平台版本使用此檔案的第 2 版格式。此格式只能與 ECS 受管 Docker 平台搭配使用，因為它與支援非由 ECS 管理之 Docker 平台分支的其他組態檔案版本明顯不同。

在應用程式的根目錄建立具有此名稱的 `Dockerrun.aws.json` v2 文字檔案，並新增下列文字：

```
{
  "AWSEBDockerrunVersion": 2,
  "volumes": [
    {
      "name": "php-app",
      "host": {
        "sourcePath": "/var/app/current/php-app"
      }
    },
    {
      "name": "nginx-proxy-conf",
      "host": {
        "sourcePath": "/var/app/current/proxy/conf.d"
      }
    }  
  ],
  "containerDefinitions": [
    {
      "name": "php-app",
      "image": "php:fpm",
      "essential": true,
      "memory": 128,
      "mountPoints": [
        {
          "sourceVolume": "php-app",
          "containerPath": "/var/www/html",
          "readOnly": true
        }
      ]
    },
    {
      "name": "nginx-proxy",
      "image": "nginx",
      "essential": true,
      "memory": 128,
      "portMappings": [
        {
          "hostPort": 80,
          "containerPort": 80
        }
      ],
      "links": [
        "php-app"
      ],
      "mountPoints": [
        {
          "sourceVolume": "php-app",
          "containerPath": "/var/www/html",
          "readOnly": true
        },
        {
          "sourceVolume": "nginx-proxy-conf",
          "containerPath": "/etc/nginx/conf.d",
          "readOnly": true
        },
        {
          "sourceVolume": "awseb-logs-nginx-proxy",
          "containerPath": "/var/log/nginx"
        }
      ]
    }
  ]
}
```

此範例組態定義了兩個容器 (前景有 nginx 代理的 PHP 網站)。這兩個容器將會在您 Elastic Beanstalk 環境的每個執行個體上，於 Docker 容器中同時並列執行，存取主機執行個體磁碟區的共用內容 (網站的內容)，該磁碟區也會在此檔案中定義。容器本身是從 Docker Hub 的官方儲存庫中所託管的映像建立的。所產生的環境看起來如下：

![\[Elastic Beanstalk environment with load balancer, auto scaling group, and two instances running Nginx and PHP-FPM.\]](http://docs.aws.amazon.com/zh_tw/elasticbeanstalk/latest/dg/images/aeb-multicontainer-tutorial.png)


組態中所定義的磁碟區，會與您接下來所要建立的內容相符，並隨應用程式來源套件上傳。容器會掛載容器定義 `mountPoints` 區段中的磁碟區，以存取主機上的內容。

如需 `Dockerrun.aws.json` v2 格式及其參數的詳細資訊，請參閱 [容器定義格式](create_deploy_docker_v2config.md#create_deploy_docker_v2config_dockerrun_format)。

## 新增內容
<a name="create_deploy_docker_ecstutorial_code"></a>

接下來，您將會加入 PHP 網站的一些內容 (要顯示給訪客看的內容)，和 nginx 代理的組態檔案。

**php-app/index.php**

```
<h1>Hello World!!!</h1>
<h3>PHP Version <pre><?= phpversion()?></pre></h3>
```

**php-app/static.html**

```
<h1>Hello World!</h1>
<h3>This is a static HTML page.</h3>
```

**proxy/conf.d/default.conf**

```
server {
  listen 80;
  server_name localhost;
  root /var/www/html;
 
  index index.php;
 
  location ~ [^/]\.php(/|$) {
    fastcgi_split_path_info ^(.+?\.php)(/.*)$;
    if (!-f $document_root$fastcgi_script_name) {
      return 404;
    }

    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param PATH_INFO $fastcgi_path_info;
    fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;

    fastcgi_pass php-app:9000;
    fastcgi_index index.php;
  }
}
```

## 部署到 Elastic Beanstalk
<a name="create_deploy_docker_ecstutorial_deploy"></a>

您的應用程式資料夾現在包含下列檔案：

```
├── Dockerrun.aws.json
├── php-app
│   ├── index.php
│   └── static.html
└── proxy
    └── conf.d
        └── default.conf
```

您只需建立 Elastic Beanstalk 環境即可。建立前述檔案和資料夾的 `.zip` 封存檔 (不包括最上層專案資料夾)。若要在 Windows 檔案總管中建立封存檔，請選取專案資料夾的內容，在按一下滑鼠右鍵後選擇 **Send To (傳送對象)**，然後再按一下**Compressed (zipped) Folder (壓縮的 (zipped) 資料夾)** 

**注意**  
如需所需的檔案架構的相關資訊，以及在其他環境中建立封存檔的說明，請參閱[建立 Elastic Beanstalk 應用程式原始碼套件](applications-sourcebundle.md) 

接著，將原始碼套件上傳到 Elastic Beanstalk，然後建立您的環境。針對 **Platform (平台)**，請選取 **Docker (Docker)**。針對**平台分支**，選取**在 64 位元 Amazon Linux 2023 上執行的 ECS**。

**啟動環境 (主控台)**

1. 透過此一預設連結來開啟 Elastic Beanstalk 主控台：[console.aws.amazon.com/elasticbeanstalk/home\$1/newApplication?applicationName=tutorials&environmentType=LoadBalanced](https://console.aws.amazon.com/elasticbeanstalk/home#/newApplication?applicationName=tutorials&environmentType=LoadBalanced)

1. 在 **Platform** (平台)，選取符合您應用程式所使用語言的平台和平台分支，或針對以容器為基礎的應用程式選取 Docker 平台。

1. 在 **Application code (應用程式的程式碼)**，選擇 **Upload your code (上傳您的程式碼)**。

1. 選擇 **Local file (本機檔案)**，選擇 **Choose file (選擇檔案)**，然後開啟原始碼套件。

1. 選擇 **Review and launch (檢閱和啟動)**。

1. 檢閱可用的設定，然後選擇 **Create app (建立應用程式)**。

Elastic Beanstalk 主控台會將您重新導向到新環境的管理儀表板。這個畫面會顯示環境的運作狀態，和 Elastic Beanstalk 服務所輸出的事件。當狀態為綠色 (Green) 時，請按一下環境名稱旁的 URL，來查看您的新網站。

## 連線到容器執行個體
<a name="create_deploy_docker_ecstutorial_connect"></a>

接下來，您會連線到 Elastic Beanstalk 環境中的 Amazon EC2 執行個體，以查看正在運作的項目。

使用 EB CLI 是連線到您環境中執行個體的最簡單方法。若要使用 EB CLI，[請安裝 EB CLI](eb-cli3.md#eb-cli3-install) (如果您尚未安裝)。您也需要使用 Amazon EC2 SSH 金鑰對設定您的環境。使用主控台的[安全組態頁面](using-features.managing.security.md)或 EB CLI [eb init](eb3-init.md) 命令進行此工作。若要連線到環境執行個體，請使用 EB CLI [eb ssh](eb3-ssh.md) 命令。

您已連線到承載您 Docker 容器的 Amazon EC2 執行個體，現在您可以查看運作的狀況。執行 `ls` 中的 `/var/app/current`：

```
[ec2-user@ip-10-0-0-117 ~]$ ls /var/app/current
Dockerrun.aws.json  php-app  proxy
```

此目錄包含原始碼套件中的檔案，您在建立環境時將此套件上傳到 Elastic Beanstalk。

```
[ec2-user@ip-10-0-0-117 ~]$ ls /var/log/containers
nginx-proxy    nginx-proxy-4ba868dbb7f3-stdouterr.log     
php-app        php-app-dcc3b3c8522c-stdouterr.log       rotated
```

容器執行個體上的日誌，就是在此目錄中建立，Elastic Beanstalk 也會存取此目錄來收集日誌。Elastic Beanstalk 會在此目錄中，為每個容器建立磁碟區，您會將此磁碟區掛載到寫入日誌的容器位置。

您也可以利用 `docker ps` 來檢視 Docker，以查看執行中的容器。

```
[ec2-user@ip-10-0-0-117 ~]$ sudo docker ps
CONTAINER ID   IMAGE                            COMMAND                  CREATED         STATUS                  PORTS                               NAMES                                                
4ba868dbb7f3   nginx                            "/docker-entrypoint.…"   4 minutes ago   Up 4 minutes            0.0.0.0:80->80/tcp, :::80->80/tcp   ecs-awseb-Tutorials-env-dc2aywfjwg-1-nginx-proxy-acca84ef87c4aca15400        
dcc3b3c8522c   php:fpm                          "docker-php-entrypoi…"   4 minutes ago   Up 4 minutes            9000/tcp                            ecs-awseb-Tutorials-env-dc2aywfjwg-1-php-app-b8d38ae288b7b09e8101                             
d9367c0baad6   amazon/amazon-ecs-agent:latest   "/agent"                 5 minutes ago   Up 5 minutes (healthy)                                      ecs-agent
```

這會顯示您所部署的兩個執行中的容器，以及統籌部署作業的 Amazon ECS 容器代理程式。

## 檢查 Amazon ECS 容器代理程式
<a name="create_deploy_docker_ecstutorial_connect_inspect"></a>

Elastic Beanstalk 上 ECS 受管 Docker 環境中的 Amazon EC2 執行個體，會在 Docker 容器中執行代理程式程序。此代理程式會連線到 Amazon ECS 服務，以統籌容器的部署作業。這些部署作業會在 Amazon ECS 中以任務的形式執行，而任務是在任務定義檔案中設定的。Elastic Beanstalk 會根據您在原始碼套件中上傳的 `Dockerrun.aws.json`，來建立這些任務定義檔案。

發送 HTTP get 要求到 `http://localhost:51678/v1/metadata`，來查看容器代理程式的狀態：

```
[ec2-user@ip-10-0-0-117 ~]$ curl http://localhost:51678/v1/metadata
{
  "Cluster":"awseb-Tutorials-env-dc2aywfjwg",
  "ContainerInstanceArn":"arn:aws:ecs:us-west-2:123456789012:container-instance/awseb-Tutorials-env-dc2aywfjwg/db7be5215cd74658aacfcb292a6b944f",
  "Version":"Amazon ECS Agent - v1.57.1 (089b7b64)"
}
```

此結構會顯示 Amazon ECS 叢集的名稱，和叢集執行個體 (您所連線的 Amazon EC2 執行個體) 的 ARN ([Amazon Resource Name](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)) 。

如需詳細資訊，請發出 HTTP get 請求到 `http://localhost:51678/v1/tasks`︰

```
[ec2-user@ip-10-0-0-117 ~]$ curl http://localhost:51678/v1/tasks
{
   "Tasks":[
      {
         "Arn":"arn:aws:ecs:us-west-2:123456789012:task/awseb-Tutorials-env-dc2aywfjwg/bbde7ebe1d4e4537ab1336340150a6d6",
         "DesiredStatus":"RUNNING",
         "KnownStatus":"RUNNING",
         "Family":"awseb-Tutorials-env-dc2aywfjwg",
         "Version":"1",
         "Containers":[
            {
               "DockerId":"dcc3b3c8522cb9510b7359689163814c0f1453b36b237204a3fd7a0b445d2ea6",
               "DockerName":"ecs-awseb-Tutorials-env-dc2aywfjwg-1-php-app-b8d38ae288b7b09e8101",
               "Name":"php-app",
               "Volumes":[
                  {
                     "Source":"/var/app/current/php-app",
                     "Destination":"/var/www/html"
                  }
               ]
            },
            {
               "DockerId":"4ba868dbb7f3fb3328b8afeb2cb6cf03e3cb1cdd5b109e470f767d50b2c3e303",
               "DockerName":"ecs-awseb-Tutorials-env-dc2aywfjwg-1-nginx-proxy-acca84ef87c4aca15400",
               "Name":"nginx-proxy",
               "Ports":[
                  {
                     "ContainerPort":80,
                     "Protocol":"tcp",
                     "HostPort":80
                  },
                  {
                     "ContainerPort":80,
                     "Protocol":"tcp",
                     "HostPort":80
                  }
               ],
               "Volumes":[
                  {
                     "Source":"/var/app/current/php-app",
                     "Destination":"/var/www/html"
                  },
                  {
                     "Source":"/var/log/containers/nginx-proxy",
                     "Destination":"/var/log/nginx"
                  },
                  {
                     "Source":"/var/app/current/proxy/conf.d",
                     "Destination":"/etc/nginx/conf.d"
                  }
               ]
            }
         ]
      }
   ]
}
```

此結構描述了一項執行的任務，就是部署這個教學課程的範例專案的兩個 docker 容器。隨即會顯示下列資訊：
+ **KnownStatus** –`RUNNING` 狀態表示容器仍在運作中。
+ **系列** – 任務定義的名稱，此任務定義是 Elastic Beanstalk 利用 `Dockerrun.aws.json` 建立的。
+ **版本**– 任務定義的版本。這會在任務定義檔案每次更新時遞增。
+ **容器** – 關於執行個體上所執行容器的資訊。

Amazon ECS 服務本身提供了更多的資訊，您可以使用 來呼叫此服務 AWS Command Line Interface如需 AWS CLI 搭配 Amazon ECS 使用 的說明，以及 Amazon ECS 的一般相關資訊，請參閱 [Amazon ECS 使用者指南](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ECS_GetStarted.html)。