http://cnodejs.org/topic/53f494d9bbdaa79d519c9a4a

最近研究了几天docker的快速部署,感觉很有新意,非常轻量级和方便,打算在公司推广一下,解放运维,省得每次部署一台新服务器都去跑安装脚本了,对于我们开发人员也是好事情,无需写太多重复的部署文档,直接将docker的images丢上服务器就可以运行了。

可能还有一些同学不了解docker这个项目,docker是由go语言编写的,一个快速部署的轻量级虚拟技术项目,他允许开发人员将自己的程序和运行环境一起打包,制作成一个docker的image(镜像),这样部署到服务器上,也只需要下载这个image就可以将程序跑起来,免去每次都安装各种依赖和环境的麻烦,还能够做到应用程序之间的隔离,因为我们公司部署的python程序,这样一来我也省去了每次都到新服务器配置 vitualenv了。

官网地址:http://www.docker.com/

如此看来docker非常适合做小巧的外包项目,免去每次都为客户配置一遍运行环境,费时费力。

一、安装: 安装很简单,直接进入下载页面,根据自己的操作系统下载相对应的安装包即可,下面说一下windows安装:

下载地址:https://docs.docker.com/installation/windows/

在安装docker时,会附带安装git和VirtualBox,所以可能安装时间稍微长一些,安装完毕重启系统,以管理员身份进入命令行,就可以使用进入linux虚拟机命令 “boot2docker” ,由于docker目前的镜像只针对linux,所以windows下面必须安装虚拟机才能使用。

第一次使用boot2docker start,会出现错误:

    Failed to get machine "boot2docker-vm": machine does not exist

没关系,这是因为没有boot2docker iso的镜像所致,执行:

    $ boot2docker init

就可以初始化镜像,耐心等待下载并安装完毕后,我们继续执行开启虚拟机。

    $ boot2docker start 

在windows下是无法直接使用cmd窗口来操作linux系统的,所以我们需要进入linux虚拟机来操作docker,执行:

    $ boot2docker ssh

就可以进入linux虚拟机,如果要退出并关闭虚拟机,执行如下命令:

    $ exit$ boot2docker stop

调试时查看虚拟机ip地址,后面部署测试环境会用到:

    $ boot2docker ip192.168.59.103

我们可以通过ssh的ip地址192.168.59.103,用户名 docker,密码 tcuser,登录到虚拟机中去。

如果不幸长时间无法init成功,说明镜像被GFW挡住了,手动去github上下载镜像,地址为:

https://github.com/boot2docker/boot2docker/releases

如果还是无法下载成功,我是好心人,把1.1.2版本的boot2docker.iso镜像丢到了百度云上:

http://pan.baidu.com/s/1c01qieG

下载完毕之后放到目录:

    C:\Users\你的用户名\.boot2docker\boot2docker.iso

然后再执行

    $ boot2docker init

二、下载镜像,安装环境 我们先执行如下命令,启动虚拟机:

    $ boot2docker start2014/08/18 21:22:41 Waiting for VM to be started... ........... 2014/08/18 21:23:21 Started. 2014/08/18 21:23:21 Docker client does not run on Windows for now. Please use 2014/08/18 21:23:21 "boot2docker" ssh 2014/08/18 21:23:21 to SSH into the VM instead.

如果我们的物理机内存低于4G,那么跑这个boot2docker可能需要手动设置内存占用大小:

    $ boot2docker start -m=512

我们利用命令就可以进入linux虚拟机了

    $ boot2docker ssh ##        .## ## ##       == ## ## ## ## === /""""""""""""""""\___/ === ~~~ {~~ ~~~~ ~~~ ~~~~ ~~ ~ / ===- ~~~ \______ o __/ \ \ __/ \____\______/ _ _ ____ _ _ | |__ ___ ___ | |_|___ \ __| | ___ ___| | _____ _ __ | '_ \ / _ \ / _ \| __| __) / _` |/ _ \ / __| |/ / _ \ '__| | |_) | (_) | (_) | |_ / __/ (_| | (_) | (__| < __/ | |_.__/ \___/ \___/ \__|_____\__,_|\___/ \___|_|\_\___|_| boot2docker: 1.1.2 master : 740106c - Thu Jul 24 03:24:10 UTC 2014

