aboutsummaryrefslogtreecommitdiff
path: root/files/zh-tw/learn/server-side/express_nodejs/deployment/index.html
blob: d7c2089cd16c9d1a5f94f1206ac79151004f101d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
---
title: 'Express 教學 7: 佈署到生產環境'
slug: Learn/Server-side/Express_Nodejs/deployment
translation_of: Learn/Server-side/Express_Nodejs/deployment
---
<div>{{LearnSidebar}}</div>

<div>{{PreviousMenu("Learn/Server-side/Express_Nodejs/forms", "Learn/Server-side/Express_Nodejs")}}</div>

<p class="summary">現在你已經創建(並測試)了一個不錯的 本地圖書館 網站了,你打算把它發佈到一個公共網絡服務器,這樣圖書館管理員和網路上的其他成員就可以訪問它了。這篇文章總結了你可以怎樣找到一台主機部署你的網站,以及你需要為網站準備好佈署到生產環境該做什麼。</p>

<table class="learn-box standard-table">
 <tbody>
  <tr>
   <th scope="row">預備知識:</th>
   <td>完成前面所有的指南主題,包括 <a href="/en-US/docs/Learn/Server-side/Express_Nodejs/forms">Express Tutorial Part 6: Working with forms</a>.</td>
  </tr>
  <tr>
   <th scope="row">目標:</th>
   <td>學習你可以怎樣以及在哪裡部署一個 Express 應用到生產環境。</td>
  </tr>
 </tbody>
</table>

<h2 id="概覽">概覽</h2>

<p>一旦您的站點完成(或完成 “足夠” 以開始公共測試),您將需要將其託管在比您的個人開發計算機,更公開和可訪問的地方。</p>

<p>到目前為止,您一直在開發環境中工作,使用Express / Node 作為 Web 服務器,將您的站點共享到本地瀏覽器/網路,並使用(不安全的)開發設置運行您的網站,以顯示調試和其他私人信息。在您可以在外部託管網站之前,您首先必須:</p>

<ul>
 <li>選擇託管 Express 應用程序的環境。</li>
 <li>對項目設置進行一些更改。</li>
 <li>設置生產級別的基礎架構,以服務您的網站。</li>
</ul>

<p>本教程提供了,有關選擇託管站點的選項的一些指導,簡要概述了為使您的Express 應用程序準備好生產,所需執行的操作,以及一個工作示例,演示如何將 LocalLibrary 網站安裝到 <a href="https://www.heroku.com/">Heroku</a> 雲託管上的服務。</p>

<p>請記住,您不必使用 Heroku - 還有其他託管服務可用。我們還提供了一個單獨的教程,以展示如何在 <a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Installing_on_PWS_Cloud_Foundry">PWS/Cloud Foundry </a>上安裝 LocalLibrary。</p>

<h2 id="什麼是生產環境?">什麼是生產環境?</h2>

<p>生產環境是服務器計算機提供的環境,您可以在其中運行網站,以供外部使用。環境包括:</p>

<ul>
 <li>網站運行的計算機硬件。</li>
 <li>操作系統(例如 Linux 或 Windows)。</li>
 <li>編程語言運行庫和框架庫,在其上編寫您的網站。</li>
 <li>Web 服務器基礎結構,可能包含 Web 服務器,反向代理,負載平衡器等。</li>
 <li>您的網站所依賴的數據庫。</li>
</ul>

<p>服務器計算機,可以位於您的場所,並通過快速鏈接,連接到 Internet,但使用 “託管在雲上” 的計算機更為常見。這實際上意味著,您的代碼運行在託管公司的數據中心的某台遠程計算機(或可能是“虛擬”計算機)。遠程服務器,通常會以特定價格提供互聯網連接,和一些保證級別的計算資源(例如CPU,RAM,存儲器等)。</p>

<p>這種可遠程訪問的計算/網絡硬件,稱為基礎架構即服務(IaaS)。許多 IaaS 供應商,提供預安裝特定操作系統的選項,您必須在其上,安裝生產環境的其他組件。其他供應商,允許您選擇功能更全面的環境,可能包括完整的 node 設置。</p>

<div class="note">
<p><strong>注意:</strong> 預構建環境,可以使您的網站設置變得非常簡單,因為它們會減少配置,但可用選項可能會限制您使用不熟悉的服務器(或其他組件),並且可能基於較舊版本的操作系統。通常最好自己安裝組件,以便獲得所需的組件,並且當您需要升級系統的某些部分時,您可以知道從哪裡開始!</p>
</div>

