

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

# 將 Django 應用程式部署至 Elastic Beanstalk
<a name="create-deploy-python-django"></a>

本教學會演練如何將自動產生的預設 [Django](https://www.djangoproject.com/) 網站部署至執行 Python 的 AWS Elastic Beanstalk 環境。本教學示範說明如何使用 Elastic Beanstalk 環境在雲端託管 Python Web 應用程式。

在本教學中，您將執行下列作業：
+ [設定 Python 虛擬環境並安裝 Django](#python-django-setup-venv)
+ [建立 Django 專案](#python-django-create-app)
+ [針對 Elastic Beanstalk 設定您的 Django 應用程式](#python-django-configure-for-eb) 
+ [使用 EB CLI 部署您的網站](#python-django-deploy) 
+ [更新您的應用程式](#python-django-update-app) 
+ [清除](#python-django-stopping)

## 先決條件
<a name="python-django-prereq"></a>

按照這個教學課程，您應安裝適用 Python 的所有[常見先決條件](python-development-environment.md)，包括下列套件：
+ Python 3.7 或更高版本
+ `pip`
+ `virtualenv`
+ `awsebcli`

教學中會安裝 [Django](https://www.djangoproject.com/) 架構。

**注意**  
要以 EB CLI 建立環境，就必須有[服務角色](concepts-roles-service.md)。您可以在 Elastic Beanstalk 主控台建立環境，以建立服務角色。如果您沒有服務角色，EB CLI 會嘗試在您執行 `eb create` 時為您建立。

## 設定 Python 虛擬環境並安裝 Django
<a name="python-django-setup-venv"></a>

透過 `virtualenv` 建立虛擬環境，並用其安裝 Django 及依存項目。透過虛擬環境，您可清楚分辨應用程式需要哪些套裝服務，以便在執行您應用程式的 Amazon EC2 執行個體上安裝所需套裝服務。

下列步驟示範 Unix 系統和 Windows 必須輸入的命令，以不同的標籤顯示。

**欲設定您的虛擬環境**

1. 建立名為 `eb-virt` 的虛擬環境。

------
#### [ Unix-based systems ]

   ```
   ~$ virtualenv ~/eb-virt
   ```

------
#### [ Windows ]

   ```
   C:\> virtualenv %HOMEPATH%\eb-virt
   ```

------

1. 啟用虛擬環境。

------
#### [ Unix-based systems ]

   ```
   ~$ source ~/eb-virt/bin/activate
   (eb-virt) ~$
   ```

------
#### [ Windows ]

   ```
   C:\>%HOMEPATH%\eb-virt\Scripts\activate
   (eb-virt) C:\>
   ```

------

   您的命令提示字元前方會加上 `(eb-virt)`，表示您正位於虛擬環境中。
**注意**  
其餘說明會顯示您主目錄的 Linux 命令提示字元 `~$`。在 Windows 上，此為 `C:\Users\USERNAME>`，其中 *USERNAME* 是您的 Windows 登入名稱。

1. 使用 `pip` 安裝 Django。

   ```
   (eb-virt)~$ pip install django==2.2
   ```
**注意**  
您安裝的 Django 版本必須與您在 Elastic Beanstalk Python 組態選擇用於部署應用程式的 Python 版本相容。如需部署的資訊，請參閱本主題中的 [使用 EB CLI 部署您的網站](#python-django-deploy)。  
如需目前 Python 平台版本的詳細資訊，請參閱《AWS Elastic Beanstalk 平台文件》**中的 [Python](https://docs.aws.amazon.com/elasticbeanstalk/latest/platforms/platforms-supported.html#platforms-supported.python)。  
如需 Django 版本與 Python 的相容性詳細資訊，請參閱 [What Python version can I use with Django?](https://docs.djangoproject.com/en/3.1/faq/install/#what-python-version-can-i-use-with-django)

1. 若要確認是否已安裝 Django，請輸入以下內容。

   ```
   (eb-virt)~$ pip freeze
   Django==2.2
   ...
   ```

   本命令列出您虛擬環境安裝的所有套件。稍後，使用此命令的輸出設定您的專案，以搭配 Elastic Beanstalk 使用。

## 建立 Django 專案
<a name="python-django-create-app"></a>

現在您已準備就緒，能夠建立 Django 專案並使用虛擬環境執行於您的機器。

**注意**  
本教學使用 Python 隨附的資料庫引擎 SQLite。這個資料庫會和您的專案檔案一同部署。至於生產環境，則建議使用 Amazon Relational Database Service (Amazon RDS)，並將之從您的環境中獨立出來。如需詳細資訊，請參閱[將 Amazon RDS 資料庫執行個體新增至 Python Elastic Beanstalk 環境](create-deploy-python-rds.md)。

**欲產生 Django 應用程式**

1. 啟用您的虛擬環境。

------
#### [ Unix-based systems ]

   ```
   ~$ source ~/eb-virt/bin/activate
   (eb-virt) ~$
   ```

------
#### [ Windows ]

   ```
   C:\>%HOMEPATH%\eb-virt\Scripts\activate
   (eb-virt) C:\>
   ```

------

   您的命令提示字元前方會加上 `(eb-virt)` 前綴，表示您正位於虛擬環境中。
**注意**  
其餘說明會顯示您主目錄的 Linux 命令提示字元 `~$` 以及 Linux 主目錄 `~/`。在 Windows 上，此為 `C:\Users\USERNAME>`，其中 *USERNAME* 是您的 Windows 登入名稱。

1. 使用 `django-admin startproject` 命令建立名為 `ebdjango` 的 Django 專案。

   ```
   (eb-virt)~$ django-admin startproject ebdjango
   ```

   此命令會建立名為 **ebdjango** 的標準 Django 網站，採用下列目錄結構。

   ```
   ~/ebdjango
     |-- ebdjango
     |   |-- __init__.py
     |   |-- settings.py
     |   |-- urls.py
     |   `-- wsgi.py
     `-- manage.py
   ```

1. 使用 `manage.py runserver` 在本機執行您的 Django 網站。

   ```
   (eb-virt) ~$ cd ebdjango
   ```

   ```
   (eb-virt) ~/ebdjango$ python manage.py runserver
   ```

1. 在 Web 瀏覽器中開啟 `http://127.0.0.1:8000/` 以檢視此網站。

1. 檢查伺服器日誌，以查看您請求的輸出。若要停止 Web 伺服器並返回您的虛擬環境，請按 **Ctrl\$1C**。

   ```
   Django version 2.2, using settings 'ebdjango.settings'
   Starting development server at http://127.0.0.1:8000/
   Quit the server with CONTROL-C.
   [07/Sep/2018 20:14:09] "GET / HTTP/1.1" 200 16348
   Ctrl+C
   ```

## 針對 Elastic Beanstalk 設定您的 Django 應用程式
<a name="python-django-configure-for-eb"></a>

現在您的本機已具備採用 Django 的網站，因此您可將其設定為透過 Elastic Beanstalk 進行部署。

根據預設，Elastic Beanstalk 會尋找名為 `application.py` 的檔案，以啟動您的應用程式。因為您建立的 Django 專案中不存在此檔案，所以您需要對您的應用程式環境稍加調整。您也必須設定環境變數，以便載入您的應用程式模組。

**欲針對 Elastic Beanstalk 設定您的網站**

1. 啟用您的虛擬環境。

------
#### [ Unix-based systems ]

   ```
   ~/ebdjango$ source ~/eb-virt/bin/activate
   ```

------
#### [ Windows ]

   ```
   C:\Users\USERNAME\ebdjango>%HOMEPATH%\eb-virt\Scripts\activate
   ```

------

1. 執行 `pip freeze`，然後將輸出儲存至名為 `requirements.txt` 的檔案。

   ```
   (eb-virt) ~/ebdjango$ pip freeze > requirements.txt
   ```

   Elastic Beanstalk 使用 `requirements.txt` 來判斷執行您應用程式的 EC2 執行個體應安裝哪些套件。

1. 建立名為 `.ebextensions` 的目錄。

   ```
   (eb-virt) ~/ebdjango$ mkdir .ebextensions
   ```

1. 在 `.ebextensions` 目錄中，新增具有下列文字的[組態檔案](ebextensions.md) `django.config`。  
**Example \$1/ebdjango/.ebextensions/django.config**  

   ```
   option_settings:
     aws:elasticbeanstalk:container:python:
       WSGIPath: ebdjango.wsgi:application
   ```

   `WSGIPath` 設定會指定 Elastic Beanstalk 用於啟動應用程式的 WSGI 指令碼之位置。
**注意**  
如果您使用的是 Amazon Linux AMI Python 平台版本 (Amazon Linux 2 之前的版本)，請將 `WSGIPath` 的數值替換為 `ebdjango/wsgi.py`。此範例中的數值適用於 Gunicorn WSGI 伺服器，Amazon Linux AMI 平台版本不支援此伺服器。

1. 使用 `deactivate` 命令停用您的虛擬環境。

   ```
   (eb-virt) ~/ebdjango$ deactivate
   ```

   每當需要將套裝服務新增至應用程式，或於本機執行應用程式時，即可重新啟用您的虛擬環境。

## 使用 EB CLI 部署您的網站
<a name="python-django-deploy"></a>

您已新增於 Elastic Beanstalk 部署應用程式所需的所有事物。您的專案目錄現應如下所示。

```
~/ebdjango/
|-- .ebextensions
|   `-- django.config
|-- ebdjango
|   |-- __init__.py
|   |-- settings.py
|   |-- urls.py
|   `-- wsgi.py
|-- db.sqlite3
|-- manage.py
`-- requirements.txt
```

接著，您將建立應用程式環境，並透過 Elastic Beanstalk 部署已設定的應用程式。

部署後，您要立即編輯 Django 的組態，將 Elastic Beanstalk 指派給您應用程式的網域名稱新增至 Django 的 `ALLOWED_HOSTS`。然後，您要重新部署應用程式。這是一個 Django 安全要求，旨在阻擋 HTTP `Host` 標頭攻擊。如需詳細資訊，請參閱[主機標頭驗證](https://docs.djangoproject.com/en/2.2/topics/security/#host-headers-virtual-hosting)。

**欲建立環境並部署您的 Django 應用程式**
**注意**  
本教學使用 EB CLI 做為部署機制，但您亦可使用 Elastic Beanstalk 主控台來部署內含您專案內容的 .zip 檔案。

1. 透過 **eb init** 命令初始化您的 EB CLI 儲存庫。

   ```
   ~/ebdjango$ eb init -p python-3.7 django-tutorial
   Application django-tutorial has been created.
   ```

   此命令會建立名為 `django-tutorial` 的應用程式。這也會設定您的本機儲存庫，使用最新的 Python 3.7 平台版本建立環境。

1. (選用) 再次執行 **eb init** 來設定預設金鑰對，藉此使用 SSH 連接至執行您應用程式的 EC2 執行個體：

   ```
   ~/ebdjango$ eb init
   Do you want to set up SSH for your instances?
   (y/n): y
   Select a keypair.
   1) my-keypair
   2) [ Create new KeyPair ]
   ```

   若您已有金鑰對，請選擇一對，或依照提示建立金鑰對。若未出現提示，或稍後需要變更設定，請執行 **eb init -i**。

1. 使用 **eb create** 建立環境並於其中部署您的應用程式。

   ```
   ~/ebdjango$ eb create django-env
   ```
**注意**  
若您看到了 "service role required" (需要服務角色) 錯誤訊息，請以互動方式執行 `eb create` (無須指定環境名稱)，EB CLI 便會為您建立角色。

   本命令會建立名為 `django-env` 的負載平衡 Elastic Beanstalk 環境。建立環境約需要 5 分鐘。當 Elastic Beanstalk 建立執行應用程式所需要的資源時，它會輸出 EB CLI 轉送至您終端機的資訊訊息。

1. 完成環境建立程序後，請執行 **eb status** 尋找新環境的網域名稱。

   ```
   ~/ebdjango$ eb status
   Environment details for: django-env
     Application name: django-tutorial
     ...
     CNAME: eb-django-app-dev.elasticbeanstalk.com
     ...
   ```

   您環境的網域名稱為 `CNAME` 屬性的數值。

1. 在 `settings.py` 目錄中，開啟檔案 `ebdjango`。找出 `ALLOWED_HOSTS` 設定，然後將您在上個步驟中找到的應用程式網域名稱新增至設定值中。如果您無法找到檔案中的這個設定，請在新行中新增。

   ```
   ...
   ALLOWED_HOSTS = ['eb-django-app-dev.elasticbeanstalk.com']
   ```

1. 儲存檔案，然後執行 **eb deploy** 來部署應用程式。執行 **eb deploy** 時，EB CLI 會封裝您專案目錄的內容，並將其部署至您的環境。

   ```
   ~/ebdjango$ eb deploy
   ```
**注意**  
如果您使用 Git 來處理專案，請參閱[搭配 Git 使用 EB CLI](eb3-cli-git.md)。

1. 完成環境更新程序後，請使用 **eb open** 開啟您的網站。

   ```
   ~/ebdjango$ eb open
   ```

   這會開啟瀏覽器視窗，並使用為應用程式建立的網域名稱。您應該會看到與本機建立和測試相同的 Django 網站。

若未顯示您的應用程式正在執行，或收到錯誤訊息，請參閱[疑難排解部署](troubleshooting.md#troubleshooting-deployments)尋求協助，以判斷錯誤發生的原因。

若您「確實」**看見您的應用程式正在執行，恭喜您，您透過 Elastic Beanstalk 部署的第一個 Django 應用程式已完成！

## 更新您的應用程式
<a name="python-django-update-app"></a>

現在，您已於 Elastic Beanstalk 上執行應用程式，可以更新並重新部署應用程式或其組態，Elastic Beanstalk 會負責更新您的執行個體，並啟動新的應用程式版本。

在此範例中，我們將啟用 Django 管理主控台，並進行數項設定。

### 修改您的網站設定
<a name="python-django-modify-site"></a>

根據預設，您的 Django 網站會使用 UTC 時區顯示時間。您可在 `settings.py` 中指定時區來進行變更。

**欲變更您網站的時區**

1. 在 `settings.py` 中修改 `TIME_ZONE` 設定。  
**Example \$1/ebdjango/ebdjango/settings.py**  

   ```
   ...
   # Internationalization
   LANGUAGE_CODE = 'en-us'
   TIME_ZONE = 'US/Pacific'
   USE_I18N = True
   USE_L10N = True
   USE_TZ = True
   ```

   如需時區清單，請造訪[此頁面](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones)。

1. 將應用程式部署至您的 Elastic Beanstalk 環境。

   ```
   ~/ebdjango/$ eb deploy
   ```

### 建立網站管理員
<a name="python-django-create-admin"></a>

您可以為 Django 應用程式建立網站管理員，從網站直接存取管理主控台。管理員登入詳細資訊安全存放於本機資料庫映像，位於 Django 產生的預設專案中。

**欲建立網站管理員**

1. 初始化您 Django 應用程式的本機資料庫。

   ```
   (eb-virt) ~/ebdjango$ python manage.py migrate
   Operations to perform:
     Apply all migrations: admin, auth, contenttypes, sessions
   Running migrations:
     Applying contenttypes.0001_initial... OK
     Applying auth.0001_initial... OK
     Applying admin.0001_initial... OK
     Applying admin.0002_logentry_remove_auto_add... OK
     Applying admin.0003_logentry_add_action_flag_choices... OK
     Applying contenttypes.0002_remove_content_type_name... OK
     Applying auth.0002_alter_permission_name_max_length... OK
     Applying auth.0003_alter_user_email_max_length... OK
     Applying auth.0004_alter_user_username_opts... OK
     Applying auth.0005_alter_user_last_login_null... OK
     Applying auth.0006_require_contenttypes_0002... OK
     Applying auth.0007_alter_validators_add_error_messages... OK
     Applying auth.0008_alter_user_username_max_length... OK
     Applying auth.0009_alter_user_last_name_max_length... OK
     Applying sessions.0001_initial... OK
   ```

1. 執行 `manage.py createsuperuser` 以建立管理員。

   ```
   (eb-virt) ~/ebdjango$ python manage.py createsuperuser
   Username: admin
   Email address: me@mydomain.com
   Password: ********
   Password (again): ********
   Superuser created successfully.
   ```

1. 若要指示 Django 存放靜態檔案的位置，請在 `settings.py` 中定義 `STATIC_ROOT`。  
**Example \$1/ebdjango/ebdjango/settings.py**  

   ```
   # Static files (CSS, JavaScript, Images)
   # https://docs.djangoproject.com/en/2.2/howto/static-files/
   STATIC_URL = '/static/'
   STATIC_ROOT = 'static'
   ```

1. 執行 `manage.py collectstatic`，將管理員網站的靜態資產 (JavaScript、CSS 和映像) 填入 `static` 目錄。

   ```
   (eb-virt) ~/ebdjango$ python manage.py collectstatic
   119 static files copied to ~/ebdjango/static
   ```

1. 部署您的應用程式。

   ```
   ~/ebdjango$ eb deploy
   ```

1. 在您的瀏覽器中開啟網站，並將 `/admin/` 附加至網站 URL，藉此檢視管理主控台，如下所示。

   ```
   http://djang-env.p33kq46sfh.us-west-2.elasticbeanstalk.com/admin/
   ```  
![\[輸入您在步驟 2 建立的使用者名稱和密碼，即可登入管理主控台。\]](http://docs.aws.amazon.com/zh_tw/elasticbeanstalk/latest/dg/images/eb_django_admin_login.png)

1. 使用您於步驟 2 中設定的使用者名稱和密碼登入。  
![\[以 Elastic Beanstalk 部署的 Django 網站的 Django 管理主控台\]](http://docs.aws.amazon.com/zh_tw/elasticbeanstalk/latest/dg/images/eb_django_admin_console.png)

您可以使用類似於本機更新/測試的程序，之後進行 **eb deploy**。Elastic Beanstalk 會負責更新線上伺服器，因此您能夠專心開發應用程式，不受伺服器管理作業影響！

### 新增資料庫遷移組態檔案
<a name="python-django-migrate-site"></a>

您可以將命令新增至 `.ebextensions` 指令碼，這是更新網站時所執行的指令碼。這可讓您自動產生資料庫遷移。

**欲在部署應用程式時新增遷移步驟**

1. 使用下列內容，建立名為 `db-migrate.config` 的[組態檔案](ebextensions.md)。  
**Example \$1/ebdjango/.ebextensions/db-migrate.config**  

   ```
   container_commands:
     01_migrate:
       command: "source /var/app/venv/*/bin/activate && python3 manage.py migrate"
       leader_only: true
   option_settings:
     aws:elasticbeanstalk:application:environment:
       DJANGO_SETTINGS_MODULE: ebdjango.settings
   ```

   此組態檔案會先在部署過程中啟用伺服器的虛擬環境並執行 `manage.py migrate` 命令，再啟動您的應用程式。由於此命令在啟動應用程式前執行，因此您必須明確設定 `DJANGO_SETTINGS_MODULE` 環境變數 (`wsgi.py` 通常會於啟動時負責此作業)。於命令中指定 `leader_only: true`，可確保當您部署多個執行個體時，該命令僅執行一次。

1. 部署您的應用程式。

   ```
   ~/ebdjango$ eb deploy
   ```

## 清除
<a name="python-django-stopping"></a>

若要在開發工作階段之間節省執行個體時數和其他 AWS 資源，請使用 終止您的 Elastic Beanstalk 環境**eb terminate**。

```
~/ebdjango$ eb terminate django-env
```

此命令會終止環境和其中執行的所有 AWS 資源。但它不會刪除應用程式，因此您隨時能夠再次執行 **eb create**，以同一組態建立更多的環境。

如不再需要範例應用程式，您也可以移除專案資料夾和虛擬環境。

```
~$ rm -rf ~/eb-virt
~$ rm -rf ~/ebdjango
```

## 後續步驟
<a name="python-django-next-steps"></a>

如需 Django 的詳細資訊 (包括更深入的教學)，請參閱[官方文件](https://docs.djangoproject.com/en/2.2/)。

若欲嘗試其他 Python Web 框架，請參閱[將 Flask 應用程式部署至 Elastic Beanstalk](create-deploy-python-flask.md)。