执行 docker 命令,会有一个命令列表,里面列出了所有 docker 支持的功能,列表如下:

    Commands:attach    Attach to a running container build Build an image from a Dockerfile commit Create a new image from a container's changes ... ...

下面会对一些常用的命令进行示例说明,我们可以通过如下命令,先查找centos的镜像,并把他下载下来

    $ docker search centos #查找centos名字的镜像$ docker pull centos #下载官方纯净版本的centos镜像

在调用search命令时,你会看到有好多centos包,他们都是这样的<username>/<image_name>,这些不在根目录的镜像都是非官方的,是其他用户提交到docker hub上去的,耐心等待片刻我们就可以将centos的镜像拉下来了。

如果脸黑,镜像又不幸被墙,那么试试加上下面的hosts:

    54.234.135.251 get.docker.io 54.234.135.251 cdn-registry-1.docker.io

成功下载好centos镜像之后,我们可以利用如下命令来查看镜像列表:

    $ docker imagesREPOSITORY          TAG                 IMAGE ID            CREATEDVIRTUAL SIZEcentos              centos6             b1bd49907d55        2 weeks ago212.5 MB centos centos7 b157b77b1a65 2 weeks ago 243.7 MB centos latest b157b77b1a65 2 weeks ago 243.7 MB

接下来我们就利用centos7这个镜像输出一段 hello world

    $ docker run b15 /bin/echo 'Hello world' Hello world

注意这里的 b15,他表示centos7这个images的id,不用全部打全,只要保证输入的id前几位能找到唯一镜像即可,这点很赞。 稍微复杂一点的例子:

    $ docker run  -i -d -t b15 /bin/sh -c "while true; do echo hello world; sleep 1; done"

-i表示同步container的stdin,-t表示同步container的输出,-d表示deamon,以后台启动这个container,执行这个container是永远不会停止的,每一秒钟都会输出hello world。

至于什么是container,container和image的关系我们下一段再说,列出镜像的历史:

    $docker history image_name

三、安装环境 在开始第三段介绍之前,有必要说几个利用windows cmd窗口的小技巧。

1、如果想要使用标记选中功能,你会发现,当我们进入 boot2docker ssh 之后,鼠标对窗口的右键是无效的,所以想要利用标记选中窗口内的文字得这么弄:“点击左上角图标->编辑->标记”,这样就可以使用标记了

2、如果从其他地方复制了命令,但是窗口没有右键无法粘贴怎么办?用和1相同的办法:“点击左上角图标->编辑->粘贴”。

3、坑爹的windws如果命令太长,在boot2docker ssh里换行会错位的,在“点击左上角图标->属性->布局->屏幕缓冲区大小和窗口大小”的数值,保证长的命令也在一行内就没有问题了,注意要重启cmd窗口。

接下来我们简单说明一下image和container的关系,image顾名思义就是镜像的意思,我们把他理解为一个执行环境(env),当我们执行了docker run命令之后,dock就会根据当前的image创建一个新的container,container更像是一个操作或者程序运行的一个沙箱,他们互相独立,但是都运行在image创建的执行环境之上,根据上一段我们执行了2个run的任务,也就创建了2个独立的container,我们通过命令

    $ docker ps #查看当前运行的container$ docker ps -a #查看所有的container CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES d1eca89869d0 centos:centos7 /bin/sh -c 'while tr 13 minutes ago Exited (0) 7 minutes ago distracted_mcclintock 0b71024c8a95 centos:centos7 /bin/sh -c 'while tr 15 minutes ago Exited (0) 7 minutes ago pensive_meitner 79a488c9cfb6 centos:centos7 console 22 minutes ago sick_babbage 06f43c19d10a centos:centos7 /bin/echo 'Hello wor 25 minutes ago Exited (0) 25 minutes ago berserk_einstein