<p>其他託管服務提供商,支持 Express 作為平台即服務(PaaS)產品的一部分。使用此類託管時,您無需擔心大多數生產環境(服務器,負載平衡器等),因為主機平台會為您處理這些問題。這使得部署非常簡單,因為您只需要專注於 Web 應用程序,而不是任何其他服務器基礎結構。</p>

<p>一些開發人員選擇 IaaS ,相對於 PaaS ,IaaS 提供更高靈活性,而其他開發人員偏好 PaaS 的降低維護開銷,和更輕鬆的擴展性。當您在一開始使用時,在 PaaS 系統上設置您的網站,要容易得多,因此我們將在本教程中使用 PaaS。</p>

<div class="note">
<p><strong>提示:</strong> 如果您選擇 Node/Express 友好的託管服務提供商,他們應該提供,有關如何使用 Web 服務器,應用程序服務器,反向代理等不同配置,來設置 Express 網站的說明。例如,在<a href="https://www.digitalocean.com/community/tutorials?q=node"> Digital Ocean</a> 的node 社區文檔中,有許多各種配置的手把手指南。</p>
</div>

<h2 id="選擇一個主機供應商">選擇一個主機供應商</h2>

<p>眾所周知,眾多託管服務提供商,都積極支持或與 Node(和Express)合作。這些供應商提供不同類型的環境(IaaS,PaaS),以及不同價格的不同級別的計算和網絡資源。</p>

<div class="note">
<p><strong>提示:</strong> 有很多託管解決方案,他們的服務和定價,可能會隨著時間而改變。雖然我們在下面介紹幾個選項,但在選擇託管服務提供商之前,有必要自己進行互聯網搜索。</p>
</div>

<p>選擇主機時需要考慮的一些事項:</p>

<ul>
 <li>您的網站可能有多忙,以及滿足該需求所需的數據,和計算資源的成本。</li>
 <li>水平擴展(添加更多機器)和垂直擴展(升級到更強大的機器)的支持級別,以及這樣做的成本。</li>
 <li>供應商有數據中心的地方,因此訪問可能是最快的。</li>
 <li>主機正常運行時間和停機時間的歷史表現。</li>
 <li>用於管理站點的工具 - 易於使用且安全(例如 SFTP 與 FTP)。</li>
 <li>用於監控服務器的內置框架。</li>
 <li>已知限制。有些主機會故意阻止某些服務(例如電子郵件)。其他在某些價格層中,僅提供一定數小時的 “實時時間”,或者僅提供少量存儲空間。</li>
 <li>額外的好處。一些提供商將提供免費域名和 SSL 證書支持,否則您將不得不為此另外支付費用。</li>
 <li>您所依賴的“免費”等級,是否會隨著時間的推移而過期,以及遷移到更昂貴等級的成本,是否意味著您最好在一開始就使用其他服務!</li>
</ul>

<p>當你剛開始時,好消息是有很多網站提供“免費”的計算環境,儘管有一些條件。例如, <a href="https://www.heroku.com/">Heroku</a>  “永遠” 提供免費但資源有限的 PaaS 環境,而 <a href="http://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/billing-free-tier.html">Amazon Web Services</a>, <a href="https://azure.microsoft.com/en-us/pricing/details/app-service/">Microsoft Azure</a> 和開源選項 <a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Installing_on_PWS_Cloud_Foundry">PWS/Cloud Foundry</a> 在您第一次加入時,提供免費信用額度。</p>

<p>許多提供商還擁有“基本”層,可提供更多有用的計算能力,和更少的限制。舉例來說, <a href="https://www.digitalocean.com/">Digital Ocean</a> 是一個流行的託管服務提供商,它提供了一個相對便宜的基本計算層(在本教程寫作時,是每月5美元的較低範圍)。</p>

<div class="note">
<p><strong>注意:</strong> 請記住,價格不是唯一的選擇標準。如果您的網站成功,可能會發現可擴展性是最重要的考慮因素。</p>
</div>

<h2 id="準備好發布你的網站">準備好發布你的網站</h2>

<p>發佈網站時,要考慮的主要問題是網絡安全性和性能。至少,您需要刪除開發期間,錯誤頁面上包含的堆棧跟踪,整理日誌記錄,並設置適當的標頭,以避免許多常見的安全威脅。</p>

<p>在以下小節中,我們概述了您應該對應用進行的、最重要的更改。</p>

<div class="note">
<p><strong>提示:</strong> Express文檔中還有其他有用的提示 - 請參閱“<a href="https://expressjs.com/en/advanced/best-practice-performance.html">生產最佳實踐:性能和可靠性</a>”,以及“<a href="https://expressjs.com/en/advanced/best-practice-security.html">生產最佳實踐:安全性</a>”。</p>
</div>

<h3 id="設置_NODE_ENV_為_'production'">設置 NODE_ENV 為 'production'</h3>

