Docker1:部署Node應用

什么事Docker

????docker是一個開源的應用容器引擎,可以為我們提供安全、可移植、可重復的自動化部署的方式。docker采用虛擬化的技術來虛擬化出應用程序的運行環(huán)境。此種方式具有以下優(yōu)勢:

? ?????1、 每個部署的應用程序都是一個容器,彼此隔離,互不影響;

? ?????2、 服務器只需要安裝docker即可運行構(gòu)建好的應用程序鏡像,不會涉及復雜的服務器環(huán)境配置,因為配置都在特定的應用程序所在的鏡像中去配置即可;

? ????? 3、簡化了自動化部署和運維的繁瑣流程,只需將構(gòu)建好的鏡像load到服務器的docker中即可運行我們的應用程序;

? ????? 4、可以充分利用服務器的系統(tǒng)資源,一臺服務器上可以同時運行多個容器;

????docker采用的是c/s架構(gòu),Client通過接口與Server進程通信實現(xiàn)容器的構(gòu)建,運行和發(fā)布。docker比較重要的三個核心概念如下:

? ??????鏡像(images):一個只讀的模板,可以理解為應用程序的運行環(huán)境,包含了程序運行所依賴的環(huán)境和基本配置,鏡像可以按照層級(從基礎鏡像開始)來構(gòu)建,每一層包含特定的環(huán)境。

? ??????倉庫(repository):一個用于存放鏡像文件的倉庫,如果你對git的倉庫熟悉,應該很容易理解,對,就是那個。有私有倉庫和公有倉庫之分。

? ??????容器(container):一個運行應用程序的虛擬容器,在我們運行鏡像時產(chǎn)生。容器包含自己的文件系統(tǒng)+隔離的進程空間和包含其中的進程。

實戰(zhàn)開始

1、環(huán)境準備

安裝docker,未安裝的同學,請根據(jù)自己的開發(fā)環(huán)境采用不同的安裝方式去安裝,具體操作參考教程,不做贅述。

安裝成功后,可以通過docker -v查看版本號(盡量使用最新的穩(wěn)定版本)。

2、項目準備

在你的項目根目錄下,添加Dockerfile文件,此文件用來配置我們自定義一個鏡像所需要指定的依賴項、環(huán)境以及執(zhí)行的命令等。內(nèi)容格式如下:

# 指定我們的基礎鏡像是node,版本是v8.0.0

FROM node:8.0.0?

# 指定制作我們的鏡像的聯(lián)系人信息(鏡像創(chuàng)建者)

MAINTAINER EOI

# 將根目錄下的文件都copy到container(運行此鏡像的容器)文件系統(tǒng)的app文件夾下

ADD . /app/?

#cd到app文件夾下

WORKDIR /app

# 安裝項目依賴包

RUN npm install?

RUN npm rebuild node-sass --force

# 配置環(huán)境變量

ENV HOST 0.0.0.0?

ENV PORT 8000

# 容器對外暴露的端口號

EXPOSE 8000

# 容器啟動時執(zhí)行的命令,類似npm run start

CMD ["npm", "start"]

關于Dockerfile文件中的關鍵字,解釋如下:

FROM

MAINTAINER

語法:MAINTAINER解釋:MAINTAINER指令允許你給將要制作的鏡像設置作者信息。

ADD

語法:ADD解釋:ADD指令用于從指定路徑拷貝一個文件或目錄到容器的指定路徑中,是一個文件或目錄的路徑,也可以是一個url,路徑是相對于該Dockerfile文件所在位置的相對路徑,是目標容器的一個絕對路徑。

WORKDIR

語法:WORKDIR/path/to/workdir 解釋:WORKDIR指令用于設置Dockerfile中的RUN、CMD和ENTRYPOINT指令執(zhí)行命令的工作目錄(默認為/目錄),該指令在Dockerfile文件中可以出現(xiàn)多次,如果使用相對路徑則為相對于WORKDIR上一次的值,例如WORKDIR /data,WORKDIR logs,RUN pwd最終輸出的當前目錄是/data/logs。

RUN

語法:① RUN #將會調(diào)用/bin/sh -c<command>② RUN ["executable","param1","param2"]#將會調(diào)用exec執(zhí)行,以避免有些時候shell方式執(zhí)行時的傳遞參數(shù)問題,而且有些基礎鏡像可能不包含/bin/sh解釋:RUN指令會在一個新的容器中執(zhí)行任何命令,然后把執(zhí)行后的改變提交到當前鏡像,提交后的鏡像會被用于Dockerfile中定義的下一步操作,RUN中定義的命令會按順序執(zhí)行并提交,這正是Docker廉價的提交和可以基于鏡像的任何一個歷史點創(chuàng)建容器的好處,就像版本控制工具一樣。

ENV