我们可以分别利用命令对image和container进行删除

    $ docker rm #删除container$ docker rmi #删除image $ docker rm `docker ps -a -q` #删除所有容器

这样执行一次run就创建一个container,势必会造成大量的无用的container,可能我不需要持久化保存container,如果在docker run命令加上 --rm=true 选项,那当这个container执行完毕,将自动自己删除,保证了container数量不会泛滥增长。

我们之前下载纯净版centos7是没有任何第三方软件的,包括wget,ping等命令都要通过yum工具来重新安装,我们当然不想每次都重新安装这些东西,我不仅希望要把一些常用的库安装到的image中去,同时还希望把程序运行的环境也安装进去,所以image更像是一个系统的模版。

你会发现,当你执行如下命令,wget命令时安装成功了,但是当你下次执行wget命令时,又会报错,说找不到这个命令,到底是怎么回事呢?

    $ docker run -t b15 yum install -y wget #通过yum工具安装wget命令 #安装完毕后,执行wget会报没有这个命令 $ docker run -t b15 wget http://www.baidu.com 2014/08/18 15:42:19 exec: "wget": executable file not found in $PATH

为什么会出现这个问题呢?答案就是我们上面所说的那样,每次执行docker run都会去独立的创建一个新的container来执行程序,所以我们必须手动把这些对container的更改提交成一个新的image,才能够依据这个image执行wget操作。

我们先把当前所有的container都删除,然后直接登录到container的bash命令窗口中去,免得每次都去输入docker run了

    $ docker run -t -i b15 /bin/bash bash-4.2#

这样我们进入了一个新的container,依据centos7作为模板,我们将要在其上面安装wget工具,直接执行

    $ yum install -y wget

安装完毕之后,我们执行exit退出container 输入docker ps -a 我们找到刚才安装过wget工具的container ID,我们要把这个container重新做成一个新的image模版,这个模版将带wget命令。

    $ docker ps -aCONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES26cc82ad29af centos:centos7 /bin/bash 3 minutes ago Exited (0) 5 seconds ago desperate_mccarthy

我们执行如下命令,将一个安装过软件的container提交为一个image

    $ docker commit 26  wget-centos7 60cd26c6ca1e753bf77aa913ed7b826767a678b75f6dd8421353f6c0899d3e5e

我们查看当前image镜像的列表:

    wget-centos7        latest              60cd26c6ca1e 37 seconds ago 304.6 MB centos centos6 b1bd49907d55 2 weeks ago 212.5 MB centos centos7 b157b77b1a65 2 weeks ago 243.7 MB centos latest b157b77b1a65 2 weeks ago 243.7 MB

你会发现多了一行我们刚才提交的 wget-centos7 的image镜像记录,现在我们执行这个镜像的wget命令,看看会不会报错

    $ docker run -t -i --rm=true 60 wget http://www.baidu.com --2014-08-18 15:54:55-- http://www.baidu.com/ Resolving www.baidu.com (www.baidu.com)... 180.97.33.108, 180.97.33.107 Connecting to www.baidu.com (www.baidu.com)|180.97.33.108|:80... connected. HTTP request sent, awaiting response... 200 OK

执行完毕后,docker自动删除这个container,并且至今报错的wget命令无法找到也不会出错了。

第二种安装环境的办法,类似脚本安装,我们预先录入好一系列安装脚本,可以让docker帮我们依次执行这些安装脚本,然后生成image,例如有安装脚本Dockerfile:

    # This is a commentFROM centosMAINTAINER doublespout <doublespout[@gmail](/user/gmail).com> RUN yum install -y wget

