Node.js + MySQL 部署 Heroku
By: 集點送紅利
Tags: MySQL, Nodejs, Heroku

部署

我們會以上一篇聊天室專案做範例，專案資料夾目前長這樣：

專案資料夾

Git Ignore

在 Git 上傳前需要做的一件重大事。

專案裡有個 node_modules 資料夾是不需要上傳的，因為他容量較大，一般來說 Heroku 會自動根據 package.json 檔去安裝所需套件。因此我們需要先創建好 .gitignore 檔案並新增忽略規則。

.gitignore 新增忽略規則

創建 Git

再來為專案創建 Git 版本控制：

// 進到專案資料夾

$ cd chatroom $ git init

$ git add .

$ git commit -m 'first commit'

新增/連結APP

新增 Heroku APP，如後面不帶名稱 Heroku 會自己給予 APP 隨機名字。

$ heroku create [app-name] Creating ⬢ thef2e-chatroom... done

https://thef2e-chatroom.herokuapp.com/ | https://git.heroku.com/thef2e-chatroom.git

注意，如果要跟改專案名字的話，在官網上的 setting 改完他的兩個網址並不會做變更，因此輸入以下指令是比較保險的！

$ heroku apps:rename --app [old-name] [new-name]

現在，我們得到了 APP 網址以及 Git 資料庫網址。我們使用 Heroku 指令把本地的專案與遠端做連結：

$ heroku git:remote -a [app-name] // 查看

$ git remote -v

heroku git.heroku.com/thef2e-chatroom.git (fetch)

heroku git.heroku.com/thef2e-chatroom.git (push)

部署 Heroku

連結後 push 到遠端上：

$ git push heroku master

Counting objects: 100% (6/6), done.

Delta compression using up to 4 threads

Compressing objects: 100% (6/6), done.

Writing objects: 100% (6/6), 10.87 KiB | 5.44 MiB/s, done.

Total 6 (delta 0), reused 0 (delta 0)

remote: Compressing source files... done.

remote: Building source:

remote:

remote: -----> Node.js app detected

remote:

remote: -----> Creating runtime environment

remote:

remote: NPM_CONFIG_LOGLEVEL=error

remote: NODE_ENV=production

remote: NODE_MODULES_CACHE=true

remote: NODE_VERBOSE=false

remote:

remote: -----> Installing binaries

remote: engines.node (package.json): unspecified

remote: engines.npm (package.json): unspecified (use default)

remote:

remote: Resolving node version 12.x...

remote: Downloading and installing node 12.13.0...

remote: Using default npm version: 6.12.0

remote:

remote: -----> Installing dependencies

remote: Installing node modules (package.json + package-lock)

remote: added 123 packages from 102 contributors and audited 239 packages in 3.359s

remote: found 0 vulnerabilities

remote:

remote:

remote: -----> Build

remote:

remote: -----> Pruning devDependencies

remote: audited 239 packages in 1.408s

remote: found 0 vulnerabilities

remote:

remote:

remote: -----> Caching build

remote: - node_modules

remote:

remote: -----> Build succeeded!

remote: ! This app may not specify any way to start a node process

remote:

remote:

remote: -----> Discovering process types

remote: Procfile declares types -> (none)

remote: Default types for buildpack -> web

remote:

remote: -----> Compressing...

remote: Done: 23.1M

remote: -----> Launching...

remote: Released v3

remote:

remote:

remote: Verifying deploy... done.

To