<p>我們可以通過將 <code>NODE_ENV</code> 環境變量,設置為 production ,來刪除錯誤頁面中的堆棧跟踪(默認設置為 “development” )。除了生成較為不詳細的錯誤消息之外,還要將變量設置為生產緩存視圖模板,和從 CSS 擴展生成的 CSS 文件。測試表明,將<code>NODE_ENV</code>設置為生產,可以將應用程序性能提高三倍!</p>

<p>可以使用導出或環境文件,或使用 OS 初始化系統,以進行此更改。</p>

<div class="note">
<p><strong>注意:</strong> 這實際上是在環境設置,而不是應用中所做的更改,但重要的是,要注意這裡!我們將在下面,展示我們的託管示例要如何設置。</p>
</div>

<h3 id="Log_appropriately">Log appropriately</h3>

<p>記錄呼叫會對高流量網站產生影響。在生產環境中,您可能需要記錄網站活動(例如,跟踪流量,或記錄API調用),但您應嘗試最小化為調試目的而添加的日誌記錄量。</p>

<p>在生產環境中,最小化“調試”日誌記錄的一種方法,是使用類似調試 <a href="https://www.npmjs.com/package/debug">debug </a> 的模塊,允許您通過設置環境變量,來控制執行的日誌記錄。例如,下面的代碼片段,顯示如何設置 “author” 日誌記錄。調試變量使用名稱 “author” 聲明,並且將自動顯示,來自此對象的所有日誌的前綴 “author”。</p>

<pre class="brush: js"><strong>var debug = require('debug')('author');</strong>

// Display Author update form on GET
exports.author_update_get = function(req, res, next) {

    req.sanitize('id').escape().trim();
    Author.findById(req.params.id, function(err, author) {
        if (err) {
<strong>            debug('update error:' + err);</strong>
            return next(err);
        }
        //On success
        res.render('author_form', { title: 'Update Author', author: author });
    });

};</pre>

<p>然後,您可以通過在 <code>DEBUG </code>環境變量中,將它們指定為逗號分隔列表,來啟用特定日誌集。您可以設置顯示作者和書籍日誌的變量,如圖所示(也支持通配符)。</p>

<pre class="brush: bash">#Windows
set DEBUG=author,book

#Linux
export DEBUG="author,book"
</pre>

<div class="note">
<p><strong>挑戰:</strong> 調用<code>debug</code>可以替換您以前使用 <code>console.log()</code><code>console.error()</code>執行的日誌記錄。通過調試模塊 <a href="https://www.npmjs.com/package/debug">debug </a>進行日誌記錄,替換代碼中的所有<code>console.log()</code>調用。通過設置 DEBUG 變量,並在其中記錄對日誌記錄的影響,在開發環境中,打開和關閉日誌記錄。</p>
</div>

<p>如果您需要記錄網站活動,可以使用 Winston 或 Bunyan 等日誌庫。有關此主題的更多信息,請參閱:<a href="https://expressjs.com/en/advanced/best-practice-performance.html">生產最佳實踐:性能和可靠性</a></p>

<h3 id="使用_gzipdeflate_壓縮響應">使用 gzip/deflate 壓縮響應</h3>

<p>Web 服務器,通常可以壓縮發送回客戶端的 HTTP 響應,從而顯著減少客戶端獲取和加載頁面所需的時間。使用的壓縮方法,取決於客戶端在請求中支持的解壓縮方法(如果不支持壓縮方法,則響應將以未壓縮的方式發送)。</p>

<p>您可以使用壓縮中間件 <a href="https://www.npmjs.com/package/compression">compression</a>,將其添加到您的站點。通過在項目的根目錄下,運行以下命令,將其安裝到項目中。</p>

<pre class="brush: bash">npm install compression</pre>

<p>打開<strong>./app.js</strong>,並導入壓縮庫,如圖所示。使用<code> use()</code>方法,將壓縮庫添加到中間件鏈(這應該出現在您想要壓縮的任何路由之前 - 在本教程這種情況下,全部都是!)</p>

<pre class="brush: js">var catalogRouter = require('./routes/catalog'); //Import routes for "catalog" area of site
<strong>var compression = require('compression');</strong>

// Create the Express application object
var app = express();

...

<strong>app.use(compression()); //Compress all routes</strong>

app.use(express.static(path.join(__dirname, 'public')));

app.use('/', indexRouter);
app.use('/users', usersRouter);
app.use('/catalog', catalogRouter);  // Add catalog routes to middleware chain.

...
</pre>

<div class="note">
<p><strong>注意</strong>: 對於生產中流量較大的網站,您不會使用此中間件。相反,你會使用像 Nginx 這樣的反向代理。</p>
</div>