我们执行如下命令进行创建images

    $ mkdir wget$ cd wget$ vi Dockerfile #将上面内容复制进去 $ docker build -t="doublespout/wget" ./ #将看到安装脚本的执行输出,安装完成后,执行 docker images 就可以看到我们刚才创建的镜像了 docker images

container 和 host 文件互相拷贝:

1、从container往host拷贝文件:

    docker cp <container_id>:/root/hello.txt .

2、从host往container里拷贝文件,比较麻烦一点,首先停止Contaitner(当然不停止也能拷贝)

    docker stop <container_name_or_ID>

然后执行拷贝操作,执行完成之后就能看到Contaitner里有这个文件拉

    #执行命令找到程序pidContainerID=$(docker inspect --format {{.Id}} <container_name_or_ID>) cp /tmp/tmp.txt /var/lib/docker/aufs/mnt/<ContainerID>/tmp/

四、发布应用程序 我们根据上一段的步骤,手动将node.js环境装好container并且发布成image,并保存"app.js"文件到"/var/nodejs/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); //注意这边不能和官网示例那样监听127.0.0.1 console.log('Server running at http://0.0.0.0:1337/');

执行如下命令,运行container:

    $ docker run -d -i -p --name=nodeapp 1337:1337 fa node /var/nodejs/app.js #32bac9ed8ba055c935bd641d23097a36a573a243ee942358fd74dc4140308bc6

其中fa是我创建的镜像id,这个值因人而异,name参数是给这个container取名字,必须是唯一的。

-p参数就是类似端口映射的功能,将主机的端口1337映射到contianer的1337端口,我们可以运行 docker ps,查看正在运行的container,打开浏览器,就能够看到 hello world了。

用同样的方法就可以将我们开发好的应用快速部署到生产服务器上去了。如果在docker run命令需要设置cpu的支持数和权重值可以这样:

     -c, --cpu-shares=0 CPU shares (relative weight) --cpuset="" CPUs in which to allow execution (0-3, 0,1)

另外一个小敲门,如果我想要进入一个在运行中的docker container时,可以使用 docker attach,连上这个container的输入和输出。

五、将多个 container 连接起来

我现在先下载一个redis数据库image,这也是以后做项目的常规用法,数据库单独用一个image,程序一个image,利用docker的link属性将他们连接起来。

    $ docker pull redis #下载官方的redis镜像,耐心等待一段时间

接着我们执行命令启动redis镜像到一个container,开启redis-server持久化服务

    $ docker run --name redis-server -d redis redis-server --appendonly yes

然后我们再启动一个redis镜像的container作为客户端连接它

    $ docker run -it --link redis-server:redis --rm redis /bin/bash redis[@7441b8880e4e](/user/7441b8880e4e):/data$ env #想要知道当前我们在主机还是container,注意$前面的host和name REDIS_PORT_6379_TCP_PROTO=tcp HOSTNAME=7441b8880e4e TERM=xterm REDIS_NAME=/boring_perlman/redis REDIS_PORT_6379_TCP_ADDR=172.17.0.34 #redis服务器ip REDIS_PORT_6379_TCP_PORT=6379 #redis服务器端口 PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin PWD=/data REDIS_PORT_6379_TCP=tcp://172.17.0.34:6379 SHLVL=1 REDIS_PORT=tcp://172.17.0.34:6379 HOME=/ _=/usr/bin/env $ redis-cli -h "$REDIS_PORT_6379_TCP_ADDR" -p "$REDIS_PORT_6379_TCP_PORT" 172.17.0.34:6379> set a 1 #成功连入redis数据库服务器 OK 172.17.0.34:6379> get a "1" 172.17.0.34:6379>

通过这样的方法,我们就可以将发布的应用程序和数据库分开,单独进行管理,以后对数据库进行升级或者对程序进行调整两者都没有冲突,系统环境变量我们可以通过程序的os模块来获得。