* [new branch] master -> master Enumerating objects: 6, done.Counting objects: 100% (6/6), done.Delta compression using up to 4 threadsCompressing objects: 100% (6/6), done.Writing objects: 100% (6/6), 10.87 KiB | 5.44 MiB/s, done.Total 6 (delta 0), reused 0 (delta 0)remote: Compressing source files... done.remote: Building source:remote:remote: -----> Node.js app detectedremote:remote: -----> Creating runtime environmentremote:remote: NPM_CONFIG_LOGLEVEL=errorremote: NODE_ENV=productionremote: NODE_MODULES_CACHE=trueremote: NODE_VERBOSE=falseremote:remote: -----> Installing binariesremote: engines.node (package.json): unspecifiedremote: engines.npm (package.json): unspecified (use default)remote:remote: Resolving node version 12.x...remote: Downloading and installing node 12.13.0...remote: Using default npm version: 6.12.0remote:remote: -----> Installing dependenciesremote: Installing node modules (package.json + package-lock)remote: added 123 packages from 102 contributors and audited 239 packages in 3.359sremote: found 0 vulnerabilitiesremote:remote:remote: -----> Buildremote:remote: -----> Pruning devDependenciesremote: audited 239 packages in 1.408sremote: found 0 vulnerabilitiesremote:remote:remote: -----> Caching buildremote: - node_modulesremote:remote: -----> Build succeeded!remote: ! This app may not specify any way to start a node processremote: https://devcenter.heroku.com/articles/nodejs-support#default-web-process-type remote:remote: -----> Discovering process typesremote: Procfile declares types -> (none)remote: Default types for buildpack -> webremote:remote: -----> Compressing...remote: Done: 23.1Mremote: -----> Launching...remote: Released v3remote: https://thef2e-chatroom.herokuapp.com/ deployed to Herokuremote:remote: Verifying deploy... done.To https://git.heroku.com/ thef2e-chatroom .git * [new branch] master -> master

如果你是照著我聊天室步驟建立專案的話，會發現終端機有一行顯示驚嘆號，那是因為 Heroku 需要一行 Start 指令去建置專案，而我們的 package.json 檔內並沒有明確指令才報錯。

因此我們需要在 JSON 檔內多新增一行 start，並重新 push 一次，Heroku 就可以成功建置環境了。

"scripts": {

"test": "echo \"Error: no test specified\" && exit 1",

"start": "node index.js"

},

MySQL 配置

接著我們來到第二大關，要準備把本地端資料庫也 push 上去，這次使用的服務是 ClearDB。

我們要先為專案新增一個 Add-ons：

$ heroku addons:create cleardb:ignite Creating cleardb:ignite on ⬢ thef2e-chatroom... free

Created cleardb-octagonal-43734 as CLEARDB_DATABASE_URL

Use heroku addons:docs cleardb to view documentation

也可以在 Heroku 網站做新增：

Heroku 新增 Add-ons

透過以下指令，我們可以得知 ClearDB 資料庫配置：

$ heroku config | grep CLEARDB_DATABASE_URL CLEARDB_DATABASE_URL: mysql://be6c96a165xxx0:c504fxxx@us-cdbr-iron-east-05.cleardb.net/heroku_e8d000339887xxx?reconnect=true // 補充

// username: be6c96a16xxxd

// password: c504fxxx

// host: us-cdbr-iron-east-05.cleardb.net

// database: heroku_e8d000339887xxx

接著打開 MySQL Workbench，並新增新的連線就可以和剛剛新增的資料庫做連結，再把本地端的 database 輸出，引入到遠端資料庫就 OK 了！

MySQL Workbench 新增連線

對了，因為新增了遠端的資料庫，因此我們原本程式碼內連結的本地端資料庫，也須要換成遠端資料庫哦！

Session Store

最後，如果你有引入 Session 在專案裡的話，也會需要新增一項配置屬性為 store，也就是 Session 儲存的地方，在 express-session npm 最下面可以找到很多儲存的方法。

express-session store

我們選用 express-mysql-session，一樣先安裝：

$ npm install express-mysql-session --save

並且引入並使用 (設置在 Session 上方)：

const MySQLStore = require('express-mysql-session')(session); const options = {

connectionLimit: 10,

host: 'us-cdbr-iron-east-05.cleardb.net',

user: 'be6c96a165xxx0',

password: 'c504fxxx',

database: 'heroku_e8d000339887xxx'

}

const sessionStore = new MySQLStore(options); // 此處為 session 設置

app.use(session({

secret: 'thef2e_chatroom',

resave: false,

saveUninitialized: false,

cookie: {

maxAge: 60 * 60 * 1000 * 3,

},

}));

報錯處理

在 APP 網站的右上角可以打開 APP (饒舌，如果看到此頁面代表有報錯。

Heroku APP 報錯

此時可以用以下指令查詢 (使用 ctrl+c 退出)：

$ heroku logs --tail

更詳細的報錯可以參考延伸閱讀第一個文章。

後記

報錯的話多看終端機，看仔細點絕對會找到問題的！

以上是這次部署死都不看報錯的最大心得。

參考資料