Docker 搭建你的第一個 Node 項目到服務(wù)器

本文你能學(xué)到什么

Docker 是什么

Docker 概念

關(guān)于 Docker 的概念是確實不太好總結(jié)帕胆,下面我通過四點向你說明 Docker 到底是個什么東西召耘。

  • Docker 是世界領(lǐng)先的軟件容器平臺。
  • Docker 使用 Google 公司推出的 Go 語言 ?進(jìn)行開發(fā)實現(xiàn)军掂,基于 Linux 內(nèi)核 的cgroup轮蜕,namespace昨悼,以及 AUFS 類的 UnionFS 等技術(shù)蝗锥,對進(jìn)程進(jìn)行封裝隔離,屬于操作系統(tǒng)層面的虛擬化技術(shù)率触。由于隔離的進(jìn)程獨(dú)立于宿主和其它的隔離的進(jìn) 程终议,因此也稱其為容器。Docker 最初實現(xiàn)是基于 LXC.
  • Docker 能夠自動執(zhí)行重復(fù)性任務(wù)葱蝗,例如搭建和配置開發(fā)環(huán)境穴张,從而解放了開發(fā)人員以便他們專注在真正重要的事情上,構(gòu)建杰出的軟件两曼。
  • 用戶可以方便地創(chuàng)建和使用容器皂甘,把自己的應(yīng)用放入容器。容器還可以進(jìn)行版本管理悼凑、復(fù)制偿枕、分享、修改户辫,就像管理普通的代碼一樣渐夸。

Docker 的基本組成架構(gòu)

看一張 Docker 架構(gòu)圖

  1. 左邊大框框是我們進(jìn)行 Docker 操作的宿主機(jī),其運(yùn)行了一個 Docker daemon 的核心守護(hù)程序渔欢,負(fù)責(zé)構(gòu)建墓塌、運(yùn)行和分發(fā) Docker 容器。

  2. 在宿主機(jī)中安裝了 Docker 客戶端奥额,其與 Docker daemon 守護(hù)進(jìn)程進(jìn)行通信苫幢,客戶端會將 build、pull垫挨、run 等命令發(fā)送到 ?Docker daemon 守護(hù)進(jìn)程進(jìn)行執(zhí)行韩肝。

  3. 右框框為 Docker 注冊表存儲 Docker 鏡像,是一個所有 Docker 用戶共享 Docker 鏡像的服務(wù)棒拂,Docker daemon 守護(hù)進(jìn)程與之進(jìn)行交互伞梯。

下面是對架構(gòu)中基本組成說明玫氢,比較詳細(xì),大家看的時候可以對著架構(gòu)圖看谜诫。概念這個東西漾峡,你看下就好,怎么記都記不住的喻旷,只有你常用的東西才會記住和想著去記住它生逸,看完本文,可以把下面的應(yīng)用實踐一遍且预。

Registry

鏡像倉庫槽袄,存儲大量鏡像,可以從鏡像倉庫拉取和推送鏡像锋谐。

Docker 鏡像

類似虛擬機(jī)快照遍尺,從倉庫拉取,或者在現(xiàn)有工具鏡像上創(chuàng)建新鏡像涮拗。通過鏡像可以啟動容器乾戏。

Docker 容器

從鏡像中創(chuàng)建應(yīng)用環(huán)境,以單進(jìn)程的方式運(yùn)行三热。對外公開服務(wù)鼓择。是一種短暫的和一次性的環(huán)境。

Docker 數(shù)據(jù)卷

數(shù)據(jù)卷可以完成數(shù)據(jù)持久化就漾,數(shù)據(jù)卷是一個可供一個或多個容器使用的特殊目錄呐能,它繞過 UFS,可以提供很多有用的特性:

  • 數(shù)據(jù)卷可以在容器之間共享和重用
  • 對數(shù)據(jù)卷的修改會立馬生效
  • 對數(shù)據(jù)卷的更新抑堡,不會影響鏡像
  • 卷會一直存在摆出,直到?jīng)]有容器使用

Docker 網(wǎng)絡(luò)

Docker 容器之間的網(wǎng)絡(luò)交互,可以使用端口映射的方式夷野,其他容器可以直接通過端口實現(xiàn)懊蒸。除該方式外還有一個容器連接(linking)系統(tǒng)也可以達(dá)到容器交互。(本文中 node 連接 mongodb 使用的是端口映射的方式)

關(guān)于Docker 網(wǎng)絡(luò)模塊悯搔,容器連接詳情推薦這篇文章:Docker的網(wǎng)絡(luò)模式詳解

Docker 應(yīng)用場景

