再次部署在 Heroku 的問題紀錄


Posted by estella00911 on 2022-05-22

OUTLINE

  • 目標:部署由 Express.js, ORM 框架 -- Sequelize 串接資料庫所寫成的 RESTful API。
  • 將部署遇到的問題,詳細紀錄下來。

1.情境一:我不小心把 node_modules deploy 到 Heroku 上了

1.1 問題發生的原因

修改 .gitignore 檔案時,把 /node_modules 寫錯了,所以要 git push heroku時,連同 /node_modules 也 push 上 Heroku 了。

1.2 問題

$ heroku logs --tail
...(略)
2022-05-22T23:09:40.062420+00:00 app[web.1]:  Error: /app/node_modules/bcrypt/lib/binding/bcrypt_lib.node: invalid ELF header

1.2 解決問題的過程

參考此篇bcrypt error when deploy on Heroku : invalid ELF header #595,發現可以由以下方法補救:

1.2.1 步驟一:在 .gitignore 上寫上應該被 git 忽略的檔案

// google .gitignore 的 template,並加以修改:
/node_modules
.env
...

1.2.2 步驟二:儲存變更,推到 Heroku 上

$ git rm -r --cached .
$ git add .
$ git commit -m "fixed untracked files"
$ git push heroku

2. 情境二:ERR_INVALID_ARG_TYPE(name, 'string', value);

2.1 問題描述

  • heroku logs --tail
    heroku express deployinternal/validators.js:124 throw new ERR_INVALID_ARG_TYPE(name, 'string', value);
    
    #### 2.2 問題修改
    我發現在 ./models/index.js 裡面有引用 process.env[var_name] 但沒有引入 dotenv library,所以發生了問題,因此在此檔案內加:require("dotenv").config();

3. 情境三:解決了情境二,但是使用 console.log(process.env[var_name],Heroku 仍沒有吃到 .env 的變數

3.1 問題描述

在檔案內印了 process.env 的變數,但 Heroku 在執行時,沒有印出來,應該是沒有吃到 .env 變數。

// console.log('process.env.JWT_EXPIRES_IN', process.env.JWT_EXPIRES_IN)
// console.log('process.env.JWT_SECRET', process.env.JWT_SECRET)

$ heroku logs --tail
2022-05-22T05:56:18.729657+00:00 app[web.1]: Error: secretOrPrivateKey must have a value
2022-05-22T05:56:18.729657+00:00 app[web.1]: process.env.JWT_EXPIRES_IN
process.env.JWT_SECRET

3.2 解決方法:讓 Heroku 吃到 dotenv 的變數

參考此篇 StackOverflow How to set environment variables on Heroku for Node app and connect to the PostgreSQL database?,我發現可以使用 CLI 來設定 config。

$ heroku config // 查詢 Heroku 有哪些環境變數
polar-tor-55391 Config Vars
CLEARDB_DATABASE_URL: mysql://<host>:<pwd>@<host>/<dataBase>?reconnect=true
$ heroku config:set DB_HOST=my_DB // 設定新的環境參數名稱及內容

3.3 方法二:在 Heroku > setting > config Var 上直接新增

這個方法可以直接輸入環境變數名稱及內容,與上述使用 CLI 建立的方法是一樣的。

4. 情境四:如何在 Heroku 上建立 ClearDB MySQL 後該如何連線?

4.1 問題描述

一開始出現了跟資料庫連現有關的問題:

$ heroku logs --tail
2022-05-22T06:22:42.386671+00:00 app[web.1]: Ignoring invalid configuration option passed to Connection: reconnect. This is currently a warning, but in future versions of MySQL2, an error will be thrown if you pass an invalid configuration option to a Connection

4.2 嘗試的方法

在 Heroku 上部署,環境應是 production,此時打開 ./config/config.js:
因為我已經在 Heroku 上建立 ClearDB MySQL 了,Heroku 資料庫連線的基本資訊(username, password, host, database)都已經附在 Heroku > settings > Config Vars 內,所以只要加 use_env_variable: "CLEARDB_DATABASE_URL", 這行,並把其他不需要的連線資訊刪除(如下:username, password, host, database)。

const config = {
  production: {
-   username: "root",
-   password: null,
-   database: "database_test",
-   host: "127.0.0.1",
   dialect: "mysql",
+   use_env_variable: "CLEARDB_DATABASE_URL",
  },
}
module.exports = config;

5. 情境五:為什麼 Primary key -- id 一次跳 10 的倍數?

5.1 問題描述:

以使用者註冊為例,註冊成功,會成功在 database 建立一筆新資料,其中 id 為 PK,但為什麼 id 都是以十的倍數起跳呢?如: 11, 21, 31, 41?
後來參考了這篇 MySQL autoincrement column jumps by 10- why?

6. 情境六:如何在 heroku 上使用 sequelize-cli db:migrate?

6.1 問題描述:

Heroku 使用 clearDB 建立了資料庫,但是有沒有指令可以把之前在 local 的建好的 database table 移到 Heroku 上呢?ㄈ

6.2 方法:

在 Heroku 上 run sequelize 建立 Table 的指令。

$ heroku run npx sequelize-cli db:migrate

另外,可以在部署好時,在 package.json 寫指令,使用 sequelize-cli 指令建立:

// package.json
{
  "scripts": {
+   "db:migrate": "npx sequelize-cli db:migrate",
+   "start": "npm run db:migrate && node index.js"
-   "start": "node index.js"
},
}

#Heroku #Sequelize #RESTful API







Related Posts

AI輔導室|快速完成波浪線條

AI輔導室|快速完成波浪線條

Promise 非同步處理

Promise 非同步處理

HTTP API 串接

HTTP API 串接


Comments