語法:ENV解釋:ENV指令用于設置環(huán)境變量,在Dockerfile中這些設置的環(huán)境變量也會影響到RUN指令,當運行生成的鏡像時這些環(huán)境變量依然有效,如果需要在運行時更改這些環(huán)境變量可以在運行docker run時添加–env=參數(shù)來修改。 注意:最好不要定義那些可能和系統(tǒng)預定義的環(huán)境變量沖突的名字,否則可能會產(chǎn)生意想不到的結(jié)果。

EXPOSE

語法:EXPOSE[ ...]解釋:EXPOSE指令用來告訴Docker這個容器在運行時會監(jiān)聽哪些端口,Docker在連接不同的容器(使用–link參數(shù))時使用這些信息。

CMD

語法: ①CMD["executable","param1","param2"]#將會調(diào)用exec執(zhí)行,首選方式②CMD["param1","param2"]#當使用ENTRYPOINT指令時,為該指令傳遞默認參數(shù)③CMD [ | ]#將會調(diào)用/bin/sh -c執(zhí)行解釋:CMD指令中指定的命令會在鏡像運行時執(zhí)行,在Dockerfile中只能存在一個,如果使用了多個CMD指令,則只有最后一個CMD指令有效。當出現(xiàn)ENTRYPOINT指令時,CMD中定義的內(nèi)容會作為ENTRYPOINT指令的默認參數(shù),也就是說可以使用CMD指令給ENTRYPOINT傳遞參數(shù)。注意:RUN和CMD都是執(zhí)行命令,他們的差異在于RUN中定義的命令會在執(zhí)行docker build命令創(chuàng)建鏡像時執(zhí)行,而CMD中定義的命令會在執(zhí)行docker run命令運行鏡像時執(zhí)行,另外使用第一種語法也就是調(diào)用exec執(zhí)行時,命令必須為絕對路徑。

其中還有其他的一些關鍵字:USER、ENTRYPOINT、VOLUME、ONBUILD等,如果你有興趣可以自行研究。

在項目根目錄下添加.dockerignore文件,此文件的作用類似.gitignore文件,可以忽略掉添加進鏡像中的文件,寫法、格式和.gitignore一樣,一行代表一個忽略。本項目添加的忽略如下:

.DS_Store?

npm-debug.log*?

selenium-debug.log

.nuxt/?

/package-lock.json?

*.tar?

*.md?

# Editor directoriesandfiles?

.idea?

*.suo?

*.ntvs*?

*.njsproj?

*.sln

構(gòu)建鏡像

查看目前本地docker的鏡像

> docker images

REPOSITORY? ? ? ? ? TAG? ? ? ? ? ? ? ? IMAGE ID? ? ? ? ? ? CREATED? ? ? ? ? ? SIZE

cd 到項目根目錄下,執(zhí)行以下命令

> docker build -t deploy:1.0?

deploy是鏡像名,1.0是鏡像的版本號,到此你已經(jīng)成功構(gòu)建了一個新的鏡像,你可以通過docker images,查看你的鏡像。

> docker images

REPOSITORY? ? ? ? ? TAG? ? ? ? ? ? ? ? IMAGE ID? ? ? ? ? ? CREATED? ? ? ? ? ? SIZE?

deploy? ? ? ? ? ? ? 1.0? ? ? ? ? ? ? ? d8f0875e967b? ? ? ? 3 minutes ago? ? ? ? 2.11GB

啟動鏡像,測試是否成功。

> docker run -d -p 9000:8000 deploy:1.0

8aec5ee037bb253901d2c2e02c7be546580546c493576139f3789fb660f3401d

> docker ps -a

CONTAINER ID? ? IMAGE? ? ? ? COMMAND? ? ? ? ? CREATED? ? ? ? ? STATUS? ? ? ? PORTS? ? ? ? ? ? ? ? ? NAMES

8aec5ee037bb? ? deploy:1.0? "npm start"? ? 57 seconds ago? ? Up 56 seconds? 0.0.0.0:9000->8000/tcp amazing_bassi

docker run -d -p 9000:8000 deploy:1.0中-d表示后臺運行,-p 9000:8000表示指定本地的9000端口隱射到容器內(nèi)的8000端口。?deploy:1.0為我們要運行的鏡像。通過docker ps -a查看docker的進程(容器的運行本身就是一種特殊的進程)運行情況,發(fā)現(xiàn)我們的容器已經(jīng)在運行。本地可以訪問localhost:9000。

通過docker logs可以查看我們?nèi)萜鲀?nèi)應用進程的運行日志。docker logs <CONTAINER ID>

> docker logs 8aec5ee037bb

npm info it worked if it ends with ok??

npm info using npm@5.0.0??

npm info using node@v8.0.0??

npm info lifecycle newlook-deploy@1.0.0~prestart: newlook-deploy@1.0.0?