<h3 id="使用_Helmet_避免被常見漏洞侵襲">使用 Helmet 避免被常見漏洞侵襲</h3>

<p><a href="https://www.npmjs.com/package/helmet">Helmet</a> 是一個中間件包,可以通過設置適當的 HTTP 標頭,來幫助保護您的應用,免受一些眾所周知的 Web 漏洞的影響(有關它設置的標頭/防護漏洞的詳細信息,請參閱文檔 <a href="https://helmetjs.github.io/docs/">docs</a>) 。</p>

<p>通過在項目的根目錄下,運行以下命令,將其安裝到項目中。</p>

<pre class="brush: bash">npm install helmet
</pre>

<p>打開<strong>./app.js</strong>,並導入如圖所示的 helmet 庫。然後使用<code>use()</code>方法,將模塊添加到中間件鏈。</p>

<pre class="brush: js">var compression = require('compression');
<strong>var helmet = require('helmet');
</strong>
// Create the Express application object
var app = express();

<strong>app.use(helmet())</strong>;
...</pre>

<div class="note">
<p id="production-best-practices-performance-and-reliability"><strong>注意:</strong> 上面的命令,添加了對大多數站點有意義的可用標頭子集。您可以按照 <a href="https://www.npmjs.com/package/helmet">npm </a>上的說明,根據需要添加/禁用特定標頭。</p>
</div>

<h2 id="例子:在_Heroku_上安裝本地圖書館">例子:在 Heroku 上安裝本地圖書館</h2>

<p>本節提供如何在 <a href="http://heroku.com">Heroku PaaS cloud</a> 雲上安裝 LocalLibrary 的實際演示。</p>

<h3 id="為什麼選擇_Heroku">為什麼選擇 Heroku?</h3>

<p>Heroku 是運行時間最長,且最受歡迎的基於雲的 PaaS 服務之一。它最初只支持 Ruby 應用程序,但現在可用於託管來自許多編程環境的應用程序,包括 Node(以及Express)!</p>

<p>我們選擇使用 Heroku 有以下幾個原因:</p>

<ul>
 <li>Heroku 有一個免費套餐 <a href="https://www.heroku.com/pricing">free tier</a>(儘管有一些限制)。</li>
 <li>作為 PaaS,Heroku 為我們提供了大量的 Web 基礎架構。這使得入門更加容易,因為您不必擔心服務器,負載平衡器,反向代理,崩潰時重新啟動網站,或者 Heroku 為我們提供的任何其他 Web 基礎結構。</li>
 <li>雖然它確實有一些限制,但這些不會影響這個特定的應用程序。例如:
  <ul>
   <li>Heroku 只提供短期存儲,因此用戶上傳的文件無法安全地存儲在 Heroku本身。</li>
   <li>如果半小時內沒有請求,免費套餐將使不活動的網絡應用程序進入睡眠。然後,該網站可能需要幾秒鐘才能被喚醒。</li>
   <li>免費套餐將您網站運行的時間,限制為每月一定的小時數(不包括網站“睡著”的時間)。這對於低使用/演示站點來說很好,但如果需要100%的正常運行時間,則不適用。</li>
   <li>Heroku 官方文檔 <a href="https://devcenter.heroku.com/articles/limits">Limits </a>中列出的其他限制。</li>
  </ul>
 </li>
 <li>大多數情況下,它只是可以工作,如果你最終喜歡它,並希望升級,那麼擴展你的應用程序非常容易。</li>
</ul>

<p>雖然 Heroku 非常適合舉辦此演示,但它可能並不適合您的真實網站。 Heroku 可以輕鬆設置和擴展,但代價是靈活性較低,而且一旦退​​​​出免費套餐,可能會花費更多。</p>

<h3 id="Heroku_如何工作">Heroku 如何工作?</h3>

<p>Heroku在一個或多個 "<a href="https://devcenter.heroku.com/articles/dynos">Dynos</a>" 中運行網站,這些 “Dynos” 是獨立的虛擬化Unix容器,提供運行應用程序所需的環境。 Dynos 是完全隔離的,並且有一個短暫的文件系統(一個短暫的文件系統,每次dyno重新啟動時都會清理/清空)。 dynos 默認共享的唯一內容,是應用程序配置變量 <a href="https://devcenter.heroku.com/articles/config-vars">configuration variables</a>。 Heroku 內部使用負載均衡器,將Web流量分配給所有 “web” dynos。由於它們之間沒有任何共享,Heroku 可以通過添加更多 dynos,來水平擴展應用程序(當然,您可能還需要擴展數據庫,以接受其他連接)。</p>

