Windows下運用Docker部署Node.js開發環境

開始

在windows下部署nodejs開發環境着實遍地坑,每遇到一個問題都要去google緣由再試圖解決。並且若是你想把你寫好的應用交給別人跑跑看,他可能一樣須要折騰好久才能真正在他的環境下運行起來。被坑了好些時日最終仍是放棄,轉戰Docker。node

Docker的簡介不在本文贅述,基本概念可參看Docker——從入門到實踐mysql

文章開頭先明確一下咱們但願實現的效果:git

  1. 依然在Windows下編輯源代碼,在Docker容器中運行代碼,最後在Windows的瀏覽器中看到運行結果,方便後續debug。github

  2. 能夠將我開發完成的程序和運行環境一塊兒打包製做成Docker的image,移交image給小夥伴運行或者直接發佈到服務器上。web

安裝與啓動

Docker引擎核心是運行在Linux操做系統上的Linux容器。因此要在Windows上使用Docker容器,先要提供Linux運行環境。redis

Docker官網下載msi安裝程序,若你的系統版本(例如64bit Windows 10 Pro, Enterprise and Education)支持Hyper-V虛擬技術,那麼不須要使用額外的虛擬機(VirtualBox),安裝程序會自動爲你安裝完成Docker(Docker for Windows)。sql

The Hyper-V package must be enabled for Docker for Windows to work. The Docker for Windows installer will enable it for you, if needed. (This requires a reboot). If your system does not satisfy these requirements, you can install Docker Toolbox, which uses Oracle Virtual Box instead of Hyper-V.docker

若不能使用Hyper-V虛擬技術,Docker項目組也提供了Docker ToolBox工具,能夠很方便的在Windows環境下安裝Docker。npm

更詳細內容參考Docker官方文檔-toolboxjson

本文中的執行系統爲Win7,故使用Docker toolbox。

安裝過程會附帶安裝Oracle VM VirtualBox虛擬機,以下圖:

clipboard.png

Kitematic爲Docker的GUI管理工具,打開Docker Terminal能夠快速地啓動Docker。

clipboard.png

能夠發現此時Docker給default machine分配了一個IP:192.168.99.100。咱們能夠直接在該終端下執行Docker命令。

因爲在Windows中運行Docker多加了一層虛擬機,有幾個概念須要瞭解:

  • Docker主機指的是Linux虛擬機,也就是說,此時Docker主機(即Linux虛擬機)的IP地址爲192.168.99.100。

  • 與通常的ssh訪問虛擬機同樣,咱們也能夠經過該IP用ssh登陸到Docker主機去執行命令。(用戶名:docker;密碼:tcuser)

  • 如要用root權限去執行Linux命令(如mount),則須要打開VirtualBox。

    clipboard.png
    clipboard.png

搭建Image

新安裝好的Docker主機中沒有任何image(docker images 查看已有的image)。運行node應用須要搭建node環境鏡像,能夠從Docker Hub上pull輕量級的Linux鏡像做爲基礎鏡像(如CentOS),在上面手動安裝node;也能夠直接pull一個已安裝了node的鏡像(docker pull 拉取鏡像)。從Docker Hub下載鏡像可能很是慢,能夠藉助國內的雲服務商下載(如daocloud.io)。

如今假設咱們pull了一個不包含node環境的CentOS鏡像。

$ docker run -it centos bash

啓動一個容器,並進入容器的bash進行交互式操做。採用與CentOS下同樣的方式安裝node。安裝完成後exit退出容器。請放心,若是不使用docker rm或者docker run時不增長--rm參數,即便退出容器,容器自己及其中的修改不會消失。能夠用docker ps -a查看全部容器,docker ps查看正在運行的容器。

$ docker commit <CONTAINER_ID> <IMAGE>

提交以前修改的容器到新的image。該鏡像就是已經安裝了node環境的鏡像(命名爲nodejs)。
在後續的開發中咱們能夠用docker run -it nodejs bash啓動容器。

在Windows和虛擬機之間共享文件

咱們如今須要在Docker容器中運行源代碼,而Docker容器是在Docker主機中的,因此首先,咱們須要先保證Docker主機(即Linux虛擬機)能訪問到Windows中的源代碼文件。

打開VirtualBox,點擊「設置」->「共享文件夾」,指定路徑和名稱後勾選「自動掛載」和「固定分配」。「自動掛載」可使得虛擬機下次啓動時自動掛載文件夾,不然每次啓動都須要從新手動掛載。

clipboard.png

若是順利,重啓虛擬機輸入mount命令,能夠看到共享文件夾掛載到了哪裏,進入該目錄就能看到與Windows下同步的文件。

clipboard.png