?npm info lifecycle newlook-deploy@1.0.0~start: newlook-deploy@1.0.0??

> newlook-deploy@1.0.0 start /app? > node ./server/index.jsServer listening on 0.0.0.0:8000? DONE? Compiled successfully in 9310ms06:55:56? > Open http://0.0.0.0:8000

docker stop <CONTAINER ID>可以停止容器運行

docker start <CONTAINER ID>可以啟動容器運行

docker restart <CONTAINER ID>可以重啟容器

docker rm <CONTAINER ID> -f可以強制刪除在運行的容器

上傳鏡像(這里用上傳到公共倉庫來演示)

沒注冊DockerHub的同學,請注冊DockerHub

登錄docker

> docker login

Username: XXX

Password: XXXLogin

?Succeeded

docker tag <name:tag> <namespace>/<name:tag>上傳之前必須給鏡像打上tag,namespace可以指定為你的docker Id

>?docker tag deploy:1.0 lzqs/deploy:1.0

docker push <namespace>/<name:tag>將鏡像上傳至docker的公共倉庫

>?docker push lzqs/deploy:1.0

上傳成功后,docker logout?退出,登錄?https://hub.docker.com/?查看上傳的鏡像。

下載鏡像

通過docker pull <namespace>/<name:tag>下載我們的鏡像。

>?docker pull lzqs/deploy:1.0

生產(chǎn)部署

前面說了,我們可以將上傳到倉庫的鏡像下載下來部署,但是如果鏡像比較大或者部署環(huán)境壓根無法聯(lián)網(wǎng),你是不是要跪了。所以我們采取另一種方法,將開發(fā)好的鏡像直接打包保存到安裝盤里面,到客戶生產(chǎn)環(huán)境再將鏡像包上傳并加載到服務器的docker中即可。

在開發(fā)環(huán)境打包,docker save <namespace>/<name:tag> <name>.tar

>?docker save lzqs/deploy:1.0 > deploy.tar

這里ls會發(fā)現(xiàn)目錄下生成了deploy.tar的文件。部署時將此文件copy到生產(chǎn)環(huán)境服務器上。

確保生產(chǎn)服務器上已經(jīng)安裝了docker,若沒裝,請參考相關文檔,若不裝,對不起小生也無力了,然后在服務器上加載上傳的鏡像包deploy.tar。

> docker load < deploy.tar

007ab444b234: Loading layer [==================================================>] 129.3 MB/129.3 MB??

4902b007e6a7: Loading layer [==================================================>] 45.45 MB/45.45 MB?

?bb07d0c1008d: Loading layer [==================================================>] 126.8 MB/126.8 MB??

ecf5c2e2468e: Loading layer [==================================================>] 326.6 MB/326.6 MB??

7b3b4fef39c1: Loading layer [==================================================>] 352.3 kB/352.3 kB??

677f02386f07: Loading layer [==================================================>] 137.2 kB/137.2 kB??

7333bb4665b8: Loading layer [==================================================>] 55.66 MB/55.66 MB??

e292e64ffb88: Loading layer [==================================================>] 3.757 MB/3.757 MB??

ee76d0e6f6d9: Loading layer [==================================================>] 1.436 GB/1.436 GB??

33dca533c6e5: Loading layer [==================================================>] 331.8 kB/331.8 kB??

24630015679d: Loading layer [==================================================>] 35.18 MB/35.18 MB??

Loaded image: lzqs/deploy:1.0

加載成功后,docker images即可看到加載的鏡像

> docker images

REPOSITORY? ? ? ? ? TAG? ? ? ? ? ? ? ? IMAGE ID? ? ? ? ? ? CREATED? ? ? ? ? ? SIZE

lzqs/deploy? ? ? ? 1.0? ? ? ? ? ? ? ? d8f0875e967b? ? ? ? About an hour ago? 2.115 GB

運行l(wèi)zqs/deploy鏡像,成功后,在外部訪問服務器的9000端口,?<服務器的IP>:9000

> docker run -d -p 9000:8000 lzqs/deploy

1d0db9a5d0c8826171e501b0e86afd444fca8144b1105e63dae8d621bdda7a77

> docker ps -a

CONTAINER ID? IMAGE? ? ? ? ? COMMAND? ? ? CREATED? ? ? ? ? ? ? STATUS? ? ? ? ? ? PORTS? ? ? ? ? ? ? ? ? ? NAMES

1d0db9a5d0c8? lzqs/deploy:1.0 "npm start"? About a minute ago? Up About a minute? 0.0.0.0:9000->8000/tcp goofy_curran

docker exec -it <CONTAINER ID> /bin/bash?可以進入容器中執(zhí)行,方便我們查看內(nèi)部文件和調(diào)試

>dockerexec-it 1d0db9a5d0c8 /bin/bash

root@1d0db9a5d0c8:/app#

打完收工,可以再外邊訪問了

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容