簡介
docker容器的出現,徹底的改變了應用程序的運行方式,而nodejs同樣的也顛覆了後端應用程序的開發模式。兩者結合起來,就會產生意想不到的作用。
本文將會以一個常用的nodejs程序爲例,分析怎麼使用docker來構建nodejs image.
準備nodejs應用程序
一個標準的nodejs程序,需要一個package.json文件來描述應用程序的元數據和依賴關係,然後通過npm install來安裝應用的依賴關係,最後通過node app.js來運行程序。
本文將會創建一個簡單的koa應用程序,來說明docker的使用。
首先創建package.json文件:
上面的package.json文件制定了項目的依賴。
接下來,我們需要使用npm install來安裝項目的依賴,安裝好的項目依賴文件將會放在本地的node_modules文件夾中。
然後我們就可以編寫服務程序了:
上面是一個非常簡單的koa服務端程序,監聽在3000端口,並且對每次請求都會返回‘Hello www.flydean.com’。
運行node app.js 我們就可以開啓web服務了。
好了,我們的服務程序搭建完畢,接下來,我們看一下docker打包nodejs程序的最佳實踐。
創建Dockerfile文件
爲了創建docker image,我們需要一個Dockerfile文件,作爲該image的描述。
我們一步一步的講解,如何創建這個Dockerfile文件。
引入base image。
爲了運行docker程序,我們需要指定一個基本的image,比如操作系統,node爲我們提供了一個封裝好的image,我們可以直接引用:
我們指定了node的12版本,這個版本已經安裝好了最新的LTS node 12,使用這個image我們就可以不需要自己來安裝node的相關環境,非常的方便。
指定工作目錄
有了image,接下來就需要我們指定docker中的工作目錄:
安裝node_modules
接下來我們需要將package*.json文件拷貝進image中,並且運行npm install來安裝依賴庫:
上面我們拷貝的是package*.json,因爲如果我們本地運行過npm install命令的話,將會生成一個pacakge-lock.json文件。這個文件是爲了統一依賴包版本用的。我們需要一併拷貝。
拷貝完之後就可以運行npm install來安裝依賴包了。
問題?爲什麼我們只拷貝了pacakge.json,而不是拷貝整個工作目錄呢?
回答:docker file中的每一個命令,都會導致創建一個新的layer,上面的docker file中,只要pakage.json沒有被修改,新創建的docker image其實是可以共享layer緩存的。
但是如果我們直接添加本地的工作目錄,那麼只要我們的工作目錄有文件被修改,會導致整個docker image重新構建。所以爲了提升構建效率和速度,我們只拷貝package.json。
拷貝應用程序並運行
最後的工作就是拷貝應用程序app.js然後運行了:
最後,我們的dockerfile文件應該是這樣的:
創建.dockerignore文件
我們知道git會有一個.gitignore文件,同樣的docker也有一個.dockerignore文件,這個文件的作用就是避免你的本地文件被拷貝到docker image中。
比如我們可以在其中指定node_modules,使其不會被拷貝。
創建docker image
創建docker image很簡單,我們可以使用下面的命令:
創建完畢之後,我們可以使用docker images來查看剛剛創建好的image :
運行docker程序
最後,我們可以通過docker run命令來運行應用程序
然後我們就可以通過本地的54321端口來訪問應用程序了。
node的docker image需要注意的事項
這裏我們來探討一下創建docker image需要注意的事項。
不要使用root用戶來運行應用程序
默認情況下,docker中的應用程序會以root用戶來運行,爲了安全起見,建議大家以普通用戶來運行應用程序,我們可以在docker file中指定:
或者我們在運行的時候以 -u “node” 作爲啓動參數來指定運行的用戶。
指定運行時候的NODE_ENV
node的應用程序很多時候需要依賴於NODE_ENV來指定運行時環境,我們可以以參數的形式傳遞給docker run命令:
本文分享自微信公衆號 - 程序那些事(flydean-tech)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。