1. 程式人生 > >Docker部署node.js應用

Docker部署node.js應用

前言

什麼是docker?

通俗的理解,docker是建立和管理容器的一種技術。那什麼是容器呢?容器的功能與虛擬機器很近似,都是在一個物理主機上執行多個作業系統的技術。最大的不同之處在於,虛擬機器技術是虛擬出一套硬體後,在其上執行一個完整作業系統,在該系統上再執行所需應用程序;而容器內的應用程序直接運行於宿主的核心,容器內沒有自己的核心,而且也沒有進行硬體虛擬。因此容器要比傳統虛擬機器更為輕便。

基本概念
  1. 映象
    Docker 映象是一個特殊的檔案系統,除了提供容器執行時所需的程式、庫、資源、配置等檔案外,還包含了一些為執行時準備的一些配置引數(如匿名卷、環境變數、使用者等)。映象不包含任何動態資料,其內容在構建之後也不會被改變。我們可以通過命令或者一些基礎映象,構建自己需要的映象。
  2. 容器
    容器可以看作映象的實體,容器可以被建立、啟動、停止、刪除、暫停等。
為什麼使用docker

我們知道在部署node.js的應用時,需要已經安裝node與npm,如果涉及資料庫的話,還需要有資料庫的環境和資料庫資訊。在啟動應用時,還需要安裝程式依賴的第三方庫。如果只是單純的在一臺機器上部署的話,感覺還好。但是如果我們需要在很多機器上部署該應用的話,按照一般的方法,就需要在多個機器上不斷地重複搭建應用所需要的環境,這是一個很費時間的過程。如果我們採用docker的形式,就可以在本地建立一個應用程式的映象(包含程式執行所需要的一切環境),然後只需要在遠端主機上傳我們建立的映象,然後使用docker根據映象建立執行應用程序的容器,輕鬆幾行命令就可以在多個主機上執行我們的程式。

環境說明

本文中所有操作均在Ubuntu 16.0上進行。

前期準備

本文讀者熟悉node.js技術,已經可以使用node.js搭建一個簡單的應用。所以,本文說明中不包含具體的node.js程式碼教程。此外,本文的node.js設計MySql儲存,不涉及資料庫的可以直接從第三節開始看起。

一、安裝docker

參考文章

二、MySQL容器製作

拉取MySQL資料庫映象
docker pull mysql/mysql-server:tag  

tag: 想要拉取的映象的版本號 (比如, 5.5, 5.6, 5.7, 8.0, or latest).這裡用的是5.7。
不建議使用8.0或者latest。新版本的mysql有些操作跟之前的不太一樣,按照網上大多數教程處理可能會有意想不到的錯誤。本人已經踩坑。

執行MySQL資料庫容器
sudo docker run --name db-manage -d -e MYSQL_ROOT_PASSWORD=password -p 3306:3306 mysql/mysql-server:5.7  

–name db-manage: 命名MySQL映象執行的容器的名稱
-d detach,在後臺執行容器。
-e MYSQL_ROOT_PASSWORD=123(或者是 –env)環境變數 – 引數告訴 docker 所提供的環境變數MYSQL_ROOT_PASSWORD=password:設定資料庫root賬戶密碼為password
-p 3306:3306(或者 –publish) 告訴引擎使用者想要將容器內的3306埠對映到外部的3306埠上。

mysql/mysql-server:5.7 : 是拉取的mysql資料庫映象

新增從外部訪問資料庫的許可權

MySQL預設是不能從外部網路訪問的,預設只能使用本地IP(127.0.0.1)訪問。我們待會需要執行node.js的容器具有訪問執行MySQL服務的容器的許可權。
或許你會覺得很疑惑,都是在一臺機器上,不應該是一個IP地址麼?
並不是這樣。因為實際的主機會為每個執行在其上面的容器單獨分配IP,所以不同容器之間,IP地址並不一樣。

1.進入MySQL容器
sudo docker exec -it db-manage bash

db-manage:執行MySQL的容器名稱

2.在容器中進入Mysql服務
mysql -uroot -ppassword