clipboard.png

若是自動掛載遇到問題,取消這個選項,使用如下命令手動掛載:

mount -t vboxsf docker_share <mount_point>

在Docker容器中運行node代碼

首先在Windows的共享文件夾下編輯測試代碼app.js:

var http = require('http');
    http.createServer(function (req, res) {
      res.writeHead(200, {'Content-Type': 'text/plain'});
      res.end('Hello World\n');
    }).listen(1337); 
console.log('Server running at http://0.0.0.0:1337/');

能夠在Docker主機中看到該文件。

用nodejs鏡像啓動一個容器,咱們但願這個容器能訪問Docker主機中的文件做爲源代碼,還但願能在Windows下訪問運行後的執行端口查看結果。用如下命令啓動容器:

$ docker run -v /docker_share:/app -p 1337:1337 -it nodejs bash

-v 主機目錄:容器數據卷目錄 使得主機目錄被掛載到容器中,可被容器訪問。
-p 主機端口:容器端口使得容器端口被映射到主機上,能夠被容器外部訪問到。

注: 重複多個-p命令能夠映射多個端口。

(Docker 0.11版本以上可使用--net=host參數使得容器中的全部端口映射在Docker主機上。故也可以使用:)

$ docker run -v /docker_share:/app --net=host -it nodejs bash

進入容器中對應的數據卷目錄,執行node app.js

clipboard.png

Windows下經過瀏覽器訪問192.168.99.100:1337可看到結果

clipboard.png

至此,基本的node應用已經能在Docker下跑起來啦~

進一步的開發工做

1. npm install

通常在node工程中都會存在node_modules依賴須要用npm install安裝。在Docker下,指望運行應用的容器中,一樣能夠執行該命令。但注意增長--no-bin-links指令來避免建立軟鏈接。

npm install --no-bin-links

2. 關聯其餘服務與容器互聯

許多node應用都會關聯啓用redis、mysql等服務。直接地,咱們能夠像在Windows下同樣打開同一個容器的多個終端分別運行服務或執行代碼。用如下命令進入一個正在運行的容器:

$ docker exec -it <CONTAINER> bash

更優雅地,咱們將不一樣的服務運行在不一樣的容器上,而後使用--link name:alias容器互聯的方式將他們關聯起來,詳情能夠看這篇博客


3. 實時響應代碼變化

在開發過程當中,若是每次修改代碼都須要結束node進程而後重啓必然會很麻煩。可使用nodemon工具實現監控代碼變化並自動重啓進程的效果,這樣一來只須要在瀏覽器下刷新就能夠看到新的運行效果。

安裝nodemon:

npm install -g nodemon

依然以app.js爲例,在容器中運行app.js時使用命令:

nodemon -L app.js

注:若是不在容器下運行,使用nodemon app.js便可,而在容器中,須要使用-L--legacy-watch參數打開Chokidar輪詢,才能監聽到掛載目錄中文件的改變。

clipboard.png

clipboard.png

嘗試更改app.js內容,保存後能夠發現nodemon自動重啓了:

clipboard.png

刷新瀏覽器看到修改後的結果:

clipboard.png

關於nodemon,更詳細的使用參見GitHub-nodemon

打包源碼和環境爲Image

在工程目錄下編輯Dockerfile和.dockerignore文件。
Dockerfile:

FROM nodejs

# Create app directory
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

# Install app dependencies
COPY package.json /usr/src/app/
RUN npm install

# Bundle app source
COPY . /usr/src/app

EXPOSE 8080
CMD [ "npm", "start" ]

FROM指定基礎鏡像,接下來列出基於基礎鏡像須要作的操做命令,搭建起新的Image環境(包括複製源碼和執行npm install)能夠參考node官方文檔這篇博文

.dockerignore:

node_modules
npm-debug.log

在build新鏡像時忽略其中的文件。

在Docker主機中的工程目錄下(Dockerfile所在目錄)使用命令:

$ docker build -t <ImageName> . //注意末尾的點不可省去

可獲得自行build的鏡像。該鏡像會自動添加到你的docker主機下,你能夠直接啓動新鏡像的容器運行代碼(鏡像內就包含代碼,因此無需重複掛載到數據卷,不過就不能在Windows下修改了),也能夠將鏡像分享給小夥伴。

總結

到此,應該已經能知足基本的開發需求。

雖然在Windows下使用Docker由於多加的一層虛擬機會以爲有一點彆扭,可是Docker自己用容器和鏡像將開發環境封裝隔離的特性依然帶來諸多方便。

以上都是我初步接觸Docker的折騰結果,若是有什麼錯誤或者更方便的方式方法歡迎交流指正。

相關文章
相關標籤/搜索