Docker 部署 Node 項目完整流程(DockerFile實踐)

  1. 使用 Koa2 初始化一個 Node 項目骑丸,通過 Mongose 中間件 連接 Mogodb 數(shù)據(jù)庫,實現(xiàn)一個基礎(chǔ)接口 Mogodb 插入數(shù)據(jù)妒貌。項目地址:https://github.com/koala-coding/dockerstudy

  2. 首先在項目根目錄下創(chuàng)建 .dockerignore 文件通危,把不需要打包進(jìn) Docker Image 里的文件進(jìn)行過濾

    # /usr/src/nodejs/dockerstudy/.dockerignore
    .git
    node_modules
  3. 在項目的根目錄中創(chuàng)建 Dockerfile 文件(Dockerfile 這里重點講一下)

    部署 Node項目 的時候,會有一個 Dockerfile 文件配置

    # /usr/src/nodejs/hello-docker/Dockerfile
    FROM node:10.0

    # 在容器中創(chuàng)建一個目錄
    RUN mkdir -p /usr/src/nodejs/

    # 定位到容器的工作目錄
    WORKDIR /usr/src/nodejs/

    # RUN/COPY 是分層的灌曙,package.json 提前菊碟,只要沒修改,就不會重新安裝包
    COPY package.json /usr/src/app/package.json
    RUN cd /usr/src/app/
    RUN npm i

    # 把當(dāng)前目錄下的所有文件拷貝到 Image 的 /usr/src/nodejs/ 目錄下
    COPY . /usr/src/nodejs/


    EXPOSE 3000
    CMD npm start

    配置參數(shù)說明( DockerFile 學(xué)習(xí)):

  • FROM:FROM 是構(gòu)建鏡像的基礎(chǔ)源鏡像在刺,該 Image 文件繼承官方的 node image逆害。

    詳細(xì)說明:Dockerfile 中 FROM 是必備的指令头镊,并且必須是第一條指令!它引入一個鏡像作為我們要構(gòu)建鏡像的基礎(chǔ)層魄幕,就好像我們首先要安裝好操作系統(tǒng)相艇,才可以在操作系統(tǒng)上面安裝軟件一樣。

  • RUN:后面跟的是在容器中要執(zhí)行的命令纯陨。

    詳細(xì)說明:每一個 RUN 指令都會新建立一層坛芽,在其上執(zhí)行這些命令,我們頻繁使用 RUN 指令會創(chuàng)建大量鏡像層翼抠,然而 Union FS 是有最大層數(shù)限制的咙轩,不能超過 127 層,而且我們應(yīng)該把每一層中我用文件清除阴颖,比如一些沒用的依賴活喊,來防止鏡像臃腫。

  • WORKDIR:容器的工作目錄

  • COPY:拷貝文件至容器的工作目錄下膘盖,.dockerignore 指定的文件不會拷貝

  • EXPOSE:將容器內(nèi)的某個端口導(dǎo)出供外部訪問

  • CMD:Dockerfile 執(zhí)行寫一個 CMD 否則后面的會被覆蓋胧弛,CMD 后面的命令是容器每次啟動執(zhí)行的命令尤误,多個命令之間可以使用 && 鏈接侠畔,例如 CMD git pull && npm start

    詳細(xì)說明:CMD 指令用來在啟動容器的時候,指定默認(rèn)的容器主進(jìn)程的啟動命令和參數(shù)损晤。它有兩種形式

    CMD echo 1
    CMD ["npm", "run", "test"] 必須是雙引號

    第一種執(zhí)行的命令會被包裝程软棺,CMD [ "sh", "-c", "echo 1" ] JSON 數(shù)組形式,一般推薦 JSON 數(shù)組形式尤勋。容器中的應(yīng)用都應(yīng)該以前臺執(zhí)行喘落,而不是啟動后臺服務(wù),容器內(nèi)沒有后臺服務(wù)的概念最冰。對于容器而言瘦棋,其啟動程序就是容器應(yīng)用進(jìn)程,容器就是為了主進(jìn)程而存在的暖哨,主進(jìn)程退出赌朋,容器就失去了存在的意義篇裁。比如 CMD service nginx start 它等同于 CMD [ "sh", "-c", "service nginx start"] 主進(jìn)程實際上是 sh沛慢,sh 也就結(jié)束了,sh 作為主進(jìn)程退出了团甲。

  • ENV(補(bǔ)充)

    ENV 指令用來設(shè)置環(huán)境變量身腻,它有兩種形式:

    ENV <key> <value>
    ENV <key1>=<value1> <key2>=<value2>...

    定義了環(huán)境變量霸株,那么在后續(xù)的指令中,就可以使用這個環(huán)境變量集乔。

  • 代碼環(huán)節(jié)暫且告一段落去件,將帶有 Dockerfile 提交到 github 或 gitlab等。

    以我的服務(wù)器 centos7 為例扰路,已安裝好 Docker尤溜。

  • 首先檢出代碼,把項目克隆到指定目錄

    git clone https://github.com/koala-coding/dockerstudy
  • 進(jìn)入目錄構(gòu)建

    cd dockerstudy
    docker build -t dockerstudy .

    build 命令用來制作鏡像汗唱,-t 是給鏡像打標(biāo)簽宫莱,-f 參數(shù)是指定 Dockerfile 路徑,由于我們使用的是默認(rèn) Dockerfile 名稱哩罪,所以可以不同填寫該參數(shù)授霸。最后一個.也不要省略,表示 Dockerfile 文件的所在目錄, 代表是當(dāng)前路徑际插,它指定鏡像構(gòu)建的上下文碘耳。我們剛才說過,真正制作鏡像的是 docker server框弛,當(dāng)我們執(zhí)行 build 命令時辛辨,docker client 會將上下文路徑下的所有內(nèi)容打包,然后上傳給 docker server瑟枫。這樣當(dāng)我們要在 Dockerfile 文件中執(zhí)行 如 COPY 指令斗搞,就可以將上下文中的文件復(fù)制到鏡像中去了。

    構(gòu)建目標(biāo)名稱 dockerstudy慷妙,是一個鏡像僻焚,可以通過 docker images 來列出所有的鏡像。

    一般應(yīng)該會將 Dockerfile 置于一個空目錄下膝擂,或者項目根目錄下虑啤。如果該目錄下沒有所需文件,那么應(yīng)該把所需文件復(fù)制一份過來猿挚。如果目錄下有些東西確實不希望構(gòu)建時傳給 Docker引擎咐旧,那么可以用.gitignore 一樣的語法寫一個 .dockerignore

  • 通過鏡像 dockerstudy 創(chuàng)建一個容器并運(yùn)行绩蜻。

    docker run --name dockerstudycontainer -d -p 3000:3000 dockerstudy

    說明:創(chuàng)建的容器名稱是 dockerstudycontainer铣墨,你可以理解為 pid,這個名稱唯一办绝,創(chuàng)建之后如果不刪除會一直存在伊约。-p 用來指定端口映射姚淆,將容器的端口3000映射到主機(jī)3000`端口上,這樣就可外部訪問了屡律。

    此時在宿主機(jī)中可以使用curl測試服務(wù)器提供的服務(wù)是否正常

    curl localhost:3000

    或者可以直接在瀏覽器中請求接口看一下輸出

    創(chuàng)建容器后腌逢,有時候需要看一下容器資源占用,使用docker stats

    docker stats dockerstudycontainer

    如果是購買的阿里云或者騰訊云服務(wù)器超埋,注意這里將自己購買的 centos 服務(wù)器3000端口開放搏讶,在安全組

  • 進(jìn)入容器

    docker ls -a 查看所有容器,包括當(dāng)前容器的id
    docker exec -it <id> bash
  • 日志檢查 查看運(yùn)行日志霍殴,“50425b8f2ef3” 為容器 ID

    $ docker logs -f 50425b8f2ef3

    但是到了這里我還有個問題媒惕,那我真想看日志文件的時候,也不能每個容器進(jìn)去看日志来庭,好浪費(fèi)時間岸饰怠!有沒有什么更高的方式月弛?我會在下一篇文章《線上環(huán)境如何優(yōu)雅的打印肴盏,保存,分析日志》中寫到帽衙。

  • Docker 部署 Mongodb 環(huán)境

    1. 遠(yuǎn)程獲取 Mongodb 鏡像
    docker pull mongo
    1. 創(chuàng)建一個docker容器

      docker run -p 27017:27017 -v /data/db --name docker_mongodb -d mongo

      在上面的命令中菜皂,幾個命令參數(shù)的詳細(xì)解釋如下:

    • -p 指定容器的端口映射(特殊說明:前面的是本機(jī)端口 ,后面的是容器的端口,添加-p參數(shù)主動將容器內(nèi)部端口給暴漏出來佛寿,將服務(wù)器的 27017 端口映射到容器的 27017 端口幌墓,這樣在外網(wǎng)就可通過 服務(wù)器的 27017 端口訪問到我們的服務(wù),Mongodb 默認(rèn)端口為 27017冀泻。最終訪問的還是本機(jī)的端口)
    • -v 為設(shè)置容器的掛載目錄,這里是將即本機(jī)中的目錄掛載到容器中的/data/db中蜡饵,作為 Mongodb 的存儲目錄
    • --name 為設(shè)置該容器的名稱
    • -d 設(shè)置容器以守護(hù)進(jìn)程方式運(yùn)行
  • 測試連接容器中的 Mongodb

  • 可視化工具連接

    以上是 MongoDB 容器創(chuàng)建后的信息弹渔。接下來,我們使用 Robo 3T 圖形界面軟件嘗試打開數(shù)據(jù)庫溯祸。打開 RoBo 3T肢专,選擇新建連接,按照下圖填入相關(guān)數(shù)據(jù)庫信息焦辅,保存博杖。

    注意其中的權(quán)限認(rèn)證。連接數(shù)據(jù)庫時候可能失敗筷登,會出現(xiàn)問題剃根,這時候注意一個問題,安全組問題前方,需要把安全組中的27017的 Mongodb 數(shù)據(jù)庫端口打開

    優(yōu)雅部署方式 DockerCompose

    Compose 是 Docker 官方開源的一個項目狈醉,可以管理多個 Docker 容器組成一個應(yīng)用廉油,例如 Web 服務(wù),除了服務(wù)本身還有數(shù)據(jù)庫苗傅、Redis抒线、Nginx 等一系列相關(guān)聯(lián)服務(wù)需要安裝。

    有個 Compose 的支持渣慕,我們只需要定義一個 YAML 格式的配置文件(docker-compose.yml)嘶炭,來編寫一個項目所需要的多個容器配置及調(diào)用關(guān)系,通過簡單的命令即可同時開始或者關(guān)閉這些容器逊桦。Compose 定位是定義和運(yùn)行多個 Docker 容器的應(yīng)用旱物。在這篇文章中不具體講 DockerCompose 使用,主要講清楚 Docker 基本架構(gòu)各部分的應(yīng)用卫袒,多實踐下哦宵呛!

    Docker 帶來了什么(優(yōu)點)

    • 環(huán)境隔離('隔離,安全')

      Docker 實現(xiàn)了資源隔離夕凝,一臺機(jī)器運(yùn)行多個容器互無影響宝穗。

    • 更高效的資源利用(節(jié)約成本)

      Docker 容器的運(yùn)行不需要額外的虛擬化管理程序的支持,它是內(nèi)核級的虛擬化码秉,可以實現(xiàn)更高的性能逮矛,同時對資源的額外需求很低。

    • 更快速的交付部署(敏捷)

      使用 Docker转砖,開發(fā)人員可以利用鏡像快速構(gòu)建一套標(biāo)準(zhǔn)的研發(fā)環(huán)境须鼎,開發(fā)完成后,測試和運(yùn)維人員可以直接通過使用相同的環(huán)境來部署代碼府蔗。

    • 更易遷移擴(kuò)展(可移植性)

      Docker 容器幾乎可以在任意的平臺上運(yùn)行晋控,包括虛擬機(jī)、公有云姓赤、私有云赡译、個人電腦、服務(wù)器等不铆,這種兼容性讓用戶可以在不同平臺之間輕松的遷移應(yīng)用蝌焚。

    • 更簡單的更新管理(高效)

      使用 Dockerfile,只需要很少的配置修改誓斥,就可以替代以往大量的更新工作只洒。并且所有修改都是以增量的方式進(jìn)行分發(fā)和更新,從而實現(xiàn)自動化和高效的容器管理劳坑。

    Docker的常用命令

    鏡像常用命令

    docker pull [鏡像名稱:版本] 拉取鏡像
    docker images 鏡像列表
    docker rmi [鏡像名稱:版本] 刪除鏡像
    docker history [鏡像名稱] 鏡像操作記錄
    docker tag [鏡像名稱:版本][新鏡像名稱:新版本]
    docker inspect [鏡像名稱:版本] 查看鏡像詳細(xì)
    docker search [關(guān)鍵字] 搜索鏡像
    docker login 鏡像登陸

    容器常用命令

    docker ps -a 容器列表(所有容器)
    docker ps 查看所有(運(yùn)行的)容器
    docker exec -ti <id> bash 以 bash 命令進(jìn)入容器內(nèi)
    docker run -ti --name [容器名稱][鏡像名稱:版本] bash 啟動容器并進(jìn)入
    docker logs 查看容器日志
    docker top <container_id> 查看容器最近的一個進(jìn)程
    docker run -ti --name [容器名稱] -p 8080:80 [鏡像名稱:版本] bash 端口映射
    docker rm <container_id> 刪除容器
    docker stop <container_id> 停止容器
    docker start <container_id> 開啟容器
    docker restart <container_id> 重啟容器
    docker inspect <container_id> 查看容器詳情
    docker commit [容器名稱] my_image:v1.0 容器提交為新的鏡像

    DockerFile常用命令

    在上面實戰(zhàn)中已經(jīng)詳細(xì)講解毕谴,可以返回看,這里就不再重復(fù)寫。

    總結(jié)

    讀完本文后析珊,你應(yīng)該掌握了 Docker 的基本使用羡鸥,對 Docker 這個概念不那么陌生了,并且知道了它的應(yīng)用場景忠寻,可以自己實踐下惧浴,這個過程也會出現(xiàn)很多問題的,實踐才能更好的記住那些知識以及常用命令奕剃。



    ? 原創(chuàng)不易“在看”是最大的支持衷旅!

    ?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
    • 序言:七十年代末,一起剝皮案震驚了整個濱河市纵朋,隨后出現(xiàn)的幾起案子柿顶,更是在濱河造成了極大的恐慌,老刑警劉巖操软,帶你破解...
      沈念sama閱讀 217,509評論 6 504
    • 序言:濱河連續(xù)發(fā)生了三起死亡事件嘁锯,死亡現(xiàn)場離奇詭異,居然都是意外死亡聂薪,警方通過查閱死者的電腦和手機(jī)家乘,發(fā)現(xiàn)死者居然都...
      沈念sama閱讀 92,806評論 3 394
    • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來藏澳,“玉大人仁锯,你說我怎么就攤上這事∠栌疲” “怎么了业崖?”我有些...
      開封第一講書人閱讀 163,875評論 0 354
    • 文/不壞的土叔 我叫張陵,是天一觀的道長蓄愁。 經(jīng)常有香客問我双炕,道長,這世上最難降的妖魔是什么涝登? 我笑而不...
      開封第一講書人閱讀 58,441評論 1 293
    • 正文 為了忘掉前任雄家,我火速辦了婚禮,結(jié)果婚禮上胀滚,老公的妹妹穿的比我還像新娘。我一直安慰自己乱投,他們只是感情好咽笼,可當(dāng)我...
      茶點故事閱讀 67,488評論 6 392
    • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著戚炫,像睡著了一般剑刑。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
      開封第一講書人閱讀 51,365評論 1 302
    • 那天施掏,我揣著相機(jī)與錄音钮惠,去河邊找鬼。 笑死七芭,一個胖子當(dāng)著我的面吹牛素挽,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播狸驳,決...
      沈念sama閱讀 40,190評論 3 418
    • 文/蒼蘭香墨 我猛地睜開眼预明,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了耙箍?” 一聲冷哼從身側(cè)響起撰糠,我...
      開封第一講書人閱讀 39,062評論 0 276
    • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎辩昆,沒想到半個月后阅酪,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
      沈念sama閱讀 45,500評論 1 314
    • 正文 獨(dú)居荒郊野嶺守林人離奇死亡汁针,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
      茶點故事閱讀 37,706評論 3 335
    • 正文 我和宋清朗相戀三年术辐,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片扇丛。...
      茶點故事閱讀 39,834評論 1 347
    • 序言:一個原本活蹦亂跳的男人離奇死亡术吗,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出帆精,到底是詐尸還是另有隱情较屿,我是刑警寧澤,帶...
      沈念sama閱讀 35,559評論 5 345
    • 正文 年R本政府宣布卓练,位于F島的核電站隘蝎,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏襟企。R本人自食惡果不足惜嘱么,卻給世界環(huán)境...
      茶點故事閱讀 41,167評論 3 328
    • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望顽悼。 院中可真熱鬧曼振,春花似錦、人聲如沸蔚龙。這莊子的主人今日做“春日...
      開封第一講書人閱讀 31,779評論 0 22
    • 文/蒼蘭香墨 我抬頭看了看天上的太陽木羹。三九已至甲雅,卻和暖如春解孙,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背抛人。 一陣腳步聲響...
      開封第一講書人閱讀 32,912評論 1 269
    • 我被黑心中介騙來泰國打工弛姜, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人妖枚。 一個月前我還...
      沈念sama閱讀 47,958評論 2 370
    • 正文 我出身青樓廷臼,卻偏偏與公主長得像,于是被迫代替她去往敵國和親盅惜。 傳聞我的和親對象是個殘疾皇子中剩,可洞房花燭夜當(dāng)晚...
      茶點故事閱讀 44,779評論 2 354