欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Node.js服務(wù)Docker容器化應用實踐小結(jié)

 更新時間:2019年09月27日 16:01:57   作者:五月君  
這篇文章主要介紹了Node.js服務(wù)Docker容器化應用實踐,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

本篇不會講解 Docker 命令的使用、安裝等,因為在之前一篇文章一文零基礎(chǔ)教你學會 Docker 入門到實踐中也已經(jīng)講解的很詳細了,不清楚的可以點擊鏈接回頭在重新看下,本篇重點是介紹 Node.js 項目如何進行 Docker 容器化及一些實踐優(yōu)化,還有一些常見的問題,當然如果還有其它使用上的問題也歡迎大家在評論區(qū)進行留言補充。

作者簡介:五月君,Nodejs Developer,熱愛技術(shù)、喜歡分享的 90 后青年,公眾號「Nodejs技術(shù)棧」,Github 開源項目 www.nodejs.red

通過本篇文章能學到什么?

  • 學會如何用 Docker 容器化一個 Node.js 服務(wù)
  • 動態(tài)設(shè)置環(huán)境變量一份 Dockerfile 文件構(gòu)建不同的版本
  • Node.js 私有 NPM 包在構(gòu)建鏡像時如何認證
  • Egg.js 框架 Docker 容器化應該注意的問題
  • Docker 鏡像體積與構(gòu)建時間的優(yōu)化

Docker 化一個 Node.js 應用程序

在本篇開始我們先創(chuàng)建一個簡單的 Node.js 應用,然后為這個應用創(chuàng)建一個 Docker 鏡像,并構(gòu)建和運行它

創(chuàng)建 Node.js 項目

首先我們需要創(chuàng)建一個 app.js 開啟一個 HTTP 服務(wù),后面會借助 Docker 來運行這個程序

const http = require('http');
const PORT = 30010;

const server = http.createServer((req, res) => {
 res.end('Hello Docker');
})

server.listen(PORT, () => {
 console.log('Running on http://localhost:', PORT, 'NODE_ENV', process.env.NODE_ENV);
});

然后我們創(chuàng)建一個 package.json 文件,這里是描述你的應用程序以及需要的依賴,寫過 Node.js 的同學應該會很熟悉的,這里我在 scripts 里面增加了npm run devnpm run pro兩個命令,因為我想在這里介紹如何在構(gòu)建時傳入?yún)?shù)來動態(tài)設(shè)置環(huán)境變量。

{ 
 "name": "hello-docker", 
 "version": "1.0.2",
 "description": "", 
 "author": "May",
 "main": "app.js", 
 "scripts": {
 "dev": "NODE_ENV=dev node app.js",
 "pro": "NODE_ENV=pro node app.js"
 }
}

Dockerfile 文件

這是一個 Dockerfile 文件所包含的信息,這些命令在Docker 入門與實踐中也有講解過

FROM node:10.0-alpine

RUN apk --update add tzdata \
 && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
 && echo "Asia/Shanghai" > /etc/timezone \
 && apk del tzdata

RUN mkdir -p /usr/src/nodejs/

WORKDIR /usr/src/nodejs/

# add npm package
COPY package.json /usr/src/nodejs/package.json
RUN cd /usr/src/nodejs/
RUN npm i

# copy code
COPY . /usr/src/nodejs/

EXPOSE 30010

CMD npm run dev

在 Dockerfile 的同級文件下創(chuàng)建一個 .dockerignore 文件,避免將你本地的調(diào)試文件、node_modules 等一些文件放入 Docker 容器中

.git
node_modules
npm-debug.log

此時通過以下命令即可構(gòu)建一個 Docker 鏡像

$ docker image build -t mayjun/hello-docker

再通過 docker run -d -p 30010:30010 mayjun/hello-docker 命令可運行一個 Docker 容器,但是有個疑問我是有生產(chǎn)和測試之分的,按照上面CMD npm run dev這樣寫死只能打包一種環(huán)境,當然你也可以在建一個文件來實現(xiàn)或者一些其它的方法。

動態(tài)設(shè)置環(huán)境變量

