更新於 2024/09/27閱讀時間約 10 分鐘

AWS 部署 | 初始化與創建環境

繼上次的 AWS 註冊與 EB CLI 安裝以及中途跑去學 MySQL 後,總算要開始專案的部署了,廢話不多說,直接開始。

這次要部屬的是之前做過的短網址產生器,我已經在前一篇文章 "MySQL | 專案應用篇" 中把它的資料庫改為 MySQL。接下來所有的操作,請打開終端機,cd 移動到要部署的專案路徑之下。



初始化

初始化指的是 Elastic Beanstalk 項目的初始化,在這裡會需要選擇 AWS 區域、應用程式的平台、配置 AWS 金鑰...等,具體操作如下:

  1. 終端機輸入 eb init,接下來會出現一系列引導操作。
  2. 選擇 AWS 主機區域,選離台灣最近的就對了 (應該是東京 ?)。
  3. 配置 AWS 金鑰。如果不知道自己的 AWS 金鑰在哪裡,點這裡,往下滑會有個存取金鑰區域,那裏有個建立存取金鑰,點下去就對了。
  1. 輸入你的應用程式名稱。
  2. 選擇應用程式平台,比如 Node.js。
  3. 是否選擇 AWS 進行程式碼儲存與版本控制,一般選否啦。
  4. 是否建立 SSH,一般選 Yes 以備不時之需 (選 Yes 會讓你配置 SSH 金鑰)。
  5. 接下來就等跑完啦!



建立環境

這裡指在 Elastic Beanstalk 建立應用程式環境。

  1. eb create
  2. 輸入環境名稱,這裡隨個人配置。
  3. 輸入 DNS CNAME 前綴,可以不填直接按 Enter。
  4. 選擇 load balancer 形式,通常處理 HTTP/HTTPS 的話要選 application。
  5. 是否啟用 Spot Fleet 請求,選否。Spot Fleet 簡單來說是 AWS 的省成本方案,不過省錢的同時也要冒著隨時被 AWS 中斷的風險。
  6. 放著等跑完啦!如果出現下面這張圖就表示成功:
  1. 打開 AWS 網站,前往 Elastic Beanstalk,點選環境,就可以看到剛剛建置的環境啦!如果看到運作狀態亮紅燈,沒關係,那可能是因為還有一些要設定的內容尚未設定。



打包部署

這裡就是把本地的程式碼打包丟到 Elastic Beanstalk 部署啦。

  1. eb deploy,然後等它跑完。
  2. 打開 AWS 網站,前往 S3,點選儲存貯體,然後一層一層往下就可以找到剛剛打包被丟上來的程式碼了。

紅框就是剛剛打包丟上來的程式碼



創建資料庫

現在來到 AWS 網站的 RDS 建立資料庫,這一步的步驟就用截圖記錄了,丟上來都是需要用戶選擇的部分,其他沒丟的選項通通默認基本上不會出錯。

  1. 前往 AWS 的 RDS。
  2. 選擇引擎。

選 MySQL

  1. 選擇範本。

選免費方案

  1. 設定。

自行輸入個體識別符與密碼

  1. 執行個體組態。

記得選最便宜的 micro

  1. 儲存體。

配置儲存改20,取消儲存自動擴展

  1. 連線。

選連接至 EC2,並選擇我們已經建立好的環境

  1. 其他組態。

建立初始資料庫名稱,取消勾選自動備份

  1. 建立資料庫,建立成功會像下面這樣:



建立 .ebextensions/migration.config

接下來需要回到專案之中建立存放 Elastic Beanstalk 環境配置文件的資料夾以及配置環境的指令檔案。

  1. 在專案下新增一個資料夾:.ebextensions。
  2. 在 .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
  1. 到 package.json 加入新的 script 指令:
"dbmigrate": "npx sequelize db:migrate && npx sequelize db:seed:all"

這一步做完會長像下圖這樣:



新增環境變數

  1. 先去 config.json 中把 "production" 修改成下列樣子:
"production": {
"use_env_variable": "PROD_DATABASE_URL",
"operatorsAliases": false
}
  1. 現在回到 AWS 網站的 Elastic Beanstalk,找到組態 → 更新、監控和記錄,點擊編輯。
  1. 找到 Environment properties 進行環境變數的新增。這裡需要新增:
    NODE_ENV = production
    PROD_DATABASE_URL = mysql://admin:password@RDS資料庫連結/prod
    其他環境變數的部分就看專案有什麼放什麼,比如把 .env 裡的東西放上來,或是像這裡 App.js 中有設定 port,那就需要添加一個 PORT 環境變數。
  1. (備註) 關於 RDS 資料庫連結,在剛剛創建資料庫後,點進去找到端點,那個就是:



重新部署

添加和修改了一堆雜七雜八的東西,接下來就是把改過的程式碼重新部署上 AWS。

  1. 重新部署前,先去 package.json 添加下面這一列:
// 請視你的 node 版本更改
"engines": { "node": "^18.17.1" }
  1. 把剛剛所有的修改新增都 git addgit commit
  2. 輸入eb deploy,沒意外的話等等就可以在 AWS 的 Elastic Beanstalk 上看到部署上去的專案了:



Troubleshooting

這裡記錄幾個我在佈署時遇到的問題。

  1. 網域變換:在開發環境中通常會定義伺服器網域是 "localhost:3000",要正式上線通常會購買一個屬於自己的網域,如果像是我一樣單純想用 AWS 佈署以及使用 RDS 資料庫,我們就得接受 AWS 給我們的預設網域,沒辦法,誰叫我沒付錢 XD。
  2. 複製功能在開發環境運作正常,但上線後卻不能用。這是因為 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();
        }
    }



連結與參考

  1. URL Shortener AWS 佈署版
  2. GitHub Repo of URL Shortener
  3. Javascript复制内容到剪贴板,解决navigator.clipboard Cannot read property 'writeText' of undefined
分享至
成為作者繼續創作的動力吧!
© 2024 vocus All rights reserved.