利用Docker設置Node.js

docker是一個開源的應用容器引擎,可以為我們提供安全、可移植亭畜、可重復的自動化部署的方式。docker采用虛擬化的技術來虛擬化出應用程序的運行環(huán)境迎卤。如上圖一樣拴鸵。docker就像一艘輪船。而輪船上面的每個小箱子可以看成我們需要部署的一個個應用蜗搔。使用docker可以充分利用服務器的系統資源宝踪,簡化了自動化部署和運維的繁瑣流程,減少很多因為開發(fā)環(huán)境中和生產環(huán)境中的不同引發(fā)的異常問題。從而提高生產力碍扔。

docker三個核心概念如下:

鏡像(images):一個只讀的模板瘩燥,可以理解為應用程序的運行環(huán)境,包含了程序運行所依賴的環(huán)境和基本配置不同。相當于上圖中的每個小箱子里面裝的東西厉膀。

倉庫(repository):一個用于存放鏡像文件的倉庫《眨可以看做和gitlab一樣服鹅。

容器(container):一個運行應用程序的虛擬容器,他和鏡像最大的區(qū)別在于容器的最上面那一層是可讀可寫的百新。 相當于上圖中的每個小箱子里企软。

本文主要是教大家了解如何在Docker容器中設置Node JS:

有一個可運行工作的NodeJS應用程序

通過確保進程在出錯時不退出,使節(jié)點應用程序具有彈性

通過在代碼更改時自動重新啟動服務器饭望,使Node應用程序易于使用

利用Docker:

快速設置與生產相同的開發(fā)環(huán)境仗哨。

輕松地能夠在本地和服務器上切換節(jié)點版本

Docker的所有其他 好處

先決條件

Docker已經安裝好了

至少入門級節(jié)點知識和NPM

1.獲取一個簡單的Node應用程序

我們將使用Express,因為它的設置是容易的铅辞。

在一個干凈的目錄中厌漂,讓我們從初始化NPM開始,繼續(xù)運行此命令并按照提示進行操作:

npm init

安裝Express:

npm install --save-prod express

編制代碼src/index.js

<b>const</b> express = require('express')

<b>const</b> app = express()

<b>const</b> port = 3000

app.get('/', (req, res) => res.send('Hello World!'))