為了解決上面的疑問,我的想法是在鏡像構(gòu)建時傳入?yún)?shù)來動態(tài)設(shè)置環(huán)境變量,對 Dockerfile 文件做下修改,看以下實現(xiàn):

EXPOSE 30010

ARG node_env # 新增加
ENV NODE_ENV=$node_env # 新增加
CMD npm run ${NODE_ENV} # 修改

下面對上面的代碼做個解釋

  • 通過 ARG 指令定義了一個變量,用戶可以在構(gòu)建時通過使用 --build-arg = 標志的 docker build 命令將其傳遞給構(gòu)建器 ARG node_env
  • 在 Dockerfile 中使用 ENV 引用這個變量 ENV NODE_ENV=$node_env
  • 這一步就是使用了 CMD npm run ${NODE_ENV}

剩下的就是在構(gòu)建鏡像時動態(tài)傳入?yún)?shù)了

$ docker image build --build-arg node_env=dev -t mayjun/hello-docker:1.0.2 . # 構(gòu)建測試環(huán)境
$ docker image build --build-arg node_env=pro -t mayjun/hello-docker:1.0.2 . # 構(gòu)建生產(chǎn)環(huán)境

運行容器

$ docker run -d -p 30010:30010 mayjun/hello-docker:1.0.2
$ docker ps
CONTAINER ID IMAGE   COMMAND   CREATED  STATUS  PORTS   NAMES
2bc6e62cd0e8 mayjun/hello-docker:1.0.2 "/bin/sh -c 'npm run…" 3 minutes ago Up 3 minutes 0.0.0.0:30010->30010/tcp elastic_bouman

查看容器日志

docker logs -f 2bc6e62cd0e8

> hello-docker@1.0.0 dev /usr/src/nodejs
> NODE_ENV=dev node app.js

Running on http://localhost: 30010 NODE_ENV dev

我將以上代碼打包成了鏡像 mayjun/hello-docker:1.0.2,可以拉取查看 docker pull mayjun/hello-docker:1.0.2

Docker 與 Node.js 私有 NPM 包

如果你的項目中使用了私有 NPM 包,在 Dcoker 構(gòu)建鏡像過程中會出現(xiàn) npm 私有包安裝 404 的錯誤,如果是在容器外部我們可以 npm login 登陸擁有 NPM 私有包權(quán)限的賬戶,來解決這個問題,但是在 Docker 的時候是不能這樣做的。

創(chuàng)建身份驗證令牌

為了安裝私有包我們需要 “創(chuàng)建身份驗證令牌” 以便在持續(xù)集成環(huán)境、Docker 容器內(nèi)部能訪問我們的私有 NPM 包,如何創(chuàng)建可參考https://docs.npmjs.com/creating-and-viewing-authentication-tokens

實現(xiàn)方法

我們在創(chuàng)建 Dockerfile 文件過程中就需要增加以下兩條命令:

# 528das62-e03e-4dc2-ba67-********** 這個 Token 就為你創(chuàng)建的身份驗證令牌 token
RUN echo "http://registry.npmjs.org/:_authToken=528das62-e03e-4dc2-ba67-**********" > /root/.npmrc
RUN cat /root/.npmrc

Egg 框架 Docker 容器化

在 Egg 里面,如果是egg-scripts start --daemon,去掉 --daemon直接 egg-scripts start 即可,否則 Docker 容器會無法啟動。

看以下代碼示例,修改下 package.json 即可,Dockerfile 文件同上面第一個Docker 化一個 Node.js 應用程序是一樣的

package.json

{
 "scripts": {
 "start": "egg-scripts start" // 去掉 --daemon
 }
}

也可參考 Egg Issues “docker容器不能run起來,請問有碰到的嗎?”https://github.com/eggjs/egg/issues/1543

Docker 鏡像體積與構(gòu)建時間優(yōu)化

如果一個鏡像在不經(jīng)過優(yōu)化的情況下體積通常都是會很大的,以下也是在實踐過程中做的幾點優(yōu)化。

RUN/COPY 分層

Dockerfile 中的每條指令都會創(chuàng)建一個鏡像層,Dockerfile 指令或復制的項目文件在沒有修改變動的情況下,每個鏡像層是可以被復用和緩存的。

