使用nodejs構建Docker image最佳實踐

簡介

docker容器的出現,完全的改變了應用程序的運行方式,而nodejs一樣的也顛覆了後端應用程序的開發模式。二者結合起來,就會產生意想不到的做用。node

本文將會以一個經常使用的nodejs程序爲例,分析怎麼使用docker來構建nodejs image.git

準備nodejs應用程序

一個標準的nodejs程序,須要一個package.json文件來描述應用程序的元數據和依賴關係,而後經過npm install來安裝應用的依賴關係,最後經過node app.js來運行程序。web

本文將會建立一個簡單的koa應用程序,來講明docker的使用。docker

首先建立package.json文件:npm

{
  "name": "koa-docker",
  "description": "怎麼將nodejs koa程序打包成docker應用",
  "version": "0.0.1",
  "dependencies": {
    "ejs": "^2.5.6",
    "fs-promise": "^2.0.3",
    "koa": "^2.2.0",
    "koa-basic-auth": "^2.0.0",
    "koa-body": "^4.0.8",
    "koa-compose": "^4.0.0",
    "koa-csrf": "^3.0.6",
    "koa-logger": "^3.0.0",
    "@koa/router": "^8.0.5",
    "koa-session": "^5.0.0",
    "koa-static": "^3.0.0",
    "koa-views": "^6.0.2"
  },
  "scripts": {
    "test": "NODE_ENV=test mocha --harmony --reporter spec --require should */test.js",
    "lint": "eslint ."
  },
  "engines": {
    "node": ">= 7.6"
  },
  "license": "MIT"
}

上面的package.json文件制定了項目的依賴。json

接下來,咱們須要使用npm install來安裝項目的依賴,安裝好的項目依賴文件將會放在本地的node_modules文件夾中。後端

而後咱們就能夠編寫服務程序了:promise

const Koa = require('koa');
const app = module.exports = new Koa();

app.use(async function(ctx) {
  ctx.body = 'Hello www.flydean.com';
});

if (!module.parent) app.listen(3000);

上面是一個很是簡單的koa服務端程序,監聽在3000端口,而且對每次請求都會返回‘Hello www.flydean.com’。緩存

運行node app.js 咱們就能夠開啓web服務了。安全

好了,咱們的服務程序搭建完畢,接下來,咱們看一下docker打包nodejs程序的最佳實踐。

建立Dockerfile文件

爲了建立docker image,咱們須要一個Dockerfile文件,做爲該image的描述。

咱們一步一步的講解,如何建立這個Dockerfile文件。

  1. 引入base image。

爲了運行docker程序,咱們須要指定一個基本的image,好比操做系統,node爲咱們提供了一個封裝好的image,咱們能夠直接引用:

FROM node:12

咱們指定了node的12版本,這個版本已經安裝好了最新的LTS node 12,使用這個image咱們就能夠不須要本身來安裝node的相關環境,很是的方便。

  1. 指定工做目錄

有了image,接下來就須要咱們指定docker中的工做目錄:

# Create app directory
WORKDIR /data/app
  1. 安裝node_modules

接下來咱們須要將package*.json文件拷貝進image中,而且運行npm install來安裝依賴庫:

COPY package*.json ./

RUN 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。

  1. 拷貝應用程序並運行

最後的工做就是拷貝應用程序app.js而後運行了:

# 拷貝應用程序
COPY app.js .

# 暴露端口
EXPOSE 8080

# 運行命令
CMD [ "node", "app.js" ]

最後,咱們的dockerfile文件應該是這樣的:

FROM node:12

# Create app directory
WORKDIR /data/app

COPY package*.json ./

RUN npm install

# 拷貝應用程序
COPY app.js .

# 暴露端口
EXPOSE 8080

# 運行命令
CMD [ "node", "app.js" ]

建立.dockerignore文件

咱們知道git會有一個.gitignore文件,一樣的docker也有一個.dockerignore文件,這個文件的做用就是避免你的本地文件被拷貝到docker image中。

node_modules

好比咱們能夠在其中指定node_modules,使其不會被拷貝。

建立docker image

建立docker image很簡單,咱們可使用下面的命令:

docker build -t flydean/koa-web-app .

建立完畢以後,咱們可使用docker images來查看剛剛建立好的image :

docker images

# Example
REPOSITORY                      TAG        ID              CREATED
node                            12         1934b0b038d1    5 days ago
flydean/koa-web-app             latest     d64d3505b0d2    1 minute ago

運行docker程序

最後,咱們能夠經過docker run命令來運行應用程序

docker run -p 54321:8080 -d flydean/koa-web-app

而後咱們就能夠經過本地的54321端口來訪問應用程序了。

node的docker image須要注意的事項

這裏咱們來探討一下建立docker image須要注意的事項。

  1. 不要使用root用戶來運行應用程序

默認狀況下,docker中的應用程序會以root用戶來運行,爲了安全起見,建議你們以普通用戶來運行應用程序,咱們能夠在docker file中指定:

FROM node:12
...
# 在最後,以node用戶來運行應用程序
USER node

或者咱們在運行的時候以 -u "node" 做爲啓動參數來指定運行的用戶。

docker run \
  -u "node"
  flydean/koa-web-app
  1. 指定運行時候的NODE_ENV

node的應用程序不少時候須要依賴於NODE_ENV來指定運行時環境,咱們能夠以參數的形式傳遞給docker run命令:

docker run \
-e "NODE_ENV=production"
  flydean/koa-web-app
本文做者:flydean程序那些事

本文連接:http://www.flydean.com/nodejs-docker-best-practices/

本文來源:flydean的博客

歡迎關注個人公衆號:「程序那些事」最通俗的解讀,最深入的乾貨,最簡潔的教程,衆多你不知道的小技巧等你來發現!

相關文章
相關標籤/搜索