Node.js开发人员宝典:上手Docker从这里开始

译文
云计算
本教程中将大致介绍一下Docker以及为何想要使用它、如何安装它,然后我们要着手安装一个Node容器,并且在该窗口里面建立一个Express入门级应用程序。

Node.js开发人员宝典:上手Docker从这里开始

难度等级:初学者

要求:Mac OS X(本教程假设你在使用Mac,但你也能找到Windows或Ubuntu的安装指示,直接跳过“安装”章节)。

Docker刚过了第二个生日,但它仍是一项“新兴”的强大技术。与本人交流过的许多开发人员对它已有所耳闻,但并没有实际用过它。Docker让你可以做一些确实很酷的事情,比如可以迅速测试开发中的应用程序,所在环境与质量保证/测试/生产环境一模一样;或者与其他开发人员共享该应用程序,以便尽快轻松熟悉情况。说到Docker,一个常打的比方就是它好比是现实生活中的集装箱或乐高积木:它提供了一种基本单元,同时提供了一种不管是什么硬件,让应用程序都易于移植、易于迁移的方法。

我在本教程中将大致介绍一下Docker以及为何想要使用它、如何安装它,然后我们要着手安装一个Node容器,并且在该窗口里面建立一个Express入门级应用程序。这篇教程内容蛮长!官方的Docker入门指南可以让你更快地上手,我在这里的目的是,解释这个过程中每一步出现的情况。

我们将介绍:

  • 引言(Docker的性质及为何使用它)
  • 安装•Docker Hub和Docker文件
  • Docker Pull:获取Ubuntu映像
  • Docker Run:运行我们的Ubuntu映像,及访问容器
  • Docker Commit:安装node、npm和express,并提交变更内容
  • Docker Push:推回容器,那样别人就能使用它

注意:我将以下列格式指代在你自己的终端中执行的命令:

  1. $ command 

并以下列格式指代容器里面的命令:

  1. $ root: command 

引言

现在你可能已经听说过Docker。每天总会有专业报章提到它,或者你在推特/IRC上看到别人谈论它。它的人气在过去几年急剧飙升;大多数云服务提供商已经支持它。如果你对它感到很好奇,但是还没有用过它,那么这篇教程蛮适合你。

闲话少说,那么Docker到底是什么东东?这么说吧,Docker可能指几个方面:

Docker客户程序:这是在我们的机器上运行的组件。它是docker二进制代码;只要我们打开终端,输入$ docker pull或$ docker run,就要与之交互。它连接至处理所有繁重任务的docker守护程序,而守护程序可能在同一个主机上(以Linux为例),也可能在远地(我们与VirtualBox虚拟机进行交互)。

Docker守护程序:这是处理诸多繁重任务的组件,比如构建、运行和分发Docker容器。

Docker映像:docker映像好比是我们应用程序的蓝图。继续说说上面的集装箱/乐高积木那个比方,docker映像是用于实际构建真正实例的蓝图。映像可能是Ubuntu之类的操作系统,也有可能是你的Web应用程序及其所有的必要程序包都已安装的Ubuntu。

Docker容器:容器是用docker映像构建而成的,它们是集装箱/乐高积木的真正实例。它们可以启动、运行、停止、删除和移动。

Docker Hub(注册中心):Docker注册中心是一台托管的注册中心服务器,可以存放Docker映像。Docker公司提供了一个公共Docker注册中心,名为Docker Hub,我们会在本教程中用到它,但Docker公司提供了开放源代码的整个系统,那样人们可以在自己的服务器上运行,以私密方式存储映像。

我们已经明确了Docker的不同部分,下面介绍你可能想要使用它的几个理由:

  • 简化开发环境的配置;
  • 在类似质量保证/测试/生产环境的环境中,迅速测试应用程序(相比虚拟机,开销较小);
  • 与其他开发人员共享你的应用程序和环境,这样便于别人尽快熟悉情况。
  • 能够构建不同的容器(这在调试中极其有用)

安装

运行容器、因而运行Docker需要Linux机器。由于我们使用的是Mac,这就意味着我们需要虚拟机。为了让安装过程来得更容易,我们可以使用Boot2Docker,它可以安装Boot2Docker管理工具VirtualBox,并在Docker已安装的情况下在里面安装虚拟机。

 

Node.js开发人员宝典:上手Docker从这里开始

boot2docker