以下代碼可在 mayjun/hello-docker:latest 鏡像倉庫找到,以下示例中,源碼改變之后,不管 package.json 有沒有改變的情況下都會重新安裝 NPM 模塊,這樣顯然是不好的,因此下面我們要改進

# ...

WORKDIR /usr/src/nodejs/hello-docker
COPY . /usr/src/nodejs/hello-docker

RUN npm install

# ...

改進之后的代碼如下所示,我們讓 package.json 提前,在 package.json 沒有修改的情況下是不會重新安裝 NPM 包的,也會減少部署的時間。

# ...

WORKDIR /usr/src/nodejs/

# add npm package
COPY package.json /usr/src/app/package.json
RUN cd /usr/src/app/
RUN npm i

# copy code
COPY . /usr/src/app/

# ...

Node.js Alpine 鏡像優(yōu)化

mayjun/hello-docker:1.0.0 這個鏡像在 Docker 倉庫也可搜索到,在未優(yōu)化之前大約在 688MB

$ docker imagesREPOSITORY TAG IMAGE ID CREATED SIZEmayjun/hello-docker 1.0.0 7217fb3e9daa 5 seconds ago 688MB

使用 Alpine 優(yōu)化

Alpine 是一個很小的 Linux 發(fā)行版,想要大幅度減小鏡像體積選擇 Node.js 的 Alpine 版本也是最簡單的,另外 -alpine 的時區(qū)默認不是國內(nèi)的,需要 Dockerfile 配置時區(qū)。

FROM node:10.0-alpine

RUN apk --update add tzdata \
 && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
 && echo "Asia/Shanghai" > /etc/timezone \
 && apk del tzdata

RUN echo "Asia/Shanghai" > /etc/timezone

RUN mkdir -p /usr/src/nodejs/

WORKDIR /usr/src/nodejs/

# add npm package
COPY package.json /usr/src/app/package.json
RUN cd /usr/src/app/
RUN npm i

# copy code
COPY . /usr/src/app/

EXPOSE 30010
CMD npm start

重新打包了一個版本 mayjun/hello-docker:1.1.0 再次查看下效果,可以看到鏡像文件從 688MB 減少至 85.3MB,這個體積優(yōu)化還是很大的

$ docker images
REPOSITORY  TAG   IMAGE ID  CREATED  SIZE
mayjun/hello-docker 1.1.0  169e05b8197d 3 minutes ago 85.3MB

生產(chǎn)環(huán)境不要打包 devDependencies 包

有些測試環(huán)境用的包,在進行生產(chǎn)環(huán)境打鏡像時不要包含進去,也就是 package.json 文件 devDependencies 對象,通過在 npm i 之后指定 --production 參數(shù)過濾

改進如下所示:

FROM node:10.0-alpine

# 省略 ...

# add npm package
COPY package.json /usr/src/app/package.json
RUN cd /usr/src/app/
RUN npm i --production # 改變在這了

# 省略 ...

重新打包了一個版本 mayjun/hello-docker:1.2.0 再次查看下效果,可以看到鏡像文件從 85.3MB 又減少至 72.3MB

$ docker images
REPOSITORY  TAG   IMAGE ID  CREATED  SIZE
mayjun/hello-docker 1.2.0  f018aa578711 3 seconds ago 72.3MB

常見問題

Question1

以下命令在刪除鏡像的時候報如下錯誤:

$ docker rmi 6b1c2775591e
Error response from daemon: conflict: unable to delete 6b1c2775591e (must be forced) - image is referenced in multiple repositories

細心的你也許會發(fā)現(xiàn)鏡像 ID 6b1c2775591e 同時指向了 hello-docker 和 mayjun/hello-docker 倉庫,這也是造成刪除失敗的原因

$ docker images
REPOSITORY  TAG   IMAGE ID  CREATED  SIZE
mysql   5.7   383867b75fd2 6 days ago  373MB
hello-docker  latest  6b1c2775591e 7 days ago  675MB
mayjun/hello-docker latest  6b1c2775591e 7 days ago  675MB

指定 repository 和 tag 來刪除,執(zhí)行刪除命令之后再次查看 mayjun/hello-docker 倉庫就已經(jīng)沒有了

