繼上次的 AWS 註冊與 EB CLI 安裝以及中途跑去學 MySQL 後,總算要開始專案的部署了,廢話不多說,直接開始。
這次要部屬的是之前做過的短網址產生器,我已經在前一篇文章 "MySQL | 專案應用篇" 中把它的資料庫改為 MySQL。接下來所有的操作,請打開終端機,cd 移動到要部署的專案路徑之下。
初始化
初始化指的是 Elastic Beanstalk 項目的初始化,在這裡會需要選擇 AWS 區域、應用程式的平台、配置 AWS 金鑰...等,具體操作如下:
- 終端機輸入
eb init
,接下來會出現一系列引導操作。 - 選擇 AWS 主機區域,選離台灣最近的就對了 (應該是東京 ?)。
- 配置 AWS 金鑰。如果不知道自己的 AWS 金鑰在哪裡,點這裡,往下滑會有個存取金鑰區域,那裏有個建立存取金鑰,點下去就對了。

- 輸入你的應用程式名稱。
- 選擇應用程式平台,比如 Node.js。
- 是否選擇 AWS 進行程式碼儲存與版本控制,一般選否啦。
- 是否建立 SSH,一般選 Yes 以備不時之需 (選 Yes 會讓你配置 SSH 金鑰)。
- 接下來就等跑完啦!
建立環境
這裡指在 Elastic Beanstalk 建立應用程式環境。
eb create
- 輸入環境名稱,這裡隨個人配置。
- 輸入 DNS CNAME 前綴,可以不填直接按 Enter。
- 選擇 load balancer 形式,通常處理 HTTP/HTTPS 的話要選 application。
- 是否啟用 Spot Fleet 請求,選否。Spot Fleet 簡單來說是 AWS 的省成本方案,不過省錢的同時也要冒著隨時被 AWS 中斷的風險。
- 放著等跑完啦!如果出現下面這張圖就表示成功:

- 打開 AWS 網站,前往 Elastic Beanstalk,點選環境,就可以看到剛剛建置的環境啦!如果看到運作狀態亮紅燈,沒關係,那可能是因為還有一些要設定的內容尚未設定。

打包部署
這裡就是把本地的程式碼打包丟到 Elastic Beanstalk 部署啦。
eb deploy
,然後等它跑完。- 打開 AWS 網站,前往 S3,點選儲存貯體,然後一層一層往下就可以找到剛剛打包被丟上來的程式碼了。

紅框就是剛剛打包丟上來的程式碼
創建資料庫
現在來到 AWS 網站的 RDS 建立資料庫,這一步的步驟就用截圖記錄了,丟上來都是需要用戶選擇的部分,其他沒丟的選項通通默認基本上不會出錯。
- 前往 AWS 的 RDS。
- 選擇引擎。

選 MySQL
- 選擇範本。

選免費方案
- 設定。

自行輸入個體識別符與密碼
- 執行個體組態。

記得選最便宜的 micro
- 儲存體。

配置儲存改20,取消儲存自動擴展
- 連線。

選連接至 EC2,並選擇我們已經建立好的環境
- 其他組態。

建立初始資料庫名稱,取消勾選自動備份
- 建立資料庫,建立成功會像下面這樣:

建立 .ebextensions/migration.config
接下來需要回到專案之中建立存放 Elastic Beanstalk 環境配置文件的資料夾以及配置環境的指令檔案。
- 在專案下新增一個資料夾:.ebextensions。
- 在 .ebextensions 下建立一個檔案:migration.config。貼上下面這段,這裡要嚴格注意空格和縮排,不然後續部署會出錯:
option_settings:
aws:elasticbeanstalk:application:environment:
NODE_ENV: production
container_commands:
01_schema_migrate:
command: "./node_modules/.bin/sequelize db:migrate"
leader_only: true
// 如果你的專案需要建立種子資料可以加下面這一段
02_seeder_migrate:
command: "./node_modules/.bin/sequelize db:seed:all"
leader_only: true
- 到 package.json 加入新的 script 指令:
"dbmigrate": "npx sequelize db:migrate && npx sequelize db:seed:all"
這一步做完會長像下圖這樣:

新增環境變數
- 先去 config.json 中把 "production" 修改成下列樣子:
"production": {
"use_env_variable": "PROD_DATABASE_URL",
"operatorsAliases": false
}
- 現在回到 AWS 網站的 Elastic Beanstalk,找到組態 → 更新、監控和記錄,點擊編輯。

- 找到 Environment properties 進行環境變數的新增。這裡需要新增:
.NODE_ENV = production
.PROD_DATABASE_URL = mysql://admin:password@RDS資料庫連結/prod
其他環境變數的部分就看專案有什麼放什麼,比如把 .env 裡的東西放上來,或是像這裡 App.js 中有設定 port,那就需要添加一個 PORT 環境變數。

- (備註) 關於 RDS 資料庫連結,在剛剛創建資料庫後,點進去找到端點,那個就是:

重新部署
添加和修改了一堆雜七雜八的東西,接下來就是把改過的程式碼重新部署上 AWS。
- 重新部署前,先去 package.json 添加下面這一列:
// 請視你的 node 版本更改
"engines": { "node": "^18.17.1" }

- 把剛剛所有的修改新增都
git add
和git commit
。 - 輸入eb deploy,沒意外的話等等就可以在 AWS 的 Elastic Beanstalk 上看到部署上去的專案了:

Troubleshooting
這裡記錄幾個我在佈署時遇到的問題。
- 網域變換:在開發環境中通常會定義伺服器網域是 "localhost:3000",要正式上線通常會購買一個屬於自己的網域,如果像是我一樣單純想用 AWS 佈署以及使用 RDS 資料庫,我們就得接受 AWS 給我們的預設網域,沒辦法,誰叫我沒付錢 XD。
- 複製功能在開發環境運作正常,但上線後卻不能用。這是因為 AWS 給我們的預設網域其實會被算是一個 "不安全的網域",
navigator.clipboard
會因此被瀏覽器禁用。
那什麼算是安全的網域?https、localhost 那些都是,這就是為什麼在開發時一切都運作正常,因為我們的網域是 localhost:3000 啊!
針對複製功能,解決方法有兩個,一個當然是搞個 https 協議,實際上也推薦這麼做啦,但我只是一個小網站,乾脆就直接改複製功能囉!
function copyText() {
const content = document.getElementById('shorter-url');
if (navigator.clipboard && window.isSecureContext) {
navigator.clipboard.writeText(content.innerText)
.then(() => alert('Copied!'))
.catch(err => console.error(err));
} else {
let textArea = document.createElement("textarea");
textArea.value = content.innerText;
textArea.style.position = "absolute";
textArea.style.opacity = 0;
textArea.style.left = "-999999px";
textArea.style.top = "-999999px";
document.body.appendChild(textArea);
textArea.focus();
textArea.select();
document.execCommand('copy') ? alert('Copied!') : console.error('Copy failed');
textArea.remove();
}
}