六、文件卷标加载 比如我们想要一个日志文件保存目录,如果直接写入container,那样image升级之后,日志文件处理就比较麻烦了,所以就需要将主机的文件卷标挂载到container中去,挂载方法如下:

    $ docker run --rm=true -i -t --name=ls-volume -v /etc/:/opt/etc/ centos ls /opt/etc boot2docker hostname ld.so.conf passwd- securetty sysconfig default hosts mke2fs.conf pcmcia services sysctl.conf fstab hosts.allow modprobe.conf profile shadow udev group hosts.deny motd profile.d shadow- version group- init.d mtab protocols shells gshadow inittab netconfig rc.d skel gshadow- issue nsswitch.conf resolv.conf ssl host.conf ld.so.cache passwd rpc sudoers

如果想要挂载后的文件是只读,需要在这样挂载:

    -v /etc/:/opt/etc/:ro #read only

我们也可以挂载其他container中的文件系统,需要用到 -volumes-from 参数,我们先创建一个container,他共享/var/目录给其他container。

    $ docker run -d -i -t -p 1337:1337 --name nodedev -v /var/ fa node /var/nodejs/app.js

然后我们启动一个ls-var的container来挂载nodedev共享的目录:

    $ docker run --rm=true -i -t --volumes-from nodedev --name=aaa1 centos ls /var adm db games kerberos local log nis opt run tmp yp cache empty gopher lib lock mail nodejs preserve spool var

我们打印var目录,会发现多了一个nodejs的目录,就是从nodedev中的container挂载过来的。其实我们挂载其他container的路径都是在根目录上的。

七、发布到docker hub上去

我们做完镜像,就需要将镜像发布到docker hub上,供服务器下载然后运行,这类似git仓库,将自己开发的东西丢到云服务器上,然后自己在其他机器或者其他开发者可以下载镜像,并且从这个镜像开始运行程序或者再进行2次制作镜像。

我们需要先登录docker帐号,执行:

    $ docker login #输入你在docker官网注册的帐号和密码就可以登录了$ docker push <用户名>/<镜像名> #将你制作的镜像提交到docker hub上

非官方不允许直接提交根目录镜像,所以必须以<用户名>/<镜像名>这样的方式提交,比如 doublespout/dev 这样

八、总结

docker快速部署介绍完毕了,总结一下,要创建一个简单项目使用的步骤: 1、安装配置docker

2、pull镜像,安装程序执行环境

3、pull数据库镜像

4、开发程序

5、push 程序的镜像

6、服务器安装配置docker

7、运行数据库镜像

8、运行程序镜像,并且把数据库镜像link进来,并且挂载主机的日志目录或其他上传目录。

使用了docker以后,环境配置只需一次,免去了开发部署一套,测试部署一套,生产又部署一套的麻烦,以后程序搬家也是非常简单。

最后分享一个小敲门,如何像使用linux虚拟机那样运行一个container,比如我我们想要直接登录container执行多个任务,又不想直接借助 docker run 命令,以后我们还想登录到这个container来查看运行情况,比如执行top,ps -aux命令等等。

   $ docker run -d -i -t -p 1337:1337 fa /bin/bash $ docker attach 58 bash-4.2#

这样我们就可以通过进入container来调试程序了。但是一旦执行ctrl+d或者exit,container就将退出,这个方法也只适用于开发调试的时候。 最后请跳出 container 是一个小的vps的概念,详见另一篇文章.

不要用ssh连接直接到你的container 常用的Dockerfile命令示例

74 回复

