使用 Docker 搭建第一個 Node 項目到伺服器

2021-12-25 分布式實驗室


關於 Docker 的概念是確實不太好總結,下面我通過四點向你說明 Docker 到底是個什麼東西。

Docker 是世界領先的軟體容器平臺。

Docker 使用 Google 公司推出的 Go 語言 進行開發實現,基於 Linux 內核 的cgroup,namespace,以及 AUFS 類的 UnionFS 等技術,對進程進行封裝隔離,屬於作業系統層面的虛擬化技術。由於隔離的進程獨立於宿主和其它的隔離的進程,因此也稱其為容器。Docker 最初實現是基於 LXC。

Docker 能夠自動執行重複性任務,例如搭建和配置開發環境,從而解放了開發人員以便他們專注在真正重要的事情上,構建傑出的軟體。

用戶可以方便地創建和使用容器,把自己的應用放入容器。容器還可以進行版本管理、複製、分享、修改,就像管理普通的代碼一樣。

左邊大框框是我們進行 Docker 操作的宿主機,其運行了一個 Docker daemon 的核心守護程序,負責構建、運行和分發 Docker 容器。

在宿主機中安裝了 Docker 客戶端,其與 Docker daemon 守護進程進行通信,客戶端會將 build、pull、run 等命令發送到 Docker daemon 守護進程進行執行。

右框框為 Docker 註冊表存儲 Docker 鏡像,是一個所有 Docker 用戶共享 Docker 鏡像的服務,Docker daemon 守護進程與之進行交互。

下面是對架構中基本組成說明,比較詳細,大家看的時候可以對著架構圖看。概念這個東西,你看下就好,怎麼記都記不住的,只有你常用的東西才會記住和想著去記住它,看完本文,可以把下面的應用實踐一遍。鏡像倉庫,存儲大量鏡像,可以從鏡像倉庫拉取和推送鏡像。類似虛擬機快照,從倉庫拉取,或者在現有工具鏡像上創建新鏡像。通過鏡像可以啟動容器。從鏡像中創建應用環境,以單進程的方式運行。對外公開服務。是一種短暫的和一次性的環境。數據卷可以完成數據持久化,數據卷是一個可供一個或多個容器使用的特殊目錄,它繞過 UFS,可以提供很多有用的特性:

數據卷可以在容器之間共享和重用

對數據卷的修改會立馬生效

對數據卷的更新,不會影響鏡像

卷會一直存在,直到沒有容器使用

Docker 容器之間的網絡交互,可以使用埠映射的方式,其他容器可以直接通過埠實現。除該方式外還有一個容器連接(linking)系統也可以達到容器交互。(本文中 Node 連接 MongoDB 使用的是埠映射的方式)

Docker 部署 Node 項目完整流程(DockerFile實踐)使用 Koa2 初始化一個 Node 項目,通過 Mongose 中間件連接 MongoDB 資料庫,實現一個基礎接口 Mogodb 插入數據。項目地址:https://github.com/koala-coding/dockerstudy首先在項目根目錄下創建 .dockerignore 文件,把不需要打包進 Docker Image 裡的文件進行過濾:

# /usr/src/nodejs/dockerstudy/.dockerignore

.git

node_modules

在項目的根目錄中創建 Dockerfile 文件(Dockerfile 這裡重點講一下)。部署 Node項目的時候,會有一個 Dockerfile 文件配置:

# /usr/src/nodejs/hello-docker/Dockerfile

FROM node:10.0

# 在容器中創建一個目錄

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

# 把當前目錄下的所有文件拷貝到 Image 的 /usr/src/nodejs/ 目錄下

COPY . /usr/src/nodejs/

EXPOSE 3000

CMD npm start