<p>由於文件系統是短暫的,因此無法直接安裝應用程序所需的服務(例如數據庫,隊列,緩存系統,存儲,電子郵件服務等)。相反,Heroku Web應用程序使用 Heroku 或第三方作為獨立“附加組件”提供的支持服務。連接到Web應用程序後,可以通過環境變量,在Web應用程序中訪問附加服務。</p>

<p>為了執行您的應用程序,Heroku 需要能夠設置適當的環境和依賴關係,並了解它是如何啟動的。對於 Node 應用程序,它所需的所有信息都是從 <strong>package.json</strong>文件中獲取的。</p>

<p>開發人員使用特殊的客戶端應用程序/終端,與 Heroku 交互,這很像 Unix bash 腳本。這允許您上傳存儲在 git 儲存庫中的代碼,檢查正在運行的進程,查看日誌,設置配置變量等等!</p>

<p>為了讓我們的應用程序在 Heroku 上工作,我們需要將我們的 Express Web 應用程序放入 git 儲存庫,並對 package.json 進行一些小的更改。完成後,我們可以設置Heroku 帳戶,獲取 Heroku 客戶端,並使用它來安裝我們的網站。</p>

<p>這是您開始教程所需的全部概述(有關更全面的指南,請參閱帶有 Node.js 的<a href="https://devcenter.heroku.com/articles/getting-started-with-nodejs">Heroku</a> 入門)。</p>

<h3 id="在_Github_上創建一個應用倉庫">在 Github 上創建一個應用倉庫</h3>

<p>Heroku 與 <strong>git</strong> 源代碼版本控制系統緊密集成,使用它來上傳/同步您對實時運行系統所做的任何更改。它通過添加一個名為 heroku 的新 Heroku“遠程”儲存庫,來指向您在Heroku雲上的源儲存庫。在開發期間,您使用 git 在“主”儲存庫 master 中儲存更改。如果要部署站點,請將更改同步到 Heroku 存儲庫。</p>

<div class="note">
<p><strong>注意:</strong> 如果您習慣於遵循良好的軟件開發實踐,那麼您可能已經在使用 git 或其他一些 SCM 系統。如果您已有 git 儲存庫,則可以跳過此步驟。</p>
</div>

<p>有很多方法可以使用git,但最簡單的方法之一,是首先在 <a href="https://github.com/">GitHub </a>上建立一個帳戶,在那裡創建儲存庫,然後在本地同步它:</p>