私活利器,docker快速部署node.js应用相关推荐

  1. 10个Spring Boot快速开发的项目,接私活利器(快速、高效)

    本文为大家精选了 码云 上优秀的 Spring Boot 语言开源项目,涵盖了企业级系统框架.文件文档系统.秒杀系统.微服务化系统.后台管理系统等,希望能够给大家带来一点帮助:) 1.项目名称:分布式 ...

  2. 飞特商城后台管理系统是接私活利器,企业级快速开发框架 商城后台 取之开源,用之开源

    简介: 飞特后台管理系统是接私活利器,企业级快速开发框架 技术选型 注册中心:zookeeper 分布式治理框架 :dubbo 核心框架:Spring Boot 权限框架:Apache Shiro 模 ...

  3. 在Google Cloud Platform上持续部署Node.js

    by Gautam Arora 由Gautam Arora 在Google Cloud Platform上持续部署Node.js (Continuous Deployment for Node.js ...

  4. 如何在Docker上构建Node.js应用程序

    Docker has been the latest trending topic over the past couple of years and if you haven't been to s ...

  5. centos 云服务器部署Node.js项目

    Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境,用来方便地搭建快速的易于扩展的网络应用.Node.js 使用了一个事件驱动.非阻塞式 I/O 的模型,使其轻量又 ...

  6. 云服务器(CentOS 7)上面部署Node.js环境

    云服务器(CentOS 7)上面部署Node.js环境 文章目录 云服务器(CentOS 7)上面部署Node.js环境 背景信息 步骤一:部署Node.js环境 部署Node.js环境 步骤二:部署 ...

  7. 阿里服务器部署Node.js项目(CentOS)

    Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境,用来方便地搭建快速的易于扩展的网络应用.Node.js 使用了一个事件驱动.非阻塞式 I/O 的模型,使其轻量又 ...

  8. 部署Node.js项目(CentOS)

    原文链接 部署Node.js项目(CentOS) 驻云科技  2017-05-11 17:46:43  浏览334  评论1  发表于: 阿里云服务 >> 最佳实践 云栖社区 linux  ...

  9. 开发笔记13 | 部署 Node.js 应用程序到云 ECS

    <<系列文章集 前言 在之前的一篇文章中,我们介绍了 如何将一个本地的 Java 应用程序直接部署到阿里云 ECS ,有不少读者反馈,在本文中,我们来介绍如何部署 Node.js 应用程序 ...

最新文章

  1. $state 新标签页
  2. [翻译] MotionBlur
  3. Windows环境下如何配置wamp的虚拟域名
  4. docker搭建lnmp环境错误总结
  5. qt 表格中插入一行_在EXCEL表格中,快速插入多行、多列的技巧
  6. 狸窝音频剪辑软件_「附下载链接」常用的5款视频格式转换软件,收藏起来吧...
  7. 活动目录应用篇一:使用windows server 2008 backup备份AD是的账户权限问题
  8. 就算会用python画颗心,可你依然还是只单身狗
  9. 20200819:力扣202周周赛题解记录
  10. 多角度闲聊游戏打击感
  11. android 挖孔屏适配_小米公布安卓Q升级适配计划,共11款机型
  12. python窗口怎么显示,如何使用Python在没有窗口的屏幕上显示文本
  13. VC++2010安装教程
  14. Unity编程软件介绍
  15. kali 控制安卓手机拍照,查看定位,获取通信录,以及其他
  16. word自动添加标题以及批量生成图片题注
  17. 国内外三维图形引擎研究现状
  18. c++ ends理解
  19. 关于学习软件逆向分析意义的阐述
  20. 傅连仲主编的《计算机应用基础》,学生教学论文,关于计算机应用基础课程标准研读的必要性相关参考文献资料-免费论文范文...

热门文章

  1. 来自未来,2022 年的前端人都在做什么?
  2. 6 个对所有 Web 开发者都有用的 GitHub 仓库
  3. swift - 根试图控制器的手势返回冲突 - push 新的tabbar控制器手势冲突
  4. 解决 spring-cloud-starter-zipkin 启动错误
  5. Hotspot hotswap, who and who are best freinds
  6. 七招挽回受损WORD文档
  7. 【转】2007高校BBS上20个睿智的冷笑话
  8. CentOS5安装Nginx1.4+PHP5.5 FastCGI
  9. [sol]250OJ 1~10
  10. [Halcon] 算子学习_Calibration_Calibration Object