FROM:FROM 是構建鏡像的基礎源鏡像,該 Image 文件繼承官方的 node image。詳細說明:Dockerfile 中 FROM 是必備的指令,並且必須是第一條指令!它引入一個鏡像作為我們要構建鏡像的基礎層,就好像我們首先要安裝好作業系統,才可以在作業系統上面安裝軟體一樣。詳細說明:每一個 RUN 指令都會新建立一層,在其上執行這些命令,我們頻繁使用 RUN 指令會創建大量鏡像層,然而 Union FS 是有最大層數限制的,不能超過 127 層,而且我們應該把每一層中我用文件清除,比如一些沒用的依賴,來防止鏡像臃腫。COPY:拷貝文件至容器的工作目錄下,.dockerignore 指定的文件不會拷貝CMD:Dockerfile 執行寫一個 CMD 否則後面的會被覆蓋,CMD 後面的命令是容器每次啟動執行的命令,多個命令之間可以使用 && 連結,例如 CMD git pull && npm start。詳細說明:CMD 指令用來在啟動容器的時候,指定默認的容器主進程的啟動命令和參數。

CMD echo 1

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

第一種執行的命令會被包裝程,CMD [ "sh", "-c", "echo 1" ] JSON 數組形式,一般推薦 JSON 數組形式。容器中的應用都應該以前臺執行,而不是啟動後臺服務,容器內沒有後臺服務的概念。對於容器而言,其啟動程序就是容器應用進程,容器就是為了主進程而存在的,主進程退出,容器就失去了存在的意義。比如 CMD service nginx start 它等同於 CMD [ "sh", "-c", "service nginx start"] 主進程實際上是 sh,sh 也就結束了,sh 作為主進程退出了。


ENV <key> <value>

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

定義了環境變量,那麼在後續的指令中,就可以使用這個環境變量。代碼環節暫且告一段落,將帶有 Dockerfile 提交到 GitHub 或 GitLab 等。以我的伺服器 CentOS 7 為例,已安裝好 Docker。

git clone https://github.com/koala-coding/dockerstudy

cd dockerstudy

docker build -t dockerstudy .

build 命令用來製作鏡像,-t 是給鏡像打標籤,-f 參數是指定 Dockerfile 路徑,由於我們使用的是默認 Dockerfile 名稱,所以可以不同填寫該參數。最後一個.也不要省略,表示 Dockerfile 文件的所在目錄, 代表是當前路徑,它指定鏡像構建的上下文。我們剛才說過,真正製作鏡像的是 docker server,當我們執行 build 命令時,docker client 會將上下文路徑下的所有內容打包,然後上傳給 docker server。這樣當我們要在 Dockerfile 文件中執行 如 COPY 指令,就可以將上下文中的文件複製到鏡像中去了。構建目標名稱 dockerstudy,是一個鏡像,可以通過 docker images 來列出所有的鏡像。一般應該會將 Dockerfile 置於一個空目錄下,或者項目根目錄下。如果該目錄下沒有所需文件,那麼應該把所需文件複製一份過來。如果目錄下有些東西確實不希望構建時傳給 Docker引擎,那麼可以用.gitignore 一樣的語法寫一個 .dockerignore。通過鏡像 dockerstudy 創建一個容器並運行。


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