$ docker rmi mayjun/hello-docker
$ docker images   
REPOSITORY  TAG   IMAGE ID  CREATED  SIZE
mysql  5.7   383867b75fd2 6 days ago  373MB
hello-docker latest  6b1c2775591e 7 days ago  675MB

Question2

執(zhí)行刪除鏡像命令報如下錯誤:

$ docker rmi 9be467fd1285
Error response from daemon: conflict: unable to delete 9be467fd1285 (cannot be forced) - image is being used by running container 1febfb05b850

根據(jù)提示是有正在運行的容器,需先停止容器、刪除容器之后在刪除鏡像

$ docker container kill 1febfb05b850 # 停止容器
$ docker rm 1febfb05b850 # 刪除容器
$ docker rmi 9be467fd1285 # 刪除鏡像

Question3

設(shè)定的工作目錄(WORKDIR)要與下面的要保持一致

...
WORKDIR /usr/src/nodejs/

# add npm package
COPY package.json /usr/src/node/package.json # 目錄不一致
RUN cd /usr/src/node/ # 目錄不一致
RUN npm i
...

例如,如以上配置因為工作目錄與實際 COPY 的目錄不一致,會導致報以下錯誤:

再按照以下方式更改為一致即可

...
WORKDIR /usr/src/nodejs/

# add npm package
COPY package.json /usr/src/nodejs/package.json # 更改為一致
RUN cd /usr/src/nodejs/ # 更改為一致
RUN npm i
...

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Docker方式啟動tomcat訪問首頁出現(xiàn)404錯誤

    Docker方式啟動tomcat訪問首頁出現(xiàn)404錯誤

    這篇文章主要介紹了Docker方式啟動tomcat訪問首頁出現(xiàn)404錯誤。文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-12-12
  • docker自定義鏡像構(gòu)建php7的方法

    docker自定義鏡像構(gòu)建php7的方法

    這篇文章主要介紹了docker自定義鏡像構(gòu)建php7的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-11-11
  • 如何下載docker日志到本地

    如何下載docker日志到本地

    這篇文章主要介紹了如何下載docker日志到本地問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • docker-compose中的環(huán)境變量問題

    docker-compose中的環(huán)境變量問題

    這篇文章主要介紹了docker-compose中的環(huán)境變量問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • Docker容器Consul部署概述

    Docker容器Consul部署概述

    這篇文章主要介紹了Docker容器Consul部署概述,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的朋友可以參考一下
    2022-08-08
  • docker容器內(nèi)要啟動兩個進程時Dockerfile的實現(xiàn)代碼

    docker容器內(nèi)要啟動兩個進程時Dockerfile的實現(xiàn)代碼

    這篇文章主要介紹了docker容器內(nèi)要啟動兩個進程時Dockerfile的實現(xiàn)代碼,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-11-11
  • Mac為docker和kubectl添加自動補全命令的方法

    Mac為docker和kubectl添加自動補全命令的方法

    很多朋友不太明白如何為docker和kubectl添加自動補全命令,本文通過一些示例給大家介紹kubectl基礎(chǔ)概念及語法知識,需要的朋友參考下吧
    2021-06-06
  • 云centos開啟docker遠程服務(wù)鏈接的實現(xiàn)步驟

    云centos開啟docker遠程服務(wù)鏈接的實現(xiàn)步驟

    本文主要介紹了云centos開啟docker遠程服務(wù)鏈接,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • docker search 搜索鏡像的實現(xiàn)示例

    docker search 搜索鏡像的實現(xiàn)示例

    本文主要介紹了docker search搜索鏡像的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,需要的朋友們下面隨著小編來一起學習學習吧
    2024-02-02
  • CentOS7.2服務(wù)器上搭建Docker私有鏡像倉庫操作示例

    CentOS7.2服務(wù)器上搭建Docker私有鏡像倉庫操作示例

    這篇文章主要介紹了CentOS7.2服務(wù)器上搭建Docker私有鏡像倉庫操作,結(jié)合實例形式分析了基于CentOS7.2平臺docker安裝、證書和密鑰生成、私有鏡像創(chuàng)建與啟動等操作相關(guān)命令與使用技巧,需要的朋友可以參考下
    2018-06-06

最新評論