<ol>
 <li>訪問 <a href="https://github.com/">https://github.com/</a> 並創建一個帳戶。</li>
 <li>登錄後,單擊頂部工具欄中的 + 號鏈接,然後選擇新建儲存庫  <strong>New repository</strong></li>
 <li>填寫此表單上的所有字段。雖然這些不是強制性的,但強烈建議使用它們。
  <ul>
   <li>輸入新的存儲庫名稱(例如,express-locallibrary-tutorial)和描述(例如 “以Express(node)編寫的本地圖書館網站”)。</li>
   <li>在 Add .gitignore 選擇列表中選擇 <strong>Node</strong></li>
   <li>在添加許可證 Add license 選擇列表中,選擇您偏好的許可證。</li>
   <li>點選 使用自述文件初始化此儲存庫 <strong>Initialize this repository with a README</strong>.</li>
  </ul>
 </li>
 <li><strong>Create repository</strong>.</li>
 <li>單擊新倉庫頁面上的綠色“克隆或下載”按鈕 "<strong>Clone or download</strong>" 。</li>
 <li>從顯示的對話框的文本字段,複製 URL值(它應該類似於:<strong>https://github.com/<em>&lt;your_git_user_id&gt;</em>/express-locallibrary-tutorial.git</strong>)。</li>
</ol>

<p>現在創建了儲存庫(“repo”),我們將要在本地計算機上克隆它:</p>

<ol>
 <li>為您的本地計算機安裝 git(您可以在<a href="https://git-scm.com/downloads">此處找到不同平台的版本</a>)。<br>
   </li>
 <li>打開命令提示符/終端,並使用您在上面複製的 URL ,克隆儲存庫:
  <pre class="brush: bash">git clone https://github.com/<strong><em>&lt;your_git_user_id&gt;</em></strong>/express-locallibrary-tutorial.git
</pre>
  這將在當前時間點之後,創建儲存庫。</li>
 <li>到新的儲存庫。
  <pre class="brush: bash">cd express-locallibrary-tutorial</pre>
 </li>
</ol>

<p>最後一步,是複制你的應用程序,然後使用 git ,將文件添加到你的倉庫:</p>

<ol>
 <li>將Express應用程序,複製到此文件夾中(不包括 <strong>/node_modules</strong>,其中包含您應根據需要,從 NPM 獲取的依賴項文件)。</li>
 <li>打開命令提示符/終端,並使用 <code>add </code>命令,將所有文件添加到 git。</li>
 <li>
  <pre class="brush: bash">git add -A
</pre>
 </li>
 <li>使用 status 命令,檢查要添加的所有文件是否正確(您希望包含源文件,而不是二進製文件,臨時文件等)。它應該看起來有點像下面的列表。
  <pre>&gt; git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
  (use "git reset HEAD &lt;file&gt;..." to unstage)

        new file:   ...</pre>
 </li>
 <li>如果您滿意,請將文件提交到本地儲存庫:
  <pre class="brush: bash">git commit -m "First version of application moved into github"</pre>
 </li>
 <li>然後使用以下內容,將本地儲存庫同步到 Github 網站:
  <pre>git push origin master</pre>
 </li>
</ol>

<p>完成此操作後,您應該可以返回創建儲存庫的 Github 上的頁面,刷新頁面,並查看您的整個應用程序現已上傳。使用此添加/提交/推送循環,您可以在文件更改時,繼續更新儲存庫。</p>

<div class="note">
<p><strong>提示:</strong> 這是備份你的“vanilla”項目的好時機 - 雖然我們將在以下部分中進行的一些更改,可能對任何平台(或開發)上的部署有用,而一些其他的更改可能沒有用。</p>

<p>執行此操作的最佳方法,是使用 git 來管理您的修訂。使用 git,您不僅可以回到特定的舊版本,而且可以在生產變更的單獨“分支”中進行維護,並選擇在生產和開發分支之間移動的任何更改。<a href="https://help.github.com/articles/good-resources-for-learning-git-and-github/">學習Git</a>非常值得,但超出了本主題的範圍。</p>

<p>最簡單的方法,是將文件複製到另一個位置。以您對 git 了解,使用最符合的方法!</p>
</div>

<h3 id="更新_Heroku_的應用程序">更新 Heroku 的應用程序</h3>

<p>本節介紹了您需要對 LocalLibrary 應用程序進行的更改,以使其在 Heroku 上運行。</p>

<h4 id="設置_node_版本">設置 node 版本</h4>

<p><strong>package.json</strong> 包含解決應用程序依賴項所需的所有內容,以及啟動站點時,應啟動的文件。 Heroku 檢測到此文件的存在,並將使用它來配置您的應用程序環境。</p>

<p>我們當前的 <strong>package.json</strong> 中,缺少的唯一有用信息,是 node 的版本。我們可以通過輸入命令,找到我們用於開發的 node 版本:</p>

<pre class="brush: bash">&gt;node --version
v8.9.1</pre>

<p>打開 <strong>package.json</strong>,並將此信息添加為 <strong>engines &gt; node</strong> 部分,如圖所示(使用系統的版本號)。</p>

<pre class="brush: json">{
  "name": "express-locallibrary-tutorial",
  "version": "0.0.0",
<strong>  "engines": {
    "node": "8.9.1"
  },</strong>
  "private": true,
  ...
</pre>

<h4 id="數據庫配置">數據庫配置</h4>

<p>到目前為止,在本教程中,我們使用了一個硬編碼到 <strong>app.js</strong> 的單個數據庫。通常我們希望,能夠為生產和開發創建不同的數據庫,接下來我們將修改 LocalLibrary 網站,以從 OS 環境獲取數據庫 URI(如果已定義),否則使用我們的開發數據庫。</p>

<p>打開 <strong>app.js</strong>,並找到設置 mongoDB 連接變量的行。它看起來像這樣:</p>

<pre class="brush: js">var mongoDB = 'mongodb://your_user_id:your_password@ds119748.mlab.com:19748/local_library';</pre>

<p>使用以下代碼替換該行,該代碼使用 <code>process.env.MONGODB_URI </code>從名為 <code>MONGODB_URI </code>的環境變量中,獲取連接字符串(如果已設置)(使用您自己的數據庫URL,而不是下面的佔位符。)</p>

<pre class="brush: js">var mongoDB = <strong>process.env.MONGODB_URI</strong> || 'mongodb://your_user_id:your_password@ds119748.mlab.com:19748/local_library';
</pre>

<h4 id="安裝依賴並重新測試">安裝依賴並重新測試</h4>

<p>在我們繼續之前,讓我們再次測試該網站,並確保它不受我們的任何更改的影響。</p>

<p>首先,我們需要獲取我們的依賴項(你會記得,我們​​沒有將 <strong>node_modules</strong>文件夾,複製到我們的 git 樹中)。您可以通過在項目根目錄的終端中,運行以下命令來執行此操作:</p>

<pre class="brush: bash">npm install
</pre>

<p>現在運行該站點(請參閱<a href="/zh-TW/docs/Learn/Server-side/Express_Nodejs/routes#Testing_the_routes">測試路由</a>的相關命令),並檢查該站點,是否仍按預期運行。</p>

<h4 id="將更改保存到_Github">將更改保存到 Github</h4>

<p>接下來,讓我們將所有更改保存到 Github。在終端中(在我們的儲存庫中),輸入以下命令:</p>

<pre class="brush: bash">git add -A
git commit -m "Added files and changes required for deployment to heroku"
git push origin master</pre>

<p>我們現在應該準備開始在 Heroku 上,部署 LocalLibrary。</p>

<h3 id="獲取一個_Heroku_帳戶">獲取一個 Heroku 帳戶</h3>

<p>要開始使用 Heroku,您首先需要創建一個帳戶(如果您已經擁有一個帳戶,並安裝了 Heroku 客戶端,請跳過創建並上傳網站):</p>

<ul>
 <li>訪問 <a href="https://www.heroku.com/">www.heroku.com</a> 並單擊免費註冊按鈕 <strong>SIGN UP FOR FREE</strong></li>
 <li>輸入您的詳細信息,然後按 <strong>CREATE FREE ACCOUNT</strong>。系統會要求您,檢查帳戶中是否有註冊電子郵件。</li>
 <li>單擊註冊電子郵件中的帳戶激活鏈接。您將在網絡瀏覽器上收回您的帳戶。</li>
 <li>輸入您的密碼,然後單擊 <strong>SET PASSWORD AND LOGIN</strong>.</li>
 <li>然後,您將登錄並進入Heroku儀表板: <a href="https://dashboard.heroku.com/apps">https://dashboard.heroku.com/apps</a>.</li>
</ul>

<h3 id="安裝客戶端">安裝客戶端</h3>

<p>按照 <a href="https://devcenter.heroku.com/articles/getting-started-with-python#set-up">Heroku 上的說明</a>,下載並安裝 Heroku 客戶端。</p>

<p>安裝客戶端后,您將能夠運行命令。例如,要獲得客戶端的幫助說明:</p>

<pre class="brush: bash">heroku help
</pre>

<h3 id="創建並上傳網站">創建並上傳網站</h3>

<p>要創建應用程序,我們在儲存庫的根目錄中,運行 “create” 命令。這將在我們的本地git 環境中,創建一個名為 heroku 的 git remote(“指向遠程儲存庫的指針”)。</p>

<pre class="brush: bash">heroku create</pre>

<div class="note">
<p><strong>注意:</strong> 如果您願意,可以在“創建”create 之後指定遠程儲存庫的命名。如果你不這樣做,你會得到一個隨機的名字。該名稱用於默認 URL。</p>
</div>

<p>然後,我們可以將我們的應用程序,推送到 Heroku 儲存庫,如下所示。這將上傳應用程序,獲取所有依賴項,將其打包到 dyno 中,然後啟動該站點。</p>

<pre class="brush: bash">git push heroku master</pre>

<p>如果我們很幸運,該應用程序現在正在網站上“運行”。要打開瀏覽器並運行新網站,請使用以下命令:</p>

<pre class="brush: bash">heroku open</pre>

<div class="note">
<p><strong>注意</strong>: 該站點將使用我們的開發數據庫運行。創建一些書本和其他對象,並檢查該網站是否按預期運行。在下一節中,我們將其設置為使用我們的新數據庫。</p>
</div>

<h3 id="設定配置變量">設定配置變量</h3>

<p>您將從前一節回憶起,我們需要將 NODE_ENV 設置為 'production',以便提高性能,並生成更簡潔的錯誤消息。我們通過輸入以下命令,來完成此操作:</p>

<pre class="brush: bash">&gt;heroku config:set NODE_ENV='production'
Setting NODE_ENV and restarting limitless-tor-18923... done, v13
NODE_ENV: production
</pre>

<p>我們還應該使用單獨的數據庫進行生產,在<strong>MONGODB_URI</strong>環境變量中,設置其URI。您可以完全按照<a href="/zh-TW/docs/Learn/Server-side/Express_Nodejs/mongoose#Setting_up_the_MongoDB_database">我們原來的方式</a>,設置新數據庫和數據庫用戶,並獲取其URI。您可以如下圖所示設置URI(顯然,要使用您自己的URI!)</p>

<pre class="brush: bash">&gt;heroku config:set <strong>MONGODB_URI</strong>='mongodb://your_user:your_password@ds139278.mlab.com:39278/local_library_production'
Setting MONGODB_URI and restarting limitless-tor-18923... done, v13
MONGODB_URI: mongodb://your_user:your_password@ds139278.mlab.com:39278/local_library_production
</pre>

<p>您可以使用 <code>heroku config </code>命令,隨時檢查配置變量 - 立即嘗試:</p>

<pre class="brush: bash">&gt;heroku config
=== limitless-tor-18923 Config Vars
MONGODB_URI: mongodb://your_user:your_password@ds139278.mlab.com:39278/local_library_production
NODE_ENV:    production
</pre>

<p>Heroku 會在更新變量時,重新啟動應用程序。如果您現在檢查主頁,它應該顯示對象計數的零值,因為上面的更改,意味著我們現在正在使用新的(空)數據庫。</p>

<h3 id="管理附加組件">管理附加組件</h3>

<p>Heroku 使用獨立的附加組件,為應用程序提供支持服務 - 例如電子郵件或數據庫服務。我們不在本網站中使用任何插件,但它們是使用 Heroku 的重要部分,因此您可能需要查看主題 - <a href="https://devcenter.heroku.com/articles/managing-add-ons">管理插件(Heroku 官方文件)</a></p>

<h3 id="除錯">除錯</h3>

<p>Heroku 客戶端提供了一些除錯工具:</p>

<pre class="brush: bash">heroku logs  # Show current logs
heroku logs --tail # Show current logs and keep updating with any new results
heroku ps   #Display dyno status
</pre>

<ul>
</ul>

<h2 id="總結">總結</h2>

<p>本教程介紹在生產環境中,如何配置 Express 應用。是Express系列教程的最後一個。我們希望你覺得這些教程有用。你可以在 <a href="https://github.com/mdn/express-locallibrary-tutorial">Github </a>上取得完整的源碼。</p>

<h2 id="相關鏈接">相關鏈接</h2>

<ul>
 <li id="production-best-practices-performance-and-reliability"><a href="https://expressjs.com/en/advanced/best-practice-performance.html">Production best practices: performance and reliability</a> (Express docs)</li>
 <li><a href="https://expressjs.com/en/advanced/best-practice-security.html">Production Best Practices: Security</a> (Express docs)</li>
 <li>Heroku
  <ul>
   <li><a href="https://devcenter.heroku.com/articles/getting-started-with-nodejs">Getting Started on Heroku with Node.js</a> (Heroku docs)</li>
   <li><a href="https://devcenter.heroku.com/articles/deploying-nodejs">Deploying Node.js Applications on Heroku</a> (Heroku docs)</li>
   <li><a href="https://devcenter.heroku.com/articles/nodejs-support">Heroku Node.js Support</a> (Heroku docs)</li>
   <li><a href="https://devcenter.heroku.com/articles/node-concurrency">Optimizing Node.js Application Concurrency</a> (Heroku docs)</li>
   <li><a href="https://devcenter.heroku.com/articles/how-heroku-works">How Heroku works</a> (Heroku docs)</li>
   <li><a href="https://devcenter.heroku.com/articles/dynos">Dynos and the Dyno Manager</a> (Heroku docs)</li>
   <li><a href="https://devcenter.heroku.com/articles/config-vars">Configuration and Config Vars</a> (Heroku docs)</li>
   <li><a href="https://devcenter.heroku.com/articles/limits">Limits</a> (Heroku docs)</li>
  </ul>
 </li>
 <li>Digital Ocean
  <ul>
   <li><a href="https://www.digitalocean.com/community/tutorials?q=express">Express</a> tutorials</li>
   <li><a href="https://www.digitalocean.com/community/tutorials?q=node.js">Node.js</a> tutorials </li>
  </ul>
 </li>
</ul>

<p>{{PreviousMenu("Learn/Server-side/Express_Nodejs/forms", "Learn/Server-side/Express_Nodejs")}}</p>

<p> </p>

<h2 id="本教學鏈接">本教學鏈接</h2>

<ul>
 <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Introduction">Express/Node introduction</a></li>
 <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/development_environment">Setting up a Node (Express) development environment</a></li>
 <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Tutorial_local_library_website">Express Tutorial: The Local Library website</a></li>
 <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/skeleton_website">Express Tutorial Part 2: Creating a skeleton website</a></li>
 <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/mongoose">Express Tutorial Part 3: Using a Database (with Mongoose)</a></li>
 <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/routes">Express Tutorial Part 4: Routes and controllers</a></li>
 <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Displaying_data">Express Tutorial Part 5: Displaying library data</a></li>
 <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/forms">Express Tutorial Part 6: Working with forms</a></li>
 <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/deployment">Express Tutorial Part 7: Deploying to production</a></li>
</ul>

<p> </p>