app.listen(port, () => {console.log(`Example app listening on port ${port}!`))

啟動一個偵聽端口3000并使用Hello World響應的"/"這個URL路由斟珊。

2.設置Docker以運行我們的Node應用程序

我們將使用docker-compose.yml文件來啟動和停止我們的Docker容器苇倡,而不是鍵入長長的Docker命令。您可以將此文件視為多個Docker容器的配置文件。

docker-compose.yml:

version: "3"

services:

app:

container_name: app # How the container will appear when listing containers from the CLI

image: node:10 # The <container-name>:<tag-version> of the container, in this case the tag version aligns with the version of node

user: node # The user to run as in the container

working_dir: "/app" # Where to container will assume it should run commands and where you will start out if you go inside the container

networks:

- app # Networking can get complex, but for all intents and purposes just know that containers on the same network can speak to each other

ports:

- "3000:3000" # <host-port>:<container-port> to listen to, so anything running on port 3000 of the container will map to port 3000 on our localhost

volumes:

- ./:/app # <host-directory>:<container-directory> this says map the current directory from your system to the /app directory in the docker container

command: "node src/index.js" # The command docker will execute when starting the container, this command is not allowed to exit, if it does your container will stop

networks:

app:

讓我們用這個命令啟動docker容器旨椒。在后臺運行(-d)

docker-compose up -d

在瀏覽器中訪問http://localhost:3000并看到 Hello World!

3. 使得應用變得彈性

如果您之前使用過Node晓褪,那么您可能知道如果應用程序中發(fā)生錯誤(如未捕獲的異常),那么它將關閉該Node進程综慎。這對我們來說真的是個壞消息涣仿,因為我們的代碼中肯定會有一個錯誤,并且無法保證我們的代碼100%無錯誤寥粹。此問題的解決方案通常是另一個監(jiān)視我們的Node應用程序并在其退出時重新啟動它的過程变过。有這么多的解決方案埃元,比如linux的supervisord涝涤,NPM包永遠和PM2等......我們只需要為本指南選擇一個。

將專注于 PM2岛杀, 因為我最熟悉它阔拳,除了進程管理之外還有一些其他功能,例如文件監(jiān)視类嗤,這將在下一節(jié)中派上用場糊肠。

安裝PM2

npm install --save-prod pm2

PM2可以通過命令行使用,但我們將設置一個簡單的配置文件遗锣,就像我們使用docker-compose.yml文件一樣货裹,以防止我們重復輸入長命令

ecosystem.config.js:

const path = require('path')

module.exports = {

apps: [{

name: 'app',

script: 'src/index.js', // Your entry point

instances: 1,

autorestart: true, // THIS is the important part, this will tell PM2 to restart your app if it falls over

max_memory_restart: '1G'

}]

}

現在我們應該更改docker-compose.yml文件以使用PM2啟動我們的應用程序,而不是直接從index.js啟動它精偿。

docker-compose.yml(僅更改了的選項)

version: "3"

services:

app:

container_name: app # How the container will appear when listing containers from the CLI

image: node:10 # The <container-name>:<tag-version> of the container, in this case the tag version aligns with the version of node

user: node # The user to run as in the container

working_dir: "/app" # Where to container will assume it should run commands and where you will start out if you go inside the container

networks:

- app # Networking can get complex, but for all intents and purposes just know that containers on the same network can speak to each other

ports:

- "3000:3000" # <host-port>:<container-port> to listen to, so anything running on port 3000 of the container will map to port 3000 on our localhost

volumes:

- ./:/app # <host-directory>:<container-directory> this says map the current directory from your system to the /app directory in the docker container

command: "npx pm2 start ecosystem.config.js --no-daemon" # The command docker will execute when starting the container, this command is not allowed to exit, if it does your container will stop

networks:

app:

更改docker-compose.yml文件不會影響已經運行的容器弧圆。為了進行更改,您應該重新啟動容器:

docker-compose restart

4.使我們的應用程序易于開發(fā)

您可能已經注意到笔咽,一旦Node進程啟動搔预,那么在重新啟動Node進程之前,更改代碼實際上并沒有做任何事情叶组,對于我們而言拯田,每次都會涉及重新啟動Docker容器以激活我們做出的改變。如果我們在進行代碼更改時自動為我們重新啟動Node進程甩十,那將是理想的選擇船庇。

在過去,我已經完成了諸如引入文件監(jiān)視實用程序和使用該文件監(jiān)視實用程序來重新啟動Docker進行文件更改之類的操作侣监,或者我會使用Nodemon但是在使用Docker時會有一些警告溢十。

最近,當文件發(fā)生變化時达吞,我一直在使用PM2來重新啟動我的Node進程张弛,而且由于我們已經從上一步中獲取了它,因此我們不必安裝另一個依賴項。

ecosystem.config.js(僅添加了watch選項):

const path = require('path')

module.exports = {

apps: [{

name: 'app',

script: 'src/index.js',

instances: 1,

autorestart: true,

watch: process.env.NODE_ENV !== 'production' ? path.resolve(__dirname, 'src') : false,

max_memory_restart: '1G'

}]

}

如果我們沒有將NODE_ENV環(huán)境變量設置為production吞鸭,則上面的配置文件現在將監(jiān)視src目錄寺董。您可以通過更改index.js文件來測試它,除了Hello World之外還可以將其他內容打印到瀏覽器中刻剥!遮咖。在此之前,您需要重新啟動Docker容器造虏,因為您更改了PM2運行容器的方式:

docker-compose restart

重新啟動Node進程可能需要一秒鐘才能完成御吞,如果你想觀察它何時完成,你可以看到你的Docker日志告訴PM2何時完成重啟你的Node Process:

docker-compose logs -f

總結

我們的目標之一是能夠輕松更改Node版本漓藕,您可以通過更改docker-compose.yml文件中的image選項來完成此操作陶珠。

本地安裝依賴項是使用本地NPM和Node版本完成的,如果您的本地版本與Dockers不同享钞,有時可能會導致沖突揍诽。使用相同的Docker容器來安裝依賴項更安全。您可以使用此命令來使用該容器來安裝依賴項栗竖,然后將其刪除

docker run --rm -i -v <absolute-path-to-your-project-locally>:/app -w /app node:10 npm install

如上所述暑脆,具有與Docker運行的Node不同的本地版本可能是有問題的。最好在容器內部運行命令以保持一致性狐肢。你可以進入一個容器

docker exec -it app bash

上面的命令將把你放到容器中添吗,這樣你就可以繼續(xù)從里面運行命令,即npm run start或npm run test

如果您不想進入容器內部份名,可以運行這樣的命令

docker exec -t app bash -c "npm run start"

參考文章:

在Docker快速部署Node.js應用的詳細步驟

詳解nodejs之創(chuàng)建最小docker鏡像

文章同步發(fā)布: https://www.geek-share.com/detail/2753888141.html

?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末碟联,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子同窘,更是在濱河造成了極大的恐慌玄帕,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,948評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件想邦,死亡現場離奇詭異裤纹,居然都是意外死亡,警方通過查閱死者的電腦和手機丧没,發(fā)現死者居然都...
    沈念sama閱讀 90,371評論 3 385
  • 文/潘曉璐 我一進店門鹰椒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人呕童,你說我怎么就攤上這事漆际。” “怎么了夺饲?”我有些...
    開封第一講書人閱讀 157,490評論 0 348
  • 文/不壞的土叔 我叫張陵奸汇,是天一觀的道長施符。 經常有香客問我,道長擂找,這世上最難降的妖魔是什么戳吝? 我笑而不...
    開封第一講書人閱讀 56,521評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮贯涎,結果婚禮上听哭,老公的妹妹穿的比我還像新娘。我一直安慰自己塘雳,他們只是感情好陆盘,可當我...
    茶點故事閱讀 65,627評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著败明,像睡著了一般隘马。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上肩刃,一...
    開封第一講書人閱讀 49,842評論 1 290
  • 那天祟霍,我揣著相機與錄音杏头,去河邊找鬼盈包。 笑死,一個胖子當著我的面吹牛醇王,可吹牛的內容都是我干的呢燥。 我是一名探鬼主播,決...
    沈念sama閱讀 38,997評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼寓娩,長吁一口氣:“原來是場噩夢啊……” “哼叛氨!你這毒婦竟也來了?” 一聲冷哼從身側響起但校,我...
    開封第一講書人閱讀 37,741評論 0 268
  • 序言:老撾萬榮一對情侶失蹤歇式,失蹤者是張志新(化名)和其女友劉穎大脉,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體仁连,經...
    沈念sama閱讀 44,203評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,534評論 2 327
  • 正文 我和宋清朗相戀三年阱穗,在試婚紗的時候發(fā)現自己被綠了饭冬。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,673評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡揪阶,死狀恐怖昌抠,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情鲁僚,我是刑警寧澤炊苫,帶...
    沈念sama閱讀 34,339評論 4 330
  • 正文 年R本政府宣布裁厅,位于F島的核電站,受9級特大地震影響侨艾,放射性物質發(fā)生泄漏姐直。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,955評論 3 313
  • 文/蒙蒙 一蒋畜、第九天 我趴在偏房一處隱蔽的房頂上張望声畏。 院中可真熱鬧,春花似錦姻成、人聲如沸插龄。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,770評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽均牢。三九已至,卻和暖如春才睹,著一層夾襖步出監(jiān)牢的瞬間徘跪,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,000評論 1 266
  • 我被黑心中介騙來泰國打工琅攘, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留垮庐,地道東北人。 一個月前我還...
    沈念sama閱讀 46,394評論 2 360
  • 正文 我出身青樓坞琴,卻偏偏與公主長得像哨查,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子剧辐,可洞房花燭夜當晚...
    茶點故事閱讀 43,562評論 2 349

推薦閱讀更多精彩內容

  • 以下原文轉載于(https://docs.docker.com/docker-for-mac/)(想找中文版的最新...
    Veekend閱讀 7,548評論 0 17
  • 上一篇大概介紹了JWT的用法寒亥,實現了一個簡單的登錄注冊以及郵箱驗證。而這一篇呢就負責把我們的項目部署到自己的服務器...
    sidiWang閱讀 10,362評論 2 48
  • 夜半三更荧关,更衣起身溫度宜人溉奕,路上無燈妙哉,妙哉正逢夜宵時分尋一處屎坑忍啤,落下加勤,開整自然是一方霸主,徒孫萬千千挑萬選之...
    馬不理饅頭閱讀 293評論 0 0
  • 【日精進打卡第122天】 【知~學習】 《六項精進》5遍 共438遍 《大學》5遍 共436遍 【經典名句分享】 ...
    湯京潤0第361期0感謝三組閱讀 102評論 0 0
  • 二十年前登此峰檀轨,不知孤嶺有詩翁胸竞。 昔時浪子頭將白,是日銀山花正紅参萄。 曾嘆椽梁湮夏草卫枝,今臨云閣沐春風。 江邊依舊他鄉(xiāng)...
    8Lollipop閱讀 326評論 0 0