Heroku 部署


0. 環境與專案

0.1 環境

  1. node.js
  2. mac terminal

0.2 專案使用

  1. MVC 架構
  2. Node.js
  3. Express & Sequelize
  4. HTML
  5. SCSS

0.3 架構

 |- README.md
 |- Procfile
 |- node_modules
 |- .env
 |- .gitignore
 |- package.json
 |- package-lock.json
 |- index.js
 |- seeders
 |- scripts
    |- click.js
 |- migrations
 |- config
    |- config.js
 |- models
    |- article.js
    |- user.js
    |- article.js
 |- public
    |- css/
    |- images/
 |- views
    |- ... ejs
 |- controllers
    |- blog.js
    |- user.js

1. 安裝 Heroku(Set up in heroku

$ brew install heroku/brew/heroku
$ heroku -v # 檢查有沒有成功安裝 heroku 
heroku/7.35.0 darwin-x64 node-v12.13.0

2. 檢查其他版本

$ node --version # 檢查有沒有安裝 node.js
v14.16.1
$ npm --version
7.21.0
$ git --version
git version 2.29.2

3. heroku 登入

$ heroku login
›   Warning: heroku update available from 7.35.0 to 7.59.0.
heroku: Press any key to open up the browser to login or q to exit:
Opening browser to https://cli-auth.heroku.com/auth/cli/browse
Logging in... done
Logged in as xxxx@...com

4. Prepare the app

$ git clone https://github.com/heroku/node-js-getting-started.git
$ cd node-js-getting-started
$ ls # 會幫我們建置所需要的 heroku 的預設檔案
Procfile    app.json    package.json    test.js
README.md   index.js    public

5. 修改package.json.gitignore,新增 .envProcfile

如果是複製 Heroku 官網的專案做示範的話($ git clone https://github.com/heroku/node-js-getting-started.git),可以直接跳到 5.2.3 的步驟,從新增跟設置 .env 開始。

5.1 修改package.json:Specify the version of node

跟 heroku 說:此專案使用 node 14.x 的版本 run。

$ vi package.json
{
  "name": "w17_hw1_blog",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
+ "engines": {
+   "node": "14.x"
+ },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "expresss": "0.0.0"
  }
}

5.2 Specifying a start script

參考Preparing a Codebase for Heroku Deployment之後,發現要先設定3. Add a Procfile
寫好 path,讓我們要將 Heroku 跑起來時,會執行哪些 code。

5.2.1 建立 Procfile:Specifying a start script

$ vi Procfile 
# 使用 vi 編輯器,若無該檔案名稱,則自動建立一個新檔案

或者可以使用其他方法新建檔案,然後再在 Procfile 加上:

web: npm start // 等同於 web 跑起來時,執行 node index.js

但現在我們在 package.json 還要加上 scripts: 中和 start 有關的指令,如下:

5.2.2 修改package.json:Specifying a start script

$ vi package.json
{
  "name": "w17_hw1_blog",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
+   "start": "node index.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "engines": {
    "node": "14.x"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "expresss": "0.0.0"
  }
}

5.2.3 新增 .env

在專案資料夾的根目錄下新增 .env

$ pwd
xxx/node-js-getting-started
$ vi .env # 在此我使用 vi 編輯器,如果開啟一個沒有該名稱的檔案時,會直接新建一個檔案

編輯 .env如下:

DB_HOST=localhost
DB_USERNAME=alice
DB_PASSWORD=alice
PORT=5001
DB_DATABASE=blog

SESSION_SECRET=keyboard cat

5.2.4 修改 ./index.js 的 PORT 設定