root:資料庫使用者名稱
password:之前執行容器時設定的資料庫密碼

3.新增外部訪問許可權

執行以下命令(若之前拉的MySQL版本高於5.7,會報錯。因為之後版本的MySQL新增使用者許可權方式的命令不是下列所展示,具體請參考官網)

# 切換資料庫
USE mysql;
# 給root賬戶開放所有ip訪問許可權
GRANT ALL PRIVILEGES ON *.* TO "root"@"%" IDENTIFIED BY "password" WITH GRANT OPTION; 
# 更新許可權設定
FLUSH PRIVILEGES;

MySQL命令已分號結尾
必須使用FLUSH PRIVILEGES更新許可權設定才有效
如果只想為指定IP連線MySQL資料庫賦予許可權,使用一下命令:(更多給MySQL新增使用者許可權可以參考這篇文章)

# 給root賬戶開放192.168.1.3訪問許可權
GRANT ALL PRIVILEGES ON *.* TO "root"@"192.168.1.3" IDENTIFIED BY "password" WITH GRANT OPTION; 

三、node程式容器製作

拉取node.js基礎映象
sudo docker pull node:tag  
製作自己的node.js服務映象

前提準備:
1. 已經有可以執行的node.js程式
2. node.js連結資料庫的設定如下:

const address = {
    host     : process.env.DATABASE_HOST || 'localhost',
    user     : 'root',
    password : 'choosealife',
    port:  process.env.PORT || '3306',
    database: 'manage',
};
1.進入程式資料夾根目錄
cd node-app
2.建立Dockerfile檔案(檔名不能更改)
    touch Dockerfile  
 檔案內容如下:
# 選擇之前下載的node基礎映象 node:<version>
FROM node:9.11.2-jessie
#將當前資料夾下所有檔案加入需要製作的映象中, 在 'manage' 資料夾中.
ADD . /manage
#  下載所需要的包
RUN cd /manage;
npm install --production
# 定義程式預設埠
EXPOSE 3000
# 執行程式命令(manage是ADD新增的資料夾名稱, server.js是自己的程式啟動入口檔案)
CMD ["node","/manage/server.js"]
3.製作映象
 sudo docker build -t node-image-name .

注意: node-imge-name是映象名稱。命令後有一個 . , 不能忘記了。

4.執行node程式映象並關聯執行的MySQL容器
sudo docker run --name manage-system -it -p 3000:3000 --link db-manage:db-manage -e DATABASE_HOST=db-manage  node-manage-image
  1. docker run -it 在容器裡執行 docker 映象,使用互動式終端。
  2. -p 3000:3000 將宿主機的3000 埠對映到容器的3000 埠上
  3. link db-manage:db-manage 連線到名為 db-manage的 容器上,並且用 db-manage 指代該容器
  4. -e DATABASE_HOST=db-manage 將在node.js資料庫連線中設定的環境變數 DATABASE_HOST 設定為 db-manage
  5. node-image-name 是在容器內執行的映象名稱

四、上傳docker映象到遠端倉庫

  1. 上傳到docker hub
    參考文章

  2. 上傳到騰訊雲伺服器
    參考文章

  3. 上傳到阿里雲伺服器
    參考文章

五、常用docker命令

1.獲取基礎映象
sudo docker pull [選項] [Docker Registry 地址[:埠號]/]倉庫名[:標籤]
2.製作映象
# 需要提前建立構建檔案Dockerfile, version不是必須, 預設為latest, . 表示當前目錄
sudo docker build -t imgae-name:version .
3.檢視映象
sudo docker image ls
4.刪除映象
sudo docker image rm image-name
5.已指定映象建立容器
sudo docker run -it image-name
6.啟動已經存在的容器
sudo docker container start container-name
7.停止已經執行的容器
sudo docker container stop container-name
8.重啟已經執行的容器
sudo docker container restart container-name
9.檢視所有容器
sudo docker container ls -a
10.刪除容器
# 刪除指定容器, 加上-f可以強制刪除正在執行的容器
sudo docker container rm  container-name
# 清除所有處於終止狀態的容器
 sudo docker container prune