直接浏览到该链接,下载最新版本的Boot2Docker,并安装它(截至本文截稿时最新版本是Boot2Docker-1.5.0.pkg)。

https://github.com/boot2docker/osx-installer/releases/latest

安装完毕后,进入到你的Applications文件夹,打开Boot2Docker。那会在VirtualBox里面打开一个新的终端,运行几个命令,这些命令的作用基本上就是启动已经安装了Docker的虚拟机,然后设置几个环境变量,那样我们就能从终端访问该虚拟机。如果你不想总是打开Boot2Docker以便与Docker进行交互,只要运行下面几个命令:

  1. # 如果你还没有新的虚拟机,创建一个 
  2.  
  3. $ boot2docker init 
  4.  
  5. # 启动虚拟机 
  6.  
  7. $ boot2docker start 
  8.  
  9. # 设置必需的环境变量 
  10.  
  11. $ $(boot2docker shellinit) 

现在输入:

  1. $ docker run hello-world 

这会让Docker从Docker Hub下载hello-world映像,并启动基于它的容器。你的终端应该会给出类似如下的输出结果:

  1. Hello from Docker. 
  2.  
  3. This message shows that your installation appears to be working correctly. 

好了!Docker已安装完毕。

要是你遇到什么问题,欢迎留言交流,也可以在此(https://docs.docker.com/installation/mac/)参阅Docker的官方安装指示。

#p#

Docker文件和Docker Hub

在探讨下一步操作之前,我认为明白我们在执行$ docker run hello-world后发生的事情很重要,那样你不仅仅是复制粘贴接下来的指示。docker run是我们用来启动基于映像的容器的基本命令,同时将命令传送给它。在这里,我们说“Docker,启动基于映像hello-world的容器,不需要额外的命令。”然后,它从Docker Hub下载映像,并且启动VirtualBox虚拟机里面基于该映像的容器。但是hello-world映像来自哪里呢?这时候,Docker Hub有了用武之地。就像我们之前在引言部分提到的那样,Docker Hub是公共注册中心,含有与Docker一起使用的容器映像,以及由Docker、其他公司和个人构建的容器映像。你在这里可以找到我们刚执行的hello-world映像:

Docker Hub Hello-World映像(https://registry.hub.docker.com/u/library/hello-world/)

每个映像都是使用Docker文件构建的。在hello-world映像的描述部分,你能找到Docker文件的链接(https://github.com/docker-library/hello-world/blob/master/Dockerfile),该文件只有短短3行:

  1. FROM scratch 
  2.  
  3. COPY hello / 
  4.  
  5. CMD [“/hello”] 

Docker文件就是文本文件,含有如何构建容器映像方面的Docker指示。映像就好比是机器快照,而容器好比是机器的实际的运行实例。Docker文件总是会有这种格式:

  1. INSTRUCTION arguments 

所以在我们的hello-world例子中,我们可以看一下含有Docker文件的GitHub软件库的根。该映像是用另一个名为“scratch”的映像构建的(所有的Docker文件都是以FROM指示开头),然后将hello文件复制到系统的根,最后运行hello。你还能在这里找到hello文件的内容(https://github.com/docker-library/hello-world/blob/master/hello.asm),包括我们在终端中刚看到的输出结果。

Docker Pull:下载Ubuntu映像

我们已知道了安装的Docker已正确设置好,不妨开始使用它!下一步是获得Ubuntu映像。想找到映像,我们可以进入到Docker Hub网站(https://hub.docker.com),或者只要在终端中运行:

  1. $ docker search ubuntu 

这会给出名称中含有Ubuntu的所有映像的列表。我的终端中显示如下:

Node.js开发人员宝典:上手Docker从这里开始

输出结果按每个映像软件库中的星号数量来排序。你能看到上面有Official(官方)栏和Automated(自动)栏。

•官方映像是由docker-library项目维护的映像,并得到Docker团队的接受。这意味着,它们遵守这里的几个准则(https://docs.docker.com/docker-hub/official_repos/),其中一些位于git软件库;对该软件库至少要有只读权,以便用户能查看其内容。你可以依赖那些映像,顺利使用Docker。另外,与你需要使用USERNAME/IMAGE_NAME来获取的其他映像相反,这些映像完全只要由IMAGE_NAME(比如Ubuntu)用命令来指代。所有Docker文件都呈现在这种组织体系中(https://github.com/docker-library)。

•自动栏是指自动构建(Automated Build)映像。这完全意味着,映像是通过GitHub或BitBucker软件库里面的Docker文件构建的;对它进行更改后,它会自动更新。

不妨下载官方的Ubuntu映像:

  1. $ docker pull ubuntu 

$ docker pull IMAGE_NAME命令是明确下载映像的方式,但如果你使用$ docker run IMAGE_NAME命令,也能下载,就是Docker找不到你所指的那个映像。

Docker Run:运行我们的Ubuntu映像,访问容器

我们已经有了Ubuntu映像(我们的蓝图)。现在不妨启动基于该映像的新容器,并将命令传送给它:

  1. $ docker run ubuntu /bin/echo ‘Hello world’ 

这在你的终端中应该会给出消息“Hello World”。我们刚启动了一个运行Ubuntu完全隔离的实例的容器,并执行了命令,这很好,但是其实没多大用处。

于是,现在不妨运行新的容器以及Ubuntu,并连接到它:

  1. $ docker run -i -t ubuntu 

请注意:run命令很庞大(查看$ docker help run),我们会在下一篇博文中更深入全面地介绍。

-t旗标在我们的新容器里面分配了伪终端(pseudo-tty)或终端,-i旗标让我们可以获取容器的标准流(STDIN),从而建立交互性连接。如果一切顺利,你应该可以连接至容器里面的终端,并显示这样的结果:

  1. $ root@c9989236296d:/# 

运行ls –ls,就会发现运行中的命令就在Ubuntu系统的根里面。

Node.js开发人员宝典:上手Docker从这里开始

终端ubuntu

我认为,有必要暂停一分钟,考虑一下我们刚才执行的操作。这正是容器的出色方面之一。我们刚下载并启动了运行Ubuntu的容器。这一切在短短5分钟内发生的吗(取决于你的互联网连接速度)?拿这与下载虚拟机Ubuntu映像、启动新虚拟机作一下比较。后者可能是不是要花15分钟至30分钟?然后,构建、停止及重启新虚拟机,这个过程要花多久?如果你把这些时间都算上去,就会发现使用容器可以节省大量时间!

#p#

Docker Commit:安装node、npm和express,提交变更内容

好了,鉴于我们已在运行中的Ubuntu容器里面,不妨安装运行节点应用程序所需要的工具(切记:你只需要执行$ root:后面的部分):

  1. $ root: apt-get update 
  2.  
  3. $ root: apt-get install nodejs 
  4.  
  5. $ root: apt-get install nodejs-legacy 
  6.  
  7. $ root: apt-get install npm 

请注意:我们需要安装nodejs-legacy,才能运行express-generator模块。

运行node -v应该会得出输出结果:

  1. $ root: node -v 
  2.  
  3. v0.10.25 

节点安装完毕后,我们可以直接从npm安装express generator模块:

  1. $ root: npm install -g express-generator 

现在我们已有了容器,而且我们所需的一切都安装在里面。不妨接下来退出容器:

  1. $ root: exit 

我们退出容器后,Docker会停止运行它。我们可以使用$ docker ps命令列出容器,不妨这么做:

  1. $ docker ps -a 

Node.js开发人员宝典:上手Docker从这里开始

终端容器

$ docker ps命令默认情况下只显示运行中的容器,于是我们传递-a旗标,那样我们就能查看刚退出的Ubuntu容器。

现在,我们可以使用该容器来构建别人可以使用的新映像。为此,我们可以使用commit命令:

  1. $ docker commit -a "Your Name <youremail@email.com>" -m "node and express" CONTAINER_ID node-express:0.1 

commit命令只有几个参数。-a旗标设定作者,你可以使用-m旗标设定消息,最后我们可以引用容器ID和所创建容器的名称,这里是node-express。我们还可以在映像名称后面添加:0.1,为映像设定标签。如果我们运行:

  1. $ docker images 

我们应该会看到:

Node.js开发人员宝典:上手Docker从这里开始

终端容器

太棒了,你刚构建了第一个Docker映像!

现在,不妨为刚创建的映像添加另一个标签。运行:

  1. $ docker tag node-express:0.1 node-express:latest 

给映像标记特定的版本是个好做法,那样人家知道自己在到底运行哪个映像。添加latest标签大有帮助,那样别人在下载映像时就能用名称来指代你的映像(我们的例子中是node-express),Docker会自动下载latest标签版本。如果你再次运行$ docker images,就能看到我们的映像有两行,但它们都有同一个ID,这意味着它们并不占用硬盘中的任何额外空间。

现在我们就可以启动想与映像一同使用的多个容器!不妨删除旧的容器:

  1. $ docker ps -a 
  2.  
  3. $ docker rm YOUR_CONTAINER_ID 

不妨运行基于新映像的容器,使用-i -t旗标连接到它,将主机(VirtualBox)的端口8080暴露为容器(虚拟机)的端口3000:

  1. $ docker run -i -t -p 8080:3000 node-express 

不妨使用我们已安装的express-generator,构建一个新的Node.js应用程序:

  1. $ root: express mynodeapp 

按终端中的指示操作后,进入到应用程序文件夹,安装依赖项,启动该应用程序:

  1. $ root: cd mynodeapp 
  2.  
  3. $ root: npm install 
  4.  
  5. $ root: npm start 

现在,我们已有了一个在容器里面运行的Node.js应用程序,暴露端口3000。想查看这个应用程序,我们需要找到Boot2Docker虚拟机IP地址,为此打开另一个终端,运行:

  1. $ boot2docker ip 
  2.  
  3. 192.168.59.103 

另外切记:我们实际上暴露了容器的端口8080,以便访问端口3000。于是,进入到浏览器,打开:

  1. 192.168.59.103:8080 
  2.  
  3. website express 

现在,你可能会想:光拥有一个运行中的应用程序就要费这老大的劲!我早已有了开发环境,可以在30秒内完成这一切!没错,确实如此,但是在本教程中,我们运行的一个超级简单的应用程序根本没有许多依赖项。你在运行依赖项要多得多的实际项目时,可能需要开发环境拥有不同的程序包、Python、Redis、MongoDB、Postgres、Node.jsK io.js等。牵涉太多的方面,结果会让在你的计算机中正常运行的应用程序在另一台机器((或在质量保证/测试/生产环境)中却无法正常运行,这就是Docker大受欢迎的主要原因。回到本教程的引言部分,通过提供一种独立于硬件而执行的基本单元,该基本单元还能轻松运行、移动和共享,Docker绝对改变了我们开发、测试及共享应用程序的方式。

Node.js开发人员宝典:上手Docker从这里开始

#p#

Docker Push:推送容器映像,那样别人就能使用它

现在不妨共享我们这个“出色的”Ubuntu映像(已安装了node、npm和express-generator),那样别人也能使用它。退出运行中的Node应用程序和容器:

  1. # Ctrl+C to stop our node app 
  2.  
  3. $ root: exit 

直接进入到Docker Hub:http://hub.docker.com,设立一个免费帐户;

之后,回到终端,运行:

  1. $ docker login 

鉴于我们已通过命令行接口(CLI)登录上去,可以将映像推送到Docker Hub。不妨先对它进行更名,并为它添加用户名,所以就像添加标签:

  1. $ docker tag node-express your_docker_hub_username/node-express 
  2.  
  3. $ docker rmi node-express 
  4.  
  5. $ docker push your_docker_hub_username/node-express 

大功告成!现在,拥有Docker的人都可以执行:

  1. $ docker pull your_docker_hub_username/node-express 

拥有了与我们之前建立的环境一模一样的环境,而Ubuntu、Node.js、npm和express-generator程序包一应俱全。
 

责任编辑:Ophira 来源: 51CTO
相关推荐

2021-03-01 10:34:28

开发技能代码

2021-03-16 06:40:43

开源工具开源Node.js

2012-02-07 14:58:03

Node.js

2019-02-28 06:14:18

物联网物联网开发IOT

2019-07-12 13:59:21

Docker软件技术

2020-12-02 09:59:49

恶意软件Docker开发

2009-12-11 14:50:14

Visual Basi

2009-11-23 20:07:51

ibmdw开发

2021-02-19 09:33:01

kubernetesJAVA服务

2009-08-07 10:00:24

开发云计算应用开发云计算人员

2023-09-04 08:20:00

2012-05-30 15:15:42

ibmdw

2023-03-15 07:12:53

企业开发人员提供商

2015-02-13 09:13:22

Java开发Docker

2023-12-25 07:58:46

Python开发.NET

2010-08-09 16:09:25

2019-11-27 18:54:07

物联网数字孪生机器学习

2011-09-05 14:21:29

webOS

2013-04-15 10:00:09

程序员

2009-05-31 08:31:07

GoogleWaveTechCrunch
点赞
收藏

51CTO技术栈公众号