說明:創建的容器名稱是 dockerstudycontainer,你可以理解為 pid,這個名稱唯一,創建之後如果不刪除會一直存在。-p 用來指定埠映射,將容器的埠3000映射到主機3000`埠上,這樣就可外部訪問了。此時在宿主機中可以使用curl測試伺服器提供的服務是否正常:

curl localhost:3000

創建容器後,有時候需要看一下容器資源佔用,使用docker stats:

docker stats dockerstudycontainer

如果是購買的阿里雲或者騰訊雲伺服器,注意這裡將自己購買的 CentOS 伺服器3000埠開放,在安全組。

docker ls -a 查看所有容器,包括當前容器的ID

docker exec -it <id> bash


日誌檢查,查看運行日誌,「50425b8f2ef3」 為容器 ID:


$ docker logs -f 50425b8f2ef3


但是到了這裡我還有個問題,那我真想看日誌文件的時候,也不能每個容器進去看日誌,好浪費時間啊!有沒有什麼更高的方式?我會在下一篇文章《線上環境如何優雅的列印,保存,分析日誌》中寫到。


docker pull mongo

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

-p 指定容器的埠映射(特殊說明:前面的是本機埠 ,後面的是容器的埠,添加-p參數主動將容器內部埠給暴漏出來,將伺服器的 27017 埠映射到容器的 27017 埠,這樣在外網就可通過 伺服器的 27017 埠訪問到我們的服務,MongoDB 默認埠為 27017。最終訪問的還是本機的埠)

-v 為設置容器的掛載目錄,這裡是將即本機中的目錄掛載到容器中的 /data/db 中,作為 MongoDB 的存儲目錄

--name 為設置該容器的名稱

-d 設置容器以守護進程方式運行

接下來,我們使用 Robo 3T 圖形界面軟體嘗試打開資料庫。打開 RoBo 3T,選擇新建連接,按照下圖填入相關資料庫信息,保存。注意其中的權限認證。連接資料庫時候可能失敗,會出現問題,這時候注意一個問題,安全組問題,需要把安全組中的 27017 的 MongoDB 資料庫埠打開。Compose 是 Docker 官方開源的一個項目,可以管理多個 Docker 容器組成一個應用,例如 Web 服務,除了服務本身還有資料庫、Redis、Nginx 等一系列相關聯服務需要安裝。有個 Compose 的支持,我們只需要定義一個 YAML 格式的配置文件(docker-compose.yml),來編寫一個項目所需要的多個容器配置及調用關係,通過簡單的命令即可同時開始或者關閉這些容器。Compose 定位是定義和運行多個 Docker 容器的應用。在這篇文章中不具體講 Docker Compose 使用,主要講清楚 Docker 基本架構各部分的應用,多實踐下哦!

環境隔離('隔離,安全'):Docker 實現了資源隔離,一臺機器運行多個容器互無影響。

更高效的資源利用(節約成本):Docker 容器的運行不需要額外的虛擬化管理程序的支持,它是內核級的虛擬化,可以實現更高的性能,同時對資源的額外需求很低。

更快速的交付部署(敏捷):使用 Docker,開發人員可以利用鏡像快速構建一套標準的研發環境,開發完成後,測試和運維人員可以直接通過使用相同的環境來部署代碼。

更易遷移擴展(可移植性):Docker 容器幾乎可以在任意的平臺上運行,包括虛擬機、公有雲、私有雲、個人電腦、伺服器等,這種兼容性讓用戶可以在不同平臺之間輕鬆的遷移應用。

更簡單的更新管理(高效):使用 Dockerfile,只需要很少的配置修改,就可以替代以往大量的更新工作。並且所有修改都是以增量的方式進行分發和更新,從而實現自動化和高效的容器管理。

docker pull [鏡像名稱:版本] 拉取鏡像

docker images 鏡像列表

docker rmi [鏡像名稱:版本] 刪除鏡像

docker history [鏡像名稱] 鏡像操作記錄

docker tag [鏡像名稱:版本][新鏡像名稱:新版本]

docker inspect [鏡像名稱:版本] 查看鏡像詳細

docker search [關鍵字] 搜索鏡像

docker login 鏡像登陸

docker ps -a 容器列表(所有容器)

docker ps 查看所有(運行的)容器

docker exec -ti <id> bash 以 bash 命令進入容器內

docker run -ti --name [容器名稱][鏡像名稱:版本] bash 啟動容器並進入

docker logs 查看容器日誌

docker top <container_id> 查看容器最近的一個進程

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 容器提交為新的鏡像

在上面實戰中已經詳細講解,可以返回看,這裡就不再重複寫。讀完本文後,你應該掌握了 Docker 的基本使用,對 Docker 這個概念不那麼陌生了,並且知道了它的應用場景,可以自己實踐下,這個過程也會出現很多問題的,實踐才能更好的記住那些知識以及常用命令。


Kubernetes入門與實戰培訓將於2020年2月28日在北京開課,3天時間帶你系統掌握Kubernetes,學習效果不好可以繼續學習。本次培訓包括:Docker基礎、容器技術、Docker鏡像、數據共享與持久化、Docker實踐、Kubernetes基礎、Pod基礎與進階、常用對象操作、服務發現、Helm、Kubernetes核心組件原理分析、Kubernetes服務質量保證、調度詳解與應用場景、網絡、基於Kubernetes的CI/CD、基於Kubernetes的配置管理等等,點擊下方圖片或者閱讀原文連結查看詳情。


相關焦點

  • 用 Docker 搭建你的第一個 Node 項目到伺服器
    (本文中 node 連接 mongodb 使用的是埠映射的方式)關於Docker 網絡模塊,容器連接詳情推薦這篇文章:Docker的網絡模式詳解Docker 應用場景Docker 部署 Node 項目完整流程(DockerFile實踐)使用 Koa2 初始化一個 Node 項目,通過 Mongose 中間件 連接 Mogodb 資料庫,實現一個基礎接口 Mogodb 插入數據。
  • Docker搭建部署Node項目
    其中在centos上搭建環境和部署都挺費周折,部署測試伺服器,接著上線的時候又部署生產環境伺服器。這中間就有很多既無聊又費精力,吃力不討好的"體力活"。所以就開始思考怎麼自動化這部分搭建部署的工作,也就引出了Docker。什麼是DockerDocker 是比虛擬機還要輕量級的虛擬化技術,它虛擬化的實體就叫做容器。
  • 巨杉Tech | 使用 SequoiaDB + Docker + Nodejs 搭建 Web 伺服器
    SequoiaDB 巨杉資料庫於3.2.1版本正式推出了 Docker 容器化部署方案,本文將會基於 SequoiaDB 巨杉資料庫與 Nodejs 的 Docker 鏡像搭建一個簡易的 Web 伺服器。我們將會搭建一個三分區三副本的高可用 SequoiaDB 巨杉資料庫。同時,我們將會創建一個SequoiaDB 巨杉資料庫的 MySQL 實例,用以提供 Nodejs 作為數據源。
  • 「前端開發者的 Docker 之旅」用 Docker 搭建 Node Express 應用
    目標: 用 Docker 鏡像的方式搭建 Node Express 應用本項目代碼:https://github.com/Ye-Ting/node-express-docker-sampleDemo :http://yeting-front-node-express-docker-sample.daoapp.io/首先,藉助 Yeomen Express
  • 使用docker swarm 搭建docker集群
    簡介Docker Swarm 和 Docker Compose 一樣,都是 Docker 官方容器編排項目,但不同的是,Docker Compose 是一個在單個伺服器或主機上創建多個容器的工具,而 Docker Swarm 則可以在多個伺服器或主機上創建容器集群服務,對於微服務的部署,顯然 Docker Swarm 會更加適合。
  • 使用 Node, Sequelize, Postgres 和 Docker 搭建 CURD API【譯】
    和 Docker 搭建 CURD API。好消息是,通過使用Docker,您實際上不需要安裝它,因為我們將使用 Node 的 docker image,因此,我們也可以避免在我的機器上安裝的我的 Node 版本和你的之間進行版本控制POSTGRES
  • Docker最全教程之使用Node.js搭建團隊技術文檔站(二十四)
    編寫Dockerfile 3. 構建並運行 1.官方鏡像地址:https://hub.docker.com/_/node使用Node.js編寫一個簡單的Web伺服器非常簡單,主要需要用到http模塊,http模塊主要用於搭建 HTTP
  • 我是如何使用docker,把一個nodejs項目部署上線的
    上一篇文章聊了一下如何把一個nodejs項目部署上線。現在容器化技術這麼火熱,作為學習,這篇文章就和大家聊一聊,我是如何使用docker把一個nodejs項目部署上線的。廢話不多說,下面開始進入正題:一、安裝 Docker首先在伺服器上安裝 Docker,參照官方極簡教程,很快便能安裝好,搭建 Docker 環境。
  • 前端開發者應該知道的 Centos/Docker/Nginx/Node/Jenkins 操作
    Centos 下安裝 Nginx 伺服器這裡我們使用 yum 安裝 Nginx 伺服器。到此,一個基於 Nginx 的靜態伺服器就搭建完成了,現在所有放在 /data/www 目錄下的的靜態資源都可以直接通過域名/IP 訪問。如果無顯示,請刷新瀏覽器頁面
  • 手把手 docker 從零搭建 jenkins 伺服器
    在項目非常趕的情況下,我每天還要抽半天時間去排查 jenkins 上的問題。所以決定在我們前端伺服器上搭建個 jenkins 給測試部署。並部署到前端伺服器上。文章是邊操作邊寫出來的,踩遍了坑。不知道大家會不會也遇到這些問題。反正我都把解決步驟寫在裡面了。本文主要內容是介紹 jenkins 的搭建與使用。
  • 使用Docker搭建poste,自建郵件伺服器
    不過現在越來越多的服務商已經開發好了產品,支持一鍵部署等方式,極大降低了部署和使用難度。這次給各位小夥伴安利一款開源郵件服務poste.關於posteposte是一款開源郵件服務軟體,可以很方便的搭建:SMTP + IMAP + POP3 + 反垃圾郵件 + 防病毒 + Web 管理 + Web 電子郵件,支持以下特性。
  • 開發者都應該知道的 Centos/Docker/Nginx/Node/Jenkins 操作(長文,建議收藏)
    Centos 下安裝 Nginx 伺服器這裡我們使用 yum 安裝 Nginx 伺服器。到此,一個基於 Nginx 的靜態伺服器就搭建完成了,現在所有放在 /data/www 目錄下的的靜態資源都可以直接通過域名/IP 訪問。如果無顯示,請刷新瀏覽器頁面
  • 在docker搭建自己的郵件伺服器
    Docker上的搭建方法2搭建ExtMail郵件伺服器2.1ExtMail簡介國內唯一活躍開發的中文開源郵件系統軟體。由於ExtMail 較符合國內用戶的使用習慣,提供本土化的論壇/QQ群等技術支持,滿足穩定收發和基本管理的需求,受到社區和商業用戶的歡迎。經粗略測算,截止2012年Q1,ExtMail/EMOS等被下載了數十萬次,超過8000臺ExtMail伺服器在Internet運行,服務著十多萬域名和數百萬個企業郵箱。
  • Docker+Selenium Grid+Python搭建分布式測試環境
    主要使用到的東西:  語言:python3.5  web自動化:selenium3.7  應用容器引擎:Docker 1.12  作業系統:CentOS 7  當一個場景在單個瀏覽器上可以運行後,就需要考慮是否可以同時測試下兼容性,之前已經有一篇文章介紹了利用Selenium Grid
  • Node.js搭建一個簡單的伺服器
    Node.js的安裝了解Node.js模塊系統伺服器的搭建
  • 從零開始Docker化你的Node.js應用
    ,使用scp命令,把zip包傳輸至伺服器的示例如下:rsync -avzP .    https:sudo yum makecache fastsudo yum install docker-ce使用Docker的時候,需要經常從官方獲取鏡像,但是由於顯而易見的網絡原因,拉取鏡像的過程非常耗時,嚴重影響使用Docker的體驗,推薦使用https://0x9.me/ragf2。
  • 使用Docker搭建Nextcloud個人工作中心
    上一篇文章使用NextCloud快速搭建你自己的工作中心(上)有一些工作沒有介紹完,這篇文章進行了補充。並且修改了docker-compose文件,重新打包了docker鏡像等優化操作,使得部署起來更方便些。
  • 如何在正確使用 Docker 搭建 GitLab
    很多程式設計師在內網搭建 gitlab 都搭建的坑坑窪窪,不支持 https,或者裝個 gitlab 就把伺服器弄得亂七八糟的,根本不知道該怎麼維護和遷移
  • Docker 入門到實戰教程(十二)ELK+Filebeat搭建日誌分析系統
    需要集中化的日誌管理,所有伺服器上的日誌收集匯總。常見解決思路是建立集中式日誌收集系統,將所有節點上的日誌統一收集,管理,訪問。一般大型系統是一個分布式部署的架構,不同的服務模塊部署在不同的伺服器上,問題出現時,大部分情況需要根據問題暴露的關鍵信息,定位到具體的伺服器和服務模塊,構建一套集中式日誌系統,可以提高定位問題的效率。
  • 如何在Linux下使用docker搭建LNMP環境
    最近在使用docker的過程中遇到了許許多多的坑。首次使用它也是浪費了大量的精力。今天我們來簡單說下如何用它搭建一個LNMP環境吧,遇到的坑和解決方法我也會寫到裡面。。            最近也是想構思一個小項目玩玩,首先就是環境的選擇,因為我是在個人電腦上測試環境等等,首先考慮的就是資源利用的問題,例如分布式,集群等等。