---
# System prepended metadata

title: 使用 CodePipeline 為 Beanstalk 的 CI/CD solution 時 nginx 出現 413 Request Entity Too Large 問題
tags: [nginx, beanstalk, aws, '413']

---

# 使用 CodePipeline 為 Beanstalk 的 CI/CD solution 時 nginx 出現 413 Request Entity Too Large 問題

[TOC]

###### tags: `aws` `beanstalk` `nginx` `413`

---

## 結論先行

1. 在 `.platform/hooks/postdeploy/` 新增 `proxy.sh` 檔案。

```shell
$ mkdir -p .platform/hooks/postdeploy/
$ vim .platform/hooks/postdeploy/proxy.sh
```

輸入以下內容：

```bash=
#!/bin/sh

cat << EOF > /etc/nginx/conf.d/elasticbeanstalk/proxy.conf
client_body_buffer_size 128M;
client_max_body_size 128M;
EOF

service nginx restart
```

儲存並離開 `vim`。

2. 新增或編輯 `buildspec.yml` 這個檔案。

```shell
$ vim buildspec.yml
```

在此檔案加入以下內容：

```yaml=6
# other content omitted for brevity
artifacts:
  files:
    - .platform/hooks/postdeploy/proxy.sh
```

儲存並離開 `vim`。

3. 上述變更提交至版控後即可。

### 專案結構

```
├─ .platform
│  └─ hooks/
│     └─ postdeploy/
│        └─ proxy.sh
├─ buildspec.yml
└─ (other directories/files omitted for brevity)
```

## 概述

`nginx` 作為 AWS Elastic Beanstalk<SUB>(以下稱 **Beanstalk**)</SUB> 多數 **platforms**<SUP>(平台)</SUP>的 **reverse proxy**<SUP>(反向代理)</SUP>，其默認的配置僅允許 `10 megabytes` 以下的 **request body**，若要提高此上限則須在目標主機<SUB>(**`/etc/nginx/conf.d/elasticbeanstalk/`** 路徑下)</SUB>新增配置檔。

然而官方文件<STRONG style="color:#F00">未</STRONG>提到的是，當專案是透過 [CodePipeline](https://aws.amazon.com/codepipeline/) 作為 CI/CD solution 時，[CodeBuild](https://aws.amazon.com/codebuild/) 並<STRONG style="color:#F00">不會</STRONG>將新增的配置檔<STRONG style="color:#F00">自動打包</STRONG>進去，故須在專案新增 **`buildspec.yml`**。

有關 `buildspec.yml` 的語法規範請參閱[這兒](https://docs.aws.amazon.com/codebuild/latest/userguide/build-spec-ref.html)，而[這兒](https://docs.aws.amazon.com/codebuild/latest/userguide/sample-elastic-beanstalk.html)有範例可循。

### 配置方式會因 platform、甚至是 platform 的版本而異

> :::info
> **Note**
>
> - On Amazon Linux 2 platforms, instead of providing files and commands in `.ebextensions` configuration files, we highly recommend that you use **`Buildfile`**, **`Procfile`**, and **platform hooks** whenever possible to configure and run custom code on your environment instances during instance provisioning. For details about these mechanisms, see [Extending Elastic Beanstalk Linux platforms](https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/platforms-linux-extend.html).
> :::

此 note 記錄的是以 **platform hooks** 為 **Amazon Linux 2** 的解決方案；官方**高度建議**在 **Amazon Linux 2** 下使用 **`Buildfile`**、**`Procfile`** 及 **platform hooks** 等方式[調整或擴展](https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/customize-containers-ec2.html "Customizing software on Linux servers") platform，然而傳統的 Amazon Linux AMI (Amazon Linux 2 **之前**的版本)則是在專案裡<SUB>(`.ebextensions/` 路徑下)</SUB>新增配置檔。

## 調整或擴展 Beanstalk 的 Linux platform

> Platform hooks are specifically designed to extend your environment's platform. These are custom scripts and other executable files that you deploy as part of your application's source code, and Elastic Beanstalk runs during various instance provisioning stages.

Platform hooks 的設計讓我們在部署過程中的不同階段置放程式讓 Beanstalk 執行，以達到調整或擴展目的。

> :::info
> **Note**
>
> Platform hooks aren't supported on Amazon Linux AMI platform versions (preceding Amazon Linux 2).
> :::

再次重申，platform hooks 不支援 Amazon Linux AMI (Amazon Linux 2 *之前*的版本)。

### Application deployment platform hooks

> To provide platform hooks that run during an application deployment, place the files under the **`.platform/hooks`** directory in your source bundle, in one of the following subdirectories.
>
> - **`prebuild`** – Files here run after the Elastic Beanstalk platform engine downloads and extracts the application source bundle, and before it sets up and configures the application and web server.
> The `prebuild` files run after running commands found in the commands section of any configuration file and before running `Buildfile` commands.
>
> - **`predeploy`** – Files here run after the Elastic Beanstalk platform engine sets up and configures the application and web server, and before it deploys them to their final runtime location.
> The `predeploy` files run after running commands found in the `container_commands` section of any configuration file and before running `Procfile` commands.
>
> - **`postdeploy`** – Files here run after the Elastic Beanstalk platform engine deploys the application and proxy server.
> This is the last deployment workflow step.

簡單來說有三個階段：

- **`prebuild`**
Beanstalk 下載並解壓縮 source bundle 之後，設定、配置 application server 及 web server 之前。
:::info
初始工作路徑為 `/var/app/staging/`。
:::

- **`predeploy`**
設定、配置 application server 及 web server 之後，部署到 EC2 instance(s)之前。
:::info
初始工作路徑為 `/var/app/staging/`。
:::

- **`postdeploy`**
部署完 application server 及 proxy server 之後，此為最後一個流程。
:::info
初始工作路徑為 `/var/app/current/`。
:::

目前要解決的問題跟 nginx<SUB>(proxy server)</SUB>有關，我們在 `postdeploy` 設置 platform hook(s)，故專案的檔案系統結構裡新增了 `.platform/hooks/postdeploy/proxy.sh`，檔名不限於 `proxy.sh`，只要在 Linux file system 合法即可，當有多個執行檔時則會按檔名的**字典順序**執行，故在某一階段裡若有執行順序需求，可在檔名前面加上數字，如：`01_proxy.sh`、`02_notify.sh`。

若有自行撰寫的 shell script(s)，別忘了在檔首加上 `#!`，如：

```shell
#!/bin/bash
```

或
```shell
#!/bin/sh
```

並在提交之前：

```shell
$ chmod +x .platform/hooks/postdeploy/proxy.sh
```

使其帶 execute permission。

:::info
platform hooks 會以 `root` 身份執行，故無須在命令前面加上 `sudo`。
:::

## 程式碼的建置規格

---

轉載時請註明出處，謝謝。