在 heroku 的 port 需要使用 process.env.PORT 環境變數。 開啟./index.js` 修改:
使用環境變數前,要先下載一個 npm modules —— dotenv

$ npm install --save dotenv
+  const dotenv = require('dotenv').config() # 引用環境變數的套件
   let PORT = process.env.PORT;
+  if (PORT == null || PORT == "") {
+    PORT = 8000;
+ }

如果 process.env.PORT 不存在,或是空字串,就給一個 port = 8000
有了這個,我在執行 heroku local web 才檢查到我的 port 是 null 或空,一檢查 .env 才發現我的 PORT 變數名稱為 DB_PORT,跟 ./index.js 使用的 process.env.PORT 名稱不一樣,難怪沒找到!

6. heroku create

此時只有準備好 web 跑起來的路徑,以及最初始的專案資料夾,此時要先 create heroku server:

$ heroku create
/
/node_modules
 ›   Warning: heroku update available from 7.35.0 to 7.59.0.
Creating app... done, ⬢ frozen-springs-86838
https://frozen-springs-86838.herokuapp.com/ | https://git.heroku.com/frozen-springs-86838.git

此時可以查詢一下 git remote -v

$ git remote -v

origin  https://github.com/heroku/node-js-getting-started.git (fetch)
origin  https://github.com/heroku/node-js-getting-started.git (push)

發現只有剛剛 clone 專案的來源 URL,可以先使用 git remote remove origin 把 clone 的專案刪除。

$ git remote remove origin
$ git remote -v
heroku  https://git.heroku.com/frozen-springs-86838.git (fetch)
heroku  https://git.heroku.com/frozen-springs-86838.git (push)

如果刪除了原本的 origin remote repository,再 git remote -v 還是沒有連結到剛剛新增的 remote repository(frozen-springs-86838)
就要自己央將本地專案資料夾連結到我們剛建立的遠端 git repository(frozen-springs-86838),要自己加上去可以打以下指令:

$ git remote add heroku https://git.heroku.com/frozen-springs-86838.git
# 加入名字叫做 heroku 的遠端 git repository

再來檢查一下遠端 git repository:

$ git remote -v
Jean-Lu-2:node-js-getting-started jeanlu$ git remote -v
heroku  https://git.heroku.com/frozen-springs-86838.git (fetch)
heroku  https://git.heroku.com/frozen-springs-86838.git (push)

參考Preparing a Codebase for Heroku Deployment之後,發現要先設定4. Listen on the correct port
先前設定 web 跑起來時,要執行 node index.js,現在就打開 ./index.js

跳過 scale the app

6. Declare app dependencies

$ npm install

安裝好從 package.json 得知所需要的 npm modules 後,會產生 package-lock.json

Once dependencies are installed, you will be ready to run your app locally. You’ll notice that a package-lock.json file is generated when npm install is run.

7. Run the app locally

在本地跑跑看 app:
然後依照要求點開:http://localhost:8000

// @ ./index.js
+  const dotenv = require('dotenv').config() # 引用環境變數的套件
   let PORT = process.env.PORT; # 假設在環境變數(.env)設 PORT = 5000
+  if (PORT == null || PORT == "") {
+    PORT = 8000;
+ }

如果我在 .env 檔案設定環境變數中的 PORT 變數為 5000,但是她在 heroku local web 網頁在本地端跑起來的 PORT 為 8000 時,就可以發現並沒有抓到 process.env.PORT,就要 debug 一下是哪裡出錯:

  1. 有可能是在 ./index.js 忘記引入 dotenv npm modules
  2. .env 設的變數名稱(如:port = 5000)與在 ./index.js 引用的環境變數(如:process.env.PORT)不相符
  3. 沒有下載 dotenv 套件。
$ heroku local web # 在 local 端讓網頁跑起來。
 ›   Warning: heroku update available from 7.35.0 to 7.59.0.
[OKAY] Loaded ENV .env File as KEY=VALUE Format
14:17:39 web.1   |  > node-js-getting-started@0.3.0 start
14:17:39 web.1   |  > node index.js
14:17:40 web.1   |  Listening on 5000

若要停止 app 執行,可以按 Ctrl + C
現在能跑的是從 Heroku 複製下來的專案資料夾,如果想要在本地做更改,再放上去的話,要前往下一個步驟:

8. Push local changes:push 至 Heroku

In this step you’ll learn how to propagate a local change to the application through to Heroku. As an example, you’ll modify the application to add an additional dependency and the code to use it.

在這個步驟,我們要學怎麼修改本地的檔案,有了更改的檔案,我們要學習怎麼放到 Heroku 上。

8.1 修改本地檔案

./index.js 上多一個 cool-ascii-faces 套件。

$ npm install --save cool-ascii-faces
added 10 packages, and audited 154 packages in 3s

38 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

會在 package.json 增加 dependencies 欄位——cool-ascii-faces

8.2 修改 ./index.js

新增兩行,如下(+ 行數):

  const dotenv = require('dotenv').config()
+ const cool = require('cool-ascii-faces');
  const express = require('express')
  const path = require('path')
  const PORT = process.env.PORT || 5000

  express()
    .use(express.static(path.join(__dirname, 'public')))
    .set('views', path.join(__dirname, 'views'))
    .set('view engine', 'ejs')
    .get('/', (req, res) => res.render('pages/index'))
+   .get('/cool', (req, res) => res.send(cool()))
    .listen(PORT, () => console.log(`Listening on ${ PORT }`))

新增好了,再試試看將應用程序(app)跑在 local 端

$ npm install

up to date, audited 154 packages in 885ms

38 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

在本地 run 網頁:

$ npm start

> node-js-getting-started@0.3.0 start
> node index.js

Listening on 5000

在 local 端執行應用程序後,進入 http://localhost:5000/cool 可以看見以下網頁:

Now deploy. Almost every deploy to Heroku follows this same pattern. First, add the modified files to the local git repository:

但是現在這樣只是在 local 端,還要改過後的檔案 delply 到 Heroku 上。

8.3 deploy to Heroku

修改好檔案,要將改好的放到 Heroku 要執行以下步驟:

$ git status # 可以先查詢一下檔案的 git 狀態
$ git add .
$ git commit -m "Add cool face API"
$ git push heroku main # push 至 Heroku 
$ heroku open cool
...
...
...
remote: -----> Launching...
remote:        Released v3
remote:        https://fathomless-tor-56396.herokuapp.com/ deployed to Heroku
remote:
remote: Verifying deploy... done.
To https://git.heroku.com/fathomless-tor-56396.git
 * [new branch]      main -> main
Jean-Lu-2:node-js-getting-started jeanlu$ heroku open cool
 ›   Warning: heroku update available from 7.35.0 to 7.59.0.

若要修改該處在分支位置的名稱,可以使用此指令 git branch -m <new-name>

$ git branch -v # 檢查分支名稱
* main b918f2b 1st test commit # 目前處於 main branch!
$ git branch -m master # 修改當前分支名稱,並命為新名稱:master
* master b918f2b 1st test commit

打開後,看到不一樣的臉!

小記: heroku open cool 好像是會直接打開 ./cool 的路徑。

到這邊學完怎麼從本地端 push 上去到 heroku 端,就可以來將自己的專案檔案s 放進去了!

補充:scale the app
讓在 deploy 的主機數量為 1。

9. 複製自己的專案,並放進去

也可以把先前 clone 的專案資料夾(node-js-getting-started)用不到的檔案如 app.jsontest.js 刪掉。
然後自己手動(可以在電腦的視窗複製)複製整個自己的專案資料夾,但不複製 node_modules,因為這個資料夾檔案太大。
另外,如果是有一些隱藏檔案,在電腦的是窗看不見,如 .gitignore.env 建議可以開啟 Linux ,移動到自己的專案資料夾使用 $ cp <檔名> <複製後的目的地路徑> 直接複製過去會比較好。
例如:
目標 heroku 資料夾:

$ pwd
xxxxx/heroku/frozen-springs-86838_w17_restaurant

處在原專案資料夾,要複製隱藏檔案的方法:

$ pwd
xxxxx/homeworks/week17/hw1 # 自己專案資料夾的檔案路徑
$ cp .env xxxxx/heroku/frozen-springs-86838_w17_restaurant
# 建議複製到的目的地路徑為「絕對路徑」:xxxxx/heroku/frozen-springs-86838_w17_restaurant
# 絕對路徑可以在目的地資料夾使用 `pwd` 來查詢目前所在的檔案絕對路徑
# 相對路徑也可,怕容易出錯!

都複製搬移好自己要的專案資料夾後,可以 ls 看一下檔案目錄對不對:

$ ls
Procfile        controllers     node_modules        scripts
README.md       index.js        package-lock.json   seeders
app.json        migrations      package.json        test.js
config          models          public          views

這只是搬移,但我們剛剛沒有搬移檔案很大的 node_modules 所以要使用 npm install 下載專案所需要的 modules

$ npm install # 下載該專案所需要的 npm modules

然後我們剛剛想要把自己的專案架在 heroku 上,所以搬移了自己的專案,也就是在本地端有修改檔案,所以要再 push 一次到 Heroku。

$ git add .
$ git commit -m '1st'
$ git push heroku main # 看主分支名稱是 master or main 自己調整

推上去 heroku 之後,來跑跑看:

$ heroku open
$ heroku logs --tail

發現使用 heroku logs --tails 發現一些錯誤:

$ heroku open
$ heroku logs --tail
2021-09-06T03:36:57.000000+00:00 app[api]: Build succeeded
2021-09-06T03:36:58.032111+00:00 heroku[web.1]: Starting process with command `npm start`
2021-09-06T03:36:59.875583+00:00 app[web.1]:
2021-09-06T03:36:59.875594+00:00 app[web.1]: > w17_hw1_blog@1.0.0 start /app
2021-09-06T03:36:59.875594+00:00 app[web.1]: > node index.js
2021-09-06T03:36:59.875594+00:00 app[web.1]:
2021-09-06T03:37:00.319433+00:00 app[web.1]: Mon, 06 Sep 2021 03:37:00 GMT body-parser deprecated undefined extended: provide extended option at index.js:23:20
2021-09-06T03:37:00.320519+00:00 app[web.1]: Mon, 06 Sep 2021 03:37:00 GMT express-session deprecated req.secret; provide secret option at index.js:25:9
2021-09-06T03:37:00.320942+00:00 app[web.1]: Warning: connect.session() MemoryStore is not
2021-09-06T03:37:00.320944+00:00 app[web.1]: designed for a production environment, as it will leak
2021-09-06T03:37:00.320944+00:00 app[web.1]: memory, and will not scale past a single process.
2021-09-06T03:37:00.324135+00:00 app[web.1]: Example app listening at http://localhost:37243
2021-09-06T03:37:00.655626+00:00 heroku[web.1]: State changed from starting to up
DB_HOST=localhost
2021-09-06T03:37:01.898454+00:00 heroku[router]: at=info method=GET path="/" host=frozen-springs-86838.herokuapp.com request_id=ba7d05ba-09e5-4496-b411-43edbc613d7e fwd="36.225.226.38" dyno=web.1 connect=0ms service=9ms status=500 bytes=404 protocol=https
2021-09-06T03:37:01.900310+00:00 app[web.1]: Error: secret option required for sessions
2021-09-06T03:37:01.900342+00:00 app[web.1]: at session (/app/node_modules/express-session/index.js:200:12)
2021-09-06T03:37:01.900344+00:00 app[web.1]: at Layer.handle [as handle_request] (/app/node_modules/express/lib/router/layer.js:95:5)

發現有幾條錯誤:

  1. 問題一:和 body-parser 有關
Mon, 06 Sep 2021 03:37:00 GMT body-parser deprecated undefined extended: provide extended option at index.js:23:20

google 到的express throws error as 'body-parser deprecated undefined extended'
修改 ./index.js

- app.use(express.urlencoded())
+ app.use(express.urlencoded({ extended: true }))
  1. express-session deprecated
Mon, 06 Sep 2021 03:37:00 GMT express-session deprecated req.secret; provide secret option at index.js:25:9

google 到的Node JS session error: express-session deprecated
修改 ./index.js

+ let SESSION_SECRET = process.env.SESSION_SECRET
+ if (SESSION_SECRET == null || SESSION_SECRET == "") {
+   SESSION_SECRET = 'keyboard cat'
+ }
+ app.set('trust proxy', 1) // trust first proxy
  app.use(session({
+   secret: SESSION_SECRET,
-   secret: process.env.SESSION_SECRET,
+   resave: true,  // original false
-   resave: flase,
    saveUninitialized: true,
    cookie: { maxAge: 60000 }
  }))
  1. memory leak
2021-09-06T03:37:00.320942+00:00 app[web.1]: Warning: connect.session() MemoryStore is not
2021-09-06T03:37:00.320944+00:00 app[web.1]: designed for a production environment, as it will leak
2021-09-06T03:37:00.320944+00:00 app[web.1]: memory, and will not scale past a single process.
2021-09-06T03:37:00.324135+00:00 app[web.1]: Example app listening at http://localhost:37243

發現有 memory leak 的情形
後來 google 資料,查到

12
This module was designed to deal with the memory leak issue.https://www.npmjs.com/package/session-memory-store
The accepted answer may be fine. However, since this question shows up high in the list of search results I figured I would include this in case it helps anyone else.
Share
Improve this answer Follow
answered Sep 22 '16 at 11:31

npm i session-memory-store
npm install --save cookie-parser

修改與新增 index.js
leak memory 參考session-memory-store
new memoryStore 參考How to access express.session.MemoryStore via socket.io objects?

+ const cookieParser = require('cookie-parser');
+ const MemoryStore = require('session-memory-store')(session);

+ app.use(cookieParser()); // 0906
- app.set('trust proxy', 1) // trust first proxy
  app.use(session({
    secret: SESSION_SECRET,
    resave: true,  // original false
    saveUninitialized: true,
    cookie: { 
      maxAge: 60000,
+     secure: true
    },
+   store: new MemoryStore()
}))

修改完上述的三個問題後,heroku logs -t 變成以下:

2021-09-06T07:39:25.000000+00:00 app[api]: Build succeeded
2021-09-06T07:39:25.206542+00:00 heroku[web.1]: Stopping all processes with SIGTERM
2021-09-06T07:39:25.293408+00:00 heroku[web.1]: Process exited with status 143
2021-09-06T07:39:26.997723+00:00 heroku[web.1]: Starting process with command `npm start`
2021-09-06T07:39:29.028250+00:00 app[web.1]:
2021-09-06T07:39:29.028263+00:00 app[web.1]: > w17_hw1_blog@1.0.0 start /app
2021-09-06T07:39:29.028263+00:00 app[web.1]: > node index.js
2021-09-06T07:39:29.028264+00:00 app[web.1]:
2021-09-06T07:39:29.392196+00:00 app[web.1]: Example app listening at http://localhost:25433
2021-09-06T07:39:30.673511+00:00 heroku[web.1]: State changed from starting to up

2021-09-06T07:40:28.150297+00:00 app[web.1]: (node:22) UnhandledPromiseRejectionWarning: SequelizeConnectionRefusedError: connect ECONNREFUSED 127.0.0.1:3306

接下來試試看下一步:設置資料庫

10. 資料庫設置

連不到資料庫,所以出現錯誤

2021-09-06T07:57:47.097707+00:00 app[web.1]: (node:22) UnhandledPromiseRejectionWarning: SequelizeConnectionRefusedError: connect ECONNREFUSED 127.0.0.1:3306
2021-09-06T07:57:47.097722+00:00 app[web.1]: at ConnectionManager.connect (/app/node_modules/sequelize/lib/dialects/mysql/connection-manager.js:116:17)

10.1 Provisioning the shared MySQL add-on

$ heroku addons:create cleardb:ignite
 ›   Warning: heroku update available from 7.35.0 to 7.59.0.
Creating cleardb:ignite on ⬢ frozen-springs-86838... free
Created cleardb-solid-88544 as CLEARDB_DATABASE_URL
Use heroku addons:docs cleardb to view documentation

可以上去 heroku 後台的 setting 查找 CLEARDB_DATABASE_URL

創了 heroku add.on(類似 plugin),現在要開始設定一些有關於連結資料庫的修改:

  1. ./config/config.js
    要怎麼把連結資料庫的帳密、data table 放到連線資料庫的檔案呢,但是又不想讓他暴露在被盜用的風險(明碼存在檔案裡,並 push 上 remote repository)?
    那就要使用環境變數,那要怎麼使用環境變數呢?
    答案可以從 ./models/index.js 中尋找:
    ./models/index.js 是 seqeulize-cli 自動幫我們產生的檔案。
const fs = require('fs')
const path = require('path')
const Sequelize = require('sequelize')

const basename = path.basename(__filename)
const env = process.env.NODE_ENV || 'development' 
const config = require(`${__dirname}/../config/config.js`)[env]
const db = {}

let sequelize
if (config.use_env_variable) {
  sequelize = new Sequelize(process.env[config.use_env_variable], config)
} else {
  sequelize = new Sequelize(config.database, config.username, config.password, config)
}

fs
  .readdirSync(__dirname)
  .filter((file) => (file.indexOf('.') !== 0) && (file !== basename) && (file.slice(-3) === '.js'))
  .forEach((file) => {
    const model = require(path.join(__dirname, file))(sequelize, Sequelize.DataTypes)
    db[model.name] = model
  })

一行一行解釋:

const env = process.env.NODE_ENV || 'development'

這個 process.env.NODE_ENV 中的 NODE_ENV 就是在 node.js 環境提供的環境變數,如果沒有該變數,就會使用 developement 的環境。
然後 process.env.NODE_ENV 也要手動調整,如果環境是 production,會有一些優化。


const config = require(`${__dirname}/../config/config.js`)[env]

會讀取 config.js,去讀取 env,再去載入相關的 env 設定檔。然後現在應該是處於 production 環境應該會去採用這邊的設定檔(有環境分為 developementtestproduction)。


if (config.use_env_variable) {
  sequelize = new Sequelize(process.env[config.use_env_variable], config)

如果 config.use_env_variabletrue(有內容時),在初始化 sequelize 時,就會使用 config.use_env_variable 提供的變數。
所以接著就來試著改一下 ./config/config.js 的檔案內容:
其中 CLEARDB_DATABASE_URL 為 heroku 上面的名稱。

  production: {
     username: 'root',
     password: null,
     database: 'database_production',
     host: '127.0.0.1',
     dialect: 'mysql',
+    use_env_variable: "CLEARDB_DATABASE_URL"
   }

結合 ./models/index.js./config/config.js
程式 run 到 ./models/index.js 的 cofig 變數時,會讀取 config.js,若在 production 時,下面的 if (config.use_env_variable) 存在的話,就會 sequelize = new Sequelize(process.env[config.use_env_variable], config) 去初始化 sequelize 時,就會去使用 process.env[config.use_env_variable] 提供的資料,現在試著將 use_env_variable: "CLEARDB_DATABASE_URL" 加在 ./config/config.jsproduction 上(如上 code)。

執行過程:
程式 run 到 ./models/index.js 的 cofig 變數時,會讀取 config.js,然後執行到 if (config.use_env_variable) 時,這個 config.use_env_variable 會等於字串 CLEARDB_DATABASE_URL ,然後就會去載入 process.env[CLEARDB_DATABASE_URL],就會把這個 URL 給載進來,這個 URL 通常都包含主機、帳號、密碼,加上這個(use_env_variable: "CLEARDB_DATABASE_URL")應該就可以連到資料庫。
修改了本地的檔案,需要再來

$ git add .
$ git commit -m 'connect to DB'
$ git push heroku main
$ heroku open
$ heroku logs -t
2021-09-06T08:09:24.760531+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
2021-09-06T08:09:24.841117+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
2021-09-06T08:09:24.851397+00:00 app[web.1]: (node:22) [SEQUELIZE0006] DeprecationWarning: This database engine version is not supported, please update your database server. More information https://github.com/sequelize/sequelize/blob/main/ENGINE.md
2021-09-06T08:09:24.851399+00:00 app[web.1]: (Use `node --trace-deprecation ...` to show where the warning was created)
2021-09-06T08:09:24.863640+00:00 app[web.1]: Executing (default): SELECT `Article`.`id`, `Article`.`title`, `Article`.`category`, `Article`.`content`, `Article`.`is_deleted`, `Article`.`createdAt`, `Article`.`updatedAt`, `Article`.`UserId`, `User`.`id` AS `User.id`, `User`.`username` AS `User.username`, `User`.`password` AS `User.password`, `User`.`createdAt` AS `User.createdAt`, `User`.`updatedAt` AS `User.updatedAt` FROM `Articles` AS `Article` LEFT OUTER JOIN `Users` AS `User` ON `Article`.`UserId` = `User`.`id` WHERE `Article`.`is_deleted` IS NULL ORDER BY `Article`.`id` DESC;
2021-09-06T08:09:24.871462+00:00 app[web.1]: (node:22) UnhandledPromiseRejectionWarning: SequelizeDatabaseError: Table 'heroku_ca617c81cd1c190.articles' doesn't exist
2021-09-06T08:09:24.871464+00:00 app[web.1]: at Query.formatError (/app/node_modules/sequelize/lib/dialects/mysql/query.js:265:16)

有好多個錯誤,一個一個看:

  1. warning
2021-09-06T08:09:24.760531+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
2021-09-06T08:09:24.841117+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
  1. This database engine version is not supported
2021-09-06T08:09:24.851397+00:00 app[web.1]: (node:22) [SEQUELIZE0006] DeprecationWarning: This database engine version is not supported, please update your database server. More information https://github.com/sequelize/sequelize/blob/main/ENGINE.md
  1. 遠端的 DB ,沒有這個 table
2021-09-06T08:09:24.871462+00:00 app[web.1]: (node:22) UnhandledPromiseRejectionWarning: SequelizeDatabaseError: Table 'heroku_ca617c81cd1c190.articles' doesn't exist

解決方法:
複習一下,先前使用 sequelize-cli 建立的 db table,放在 ./migrations/ 裡面,所以要先執行 db:migrate,就要在 package.jsonscripts 增加:

   "scripts": {
+   "db:migrate": "npx sequelize db:migrate",
+   "start": "npm run db:migrate && node index.js",
-   "start": "node index.js",
-   "test": "echo \"Error: no test specified\" && exit 1"
  },

另外,要教怎麼看這套資料庫裡的資料:
開啟 heroku > frozen-springs-86838 > settings > Config Vars 裡面有:

CLEARDB_DATABASE_URL:
mysql://b71acsdcsdcsce:1bcecewwew56@us-cdbr-east-04.cleardb.com/heroku_0322qqqwwqwqwq8d?reconnect=true (假設長這樣)
  • 帳號:b71acsdcsdcsce
  • 密碼:1bcecewwew56
  • host:us-cdbr-east-04.cleardb.com
  • database:heroku_0322qqqwwqwqwq8d

部署成功!

參考:

  1. Getting Started on Heroku with Node.js
  2. Preparing a Codebase for Heroku Deployment
#Heroku #Express #Blog #MySQL #Sequelize






你可能感興趣的文章

[python] 關於python三兩事 - class,  __init__,   __call__

[python] 關於python三兩事 - class, __init__, __call__

Go 起手式之二

Go 起手式之二

迭代陣列 forEach, for of, for in, map

迭代陣列 forEach, for of, for in, map






留言討論