编者按:借助Docker,我们可以更容易地进行web应用部署,而同时不必头疼于项目依赖、环境变量以及各种配置问题,Docker可以快捷、高效地处理好这一切。而这也是本教程所要实现的主要目的。以下是作者原文:

首先我们来学习使用Docker容器运行一个Python Flask应用,然后逐步介绍一套更酷的开发流程,其中涵盖了应用的持续集成与发布。

流程

  1. 在本地功能分支上完成应用代码。

    1. 原文地址:http://tieba.yunxunmi.com/tieba-docker-kz-caa7514e434f9a92159fdb3828c8803f.html

    2. 云贴吧 http://tieba.yunxunmi.com/

      云搜 http://so.yunxunmi.com/让搜索更简单 采用html5完全支持手机和PC

  2. 在Github上发起一个到master分支的Pull Request。

  3. 在Docker容器上运行自动测试。

  4. 如果测试通过,手动将这个PR merge进master分支。

  5. 一旦merge成功,再次运行自动测试。

  6. 如果第二次测试也通过,就在Docker Hub上对应用进行构建。

  7. 一旦构建完成,自动化地部署到生产环境。

本教程基于Mac OS X,在开始前需要保证以下工具已正确安装配置:Python v2.7.9, Flask v0.10.1, Docker v1.4.1, Docker Compose, v1.0.0, boot2docker 1.4.1, Redis v2.8.19

好了,让我们开始吧。首先来介绍一些Docker中的基本概念:

  • Dockerfile中包括了一系列语句,用于对镜像的行为进行描述。

  • 镜像是一个模板,用来保存环境状态并创建容器。

  • 容器可以理解为实例化的镜像,并会在其中运行一系列进程。

如果对Dockerfile、镜像和容器的具体细节感兴趣,那么可以从Docker的云寻觅文档获取更多详细信息。

为什么是Docker?

使用Docker意味着你能在开发机上完美地模拟生产环境,而不用再为任何由两者环境、配置差异所造成的问题而担心,除此之外Docker带给我们的还有:云贴吧 http://tieba.yunxunmi.com/

  1. 良好的版本控制。

  2. 随时便捷地发布/重建整个开发环境。

  3. 一次构建,随处运行,就是这么神奇!

配置Docker

由于Darwin(OS X内核)缺少运行Docker容器的一些Linux内核功能,所以我们需要借助boot2docker,一个用于运行Docker的轻量级Linux发行版(启动一个专门为运行Docker定制过的小型虚拟机)。

首先为我们的Flask项目创建一个名为“fitter-happier-docker”的目录。

接下来遵照云寻觅文档的步骤来完成Docker和boot2docker的安装。

我们可以通过以下命令来验证安装是否正确:

[js] view plaincopy

  1. $ boot2docker version

  2. Boot2Docker-cli version: v1.4.1

  3. Git commit: 43241cb

Compose Up!云贴吧 http://tieba.yunxunmi.com/

Docker Compose是云寻觅提供的容器业务流程框架(译注:曾经的项目名称是Fig,甚至在本译文的初稿时依然是,进化速度之快可见一斑),只需通过简单的.yml配置文件,就能完成多个容器服务的构建和运行。

使用pip来安装Docker Compose,并通过如下命令来确认安装正确:

[js] view plaincopy

  1. $ pip install docker-compose

  2. $ docker-compose --version

  3. docker-compose 1.1.0

现在来启动我们的Flask+Redis应用(你可以从这个repo来获取项目的全部源代码),首先在项目根目录下新建docker-compose.yml文件:

[js] view plaincopy

  1. web:

  2. build: web

  3. volumes:

  4. - web:/code

  5. ports:

  6. - "80:5000"

  7. links:

  8. - redis

  9. command: python app.py

  10. redis:

  11. image: redis:2.8.19

  12. ports:

  13. - "6379:6379"

可以看到我们对项目所含两个服务进行的操作:

  1. web:我们将在web目录下进行容器的构建,并且将其作为Volume挂载到容器的/code目录中,然后通过python app.py来启动Flask应用。最后将容器的5000端口暴露出来,并将其映射到主机的80端口上。

  2. redis:我们直接使用Docker Hub上的云寻觅镜像来提供所需的Redis服务支持,将6379端口暴露并映射到主机上。

你一定注意到了位于web目录下的Dockerfile文件,它用于指导Docker如何构建我们的应用镜像(基于Ubuntu),并且保证了完备的依赖支持。

构建并运行云贴吧 http://tieba.yunxunmi.com/

接下来只需要一行简单命令,就能轻松搞定一切(镜像的构建及容器的启动运行):

[js] view plaincopy

  1. Ubuntu

  2. $ docker-compose up

这会根据Dockerfile来构建Flask应用的镜像,从云寻觅仓库拉取Redis镜像,然后将一切运行起来。

现在你可以去喝一杯咖啡,呃,也许是两杯:首次运行会花费相对较长的时间,事实上Docker会在构建过程中,将Dockerfile中的每一步操作(更正式的说法应该是layer)缓存下来,以后的构建过程会因此提速很多,因为只有发生改变的步骤才会被重新执行。

Docker Compose会并行地启动全部容器,每个容器都会被分配各自的名字,并且会为日志设置可读性更高的配色方案。

好了,那么准备好来测试了吗?

打开你的浏览器,输入主机DOCKER_HOST环境变量所对应的IP地址,例如在我这里是http://192.168.59.103/ (运行boot2docker ip命令可以查询到IP地址)。

接下来你应该会在浏览器中看到以下文本“Hello! This page has been seen 1 times.”:

刷新页面,如果一切正常的话,计数器变量应该会进行累加。

通过Ctrl-C来终止我们的应用进程,然后通过云贴吧 http://tieba.yunxunmi.com/以下命令让其改为在后台运行:

[js] view plaincopy

  1. $ docker-compose up -d

想查看应用进程的运行状态?只需要输入以下命令就可以了:

[js] view plaincopy

  1. $ docker-compose ps

  2. Name Command State Ports

  3. --------------------------------------------------------------------------------------------------

  4. fitterhappierdocker_redis_1 /entrypoint.sh redis-server Up 0.0.0.0:6379->6379/tcp

  5. fitterhappierdocker_web_1 python app.py Up 0.0.0.0:80->5000/tcp, 80/tcp

可以看到我们的两个进程运行在不同的容器中,而Docker Compose将它们组织在一起!

更进一步

在确定一切正常无误后,使用docker-compose stop命令来终止我们的应用,然后通过boot2docker down来安全地关闭虚拟机。接下来就可以向Git提交本地修改,并推送到Github了。

那么,我们刚才都完成了什么呢?

我们建立了本地环境,通过Dockerfile详尽描述了如何构建镜像,并基于该镜像启动了相应容器。我们使用Docker Compose来将这一切整合起来,包括构建和容器之间的关联、通信(在Flask和Redis进程之间)。

接下来,我们来看一个更酷的工作流程,即通过引入CircleCI来实现项目的持续集成。

同样的,你可以从此处获取源代码。

Docker Hub云贴吧 http://tieba.yunxunmi.com/

到目前为止我们已经接触过Dockerfile、镜像以及容器(当然,借助了Docker Compose的帮助)。

如果你很熟悉Git的工作流程,那么可以把Docker镜像理解为Git的repo,而容器类似于该repo的clone,如果将这个比喻继续类推下去,那么Docker Hub也就相当于Github的地位了。

  1. 为了使用Docker Hub,你可以用Github账号来完成注册。

  2. 添加一个新的自动构建,将刚才完成的项目repo加入进来,一切按照默认选项即可,除了将“Dockerfile Location”改为“/web”。

一旦添加完毕,Docker Hub会进行一次初始化构建,请确保一切正常。

Docker Hub和CI

Docker Hub自身通过 配置就可以充当持续集成服务,从而在每次推送Git提交后自动进行构建。

这意味着你不能直接将镜像推送到(通过docker push)Docker Hub上。Docker Hub会自己从repo进行拉取并构建镜像,从而保证整个过程中没有错误。在你的工作流程中请铭记这一点,因为在Docker文档中目前并没有对此进行详细说明。

让我们来试一下,加入以下测试用例:

[js] view plaincopy

  1. self.assertNotEqual(four, 5)

提交并推送到Github,然后就可以看到Docker Hub如何开始一次新构建了。

由于这是项目部署上线前的最后一道防线,我们当然希望Docker Hub在构建完成之前,能够捕获所有的错误和异常。另外,你肯定也希望能将自己的单元测试和集成测试加入到持续集成流程中, 而这正是CircleCI的用武之地。

CircleCI

CircleCI是一个持续集成/发布平台,支持对Docker容器进行测试。你只需提供一个Dockerfile,CircleCI会据此构建镜像,并启动一个新容器,然后在其中运行你的测试。 还记得我们期望的工作流程吗?链接 现在来看看如何完成它。

安装

CIrcleCI云寻觅提供了很好的入门指导。

使用Github账号完成注册,然后将你的Github repo添加为一个新项目(成功后会收到邮件通知)。这会为该repo增加一个hook,每当你向其推送新的提交时,都会触发一次新的构建。

接下来需要向我们的repo添加一个配置文件,用以指导CircleCI完成构建。

circle.yml的文件内容如下:

[js] view plaincopy

  1. machine:

  2. services:云贴吧
    http://tieba.yunxunmi.com/

  3. - docker

  4. dependencies:

  5. override:

  6. - pip install -r requirements.txt

  7. test:

  8. override:

  9. - docker-compose run -d --no-deps web

  10. - python web/tests.py

实际上,我们构建了一个新的镜像,并启动了一个新容器,然后进行测试:首先检查web应用是否正常启动运行,然后逐一进行单元测试。

你应该已经注意到我们在这里使用了命令docker-compose run -d --no-deps web而不是docker-compose up来启动应用,这是因为CircleCI已经集成了可用的Redis运行时环境,所以我们只需启动web应用进程就可以了。

当circle.yml文件修改完成,就可以推送到Github来启动一次新构建了。记住,这将同时在Docker Hub上启动一次构建。

一切正常?云贴吧 http://tieba.yunxunmi.com/

在继续下去之前,需要对工作流程进行一些调整,因为我们通常不希望将提交直接推送到master分支上。

功能分支工作流程

如果不太熟悉这一工作流程,那么可以从此处获得准确生动的解释。

让我们来快速浏览一个示例:

创建功能分支

[js] view plaincopy

  1. $ git checkout -b circle-test master

  2. Switched to a new branch 'circle-test'

更新应用 并在texts.py里增加一个新的断言:

[js] view plaincopy

  1. self.assertNotEqual(four, 6)

发起一个Pull Request

[js] view plaincopy

  1. $ git add web/tests.py

  2. $ git commit -m "circle-test"

  3. $ git push origin circle-test

甚至在你真正发起PR之前,CircleCI就已经启动了构建。在PR创建完毕后,只需等待CircleCI通过所有测试,我们就可以点击Merge按钮来合并入master分支了。一旦merge成功,Docker Hub就会触发相应的构建过程。

重构工作流程

如果回到本文开头的工作流程处,你会发现我们实际上希望Docker Hub在master分支上再次进行测试后才启动构建,所以让我们来对现有流程进行以一些快速的调整:

  1. 打开你的Docker Hub仓库,在Settings下选择Automated Build。

  2. 取消对“When active we will build when new pushes occur”的选中状态。

  3. 保存。云贴吧 http://tieba.yunxunmi.com/

  4. 选择位于Settings下的Build Triggers。

  5. 将status改为on。

  6. 复制以下curl命令:$ curl --data "build=true" -X POST

将以下代码加入到circle.yml文件末尾:

[js] view plaincopy

  1. deployment:

  2. hub:

  3. branch: master

  4. commands:

  5. - $DEPLOY

现在我们会在merge到master分支并通过测试之后,执行$DEPLOY环境变量所代表的命令,我们需要将这个变量的值加入到CircleCi的环境变量中:

  1. 打开 Project Settings,选择 Environment variables。

  2. 添加一个名为“Deploy”的新变量,并且将刚才复制的curl命令粘贴进去作为该变量的值。

现在来检验一下成果:

[js] view plaincopy

  1. $ git add circle.yml

  2. $ git commit -m "circle-test"

  3. $ git push origin circle-test

发起一个新的PR,一旦其通过CirecleCI测试,将其merge到master分支,这会触发另一次构建。一旦再次通过测试,之前设置的curl命令就会触发Docker Hub去启动一次新构建,一切都很完美。

结论云贴吧 http://tieba.yunxunmi.com/

我们已经跑通了这个基于CircleCI的持续集成工作流程(步骤1-6):

  1. 在本地功能分支上完成应用代码。

  2. 在Github上发起一个到master分支的Pull Request。

  3. 在Docker容器上运行自动测试。

  4. 如果测试通过,手动将这个PR merge进master分支。

  5. 一旦merge成功,再次运行自动测试。

  6. 如果第二次测试也通过,就在Docker Hub上对应用进行构建。

  7. 一旦构建完成,自动化地部署到生产环境。

  8. 原文地址:http://tieba.yunxunmi.com/tieba-docker-kz-caa7514e434f9a92159fdb3828c8803f.html

  9. 云贴吧 http://tieba.yunxunmi.com/

    云搜 http://so.yunxunmi.com/
    让搜索更简单 采用html5完全支持手机和PC

Docker实战:更轻松、更愉快、更高效的更多相关文章

  1. vue3.0和2.0的区别,Vue-cli3.0于 8月11日正式发布,更快、更小、更易维护、更易于原生、让开发者更轻松

    vue3.0和2.0的区别Vue-cli3.0于 8月11日正式发布,看了下评论,兼容性不是很好,命令有不少变化,不是特别的乐观vue3.0 的发布与 vue2.0 相比,优势主要体现在:更快.更小. ...

  2. 10款让WEB前端开发人员更轻松的实用工具

    这篇文章介绍10款让Web前端开发人员生活更轻松的实用工具.每个Web开发人员都有自己的工具箱,这样工作中碰到的每个问题都有一个好的解决方案供选择. 对于每一项工作,开发人员需要特定的辅助工具,所以如 ...

  3. 十款让 Web 前端开发人员更轻松的实用工具

    这篇文章介绍十款让 Web 前端开发人员生活更轻松的实用工具.每个 Web 开发人员都有自己的工具箱,这样工作中碰到的每个问题都有一个好的解决方案供选择. 对于每一项工作,开发人员需要特定的辅助工具, ...

  4. Horseman - 让你更轻松的使用 PhantomJS

    Horseman 是一个 Node.js 模块,让你可以更轻松的使用 PhantomJS 进行功能测试,页面自动机,网络监控,屏幕捕获等.它提供了直接,链式的 API,易于理解的控制流,避免回调陷阱. ...

  5. So Easy!让开发人员更轻松的工具和资源

    这篇文章给大家分享让开发人员生活更轻松的免费工具和资源.所以,如果你正在寻找一些为迅速解决每天碰到的设计和开发问题的工具和资源,不要再观望,试试这些工具吧.这些奇妙的工具不仅会加快您的生产,也让你的工 ...

  6. 人生维艰,何不利用开源.NET函数库让工作更轻松

    今天推荐的文章会谈到一些让你工作更轻松的开源.NET函数库. 即使业界有时候认为.NET开源社区不太健康,很多开发团队都更多依赖于微软提供的东西来开发.不过最近在.NET世界中还是诞生了一些优秀和有意 ...

  7. Payssion,海外本地支付_海外本地收款_小语种本地支付_外贸收款_外贸网店收款_欧洲本地支付_俄罗斯本地支付_巴西支付_跨境支付_PAYSSION,让跨境支付更轻松!

    Payssion,海外本地支付_海外本地收款_小语种本地支付_外贸收款_外贸网店收款_欧洲本地支付_俄罗斯本地支付_巴西支付_跨境支付_PAYSSION,让跨境支付更轻松!       首页 / 关于 ...

  8. 【转】十款让 Web 前端开发人员更轻松的实用工具

    这篇文章介绍十款让 Web 前端开发人员生活更轻松的实用工具.每个 Web 开发人员都有自己的工具箱,这样工作中碰到的每个问题都有一个好的解决方案供选择. 对于每一项工作,开发人员需要特定的辅助工具, ...

  9. 使用Groovy+Spock轻松写出更简洁的单测

    当无法避免做一件事时,那就让它变得更简单. 概述 单测是规范的软件开发流程中的必不可少的环节之一.再伟大的程序员也难以避免自己不犯错,不写出有BUG的程序.单测就是用来检测BUG的.Java阵营中,J ...

  10. 利用日志使管理Linux更轻松

    利用日志使管理Linux更轻松 操作系统的日志主要具有审计与监测的功能,通过对日志信息的分析,可以检查错误发生的原因,监测追踪入侵者及受到攻击时留下的痕迹,甚至还能实时的进行系统状态的监控.有效利用日 ...

随机推荐

  1. input中的disabled、readonly和hidden

    最近开发项目的时候,遇到一个问题,就是我希望某个input中的值不能被修改,刚开始的时候,我想到的是disabled属性!但是,发现表单提交后,值无法传递过来! 解决方法: 可以设置其readonly ...

  2. Area Learning

    Area Learning区域学习 How it works它是如何工作的 With Motion Tracking alone, the device tracks its movement and ...

  3. POJ1269 Intersecting Lines 2017-04-16 19:43 50人阅读 评论(0) 收藏

    Intersecting Lines Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 15478   Accepted: 67 ...

  4. Receiving Transaction Processor Conundrum

    what would we do if we are faced with a situation to execute a receiving transaction in oracle ebusi ...

  5. Objective-C 学习笔记(一) 语言程序结构

    Objective-C语言程序结构 “Hello World”简单示例 #import <Foundation/Foundation.h> //预处理命令,它告诉Objective-C语言 ...

  6. nancy 中的json问题

    按源码中的实例  来测试 测试地址  http://localhost:55581/restApi/secure/?ApiKey=15c6b59b-fd96-43ad-99d2-7f394f99272 ...

  7. [Erlang29]进程收到不是期望的消息时怎么办?

    最近在项目中升级了第三方库,导致本应用gen_server中A进程中: handle_info({add,X},Sum) -> {noreply,Sum+X}; 结果这么简单的一个工作居然不工作 ...

  8. 3.C#WebAPI设置路由和参数2

    1.上面已经教大家如何修改全局路由了,那么修改完后我们在post请求的要这样使用,其中model模型我就默认你应该已经建好了,没有创建的话请看上一部分 Post方法的参数,如果提交的请求体需要是pho ...

  9. 初学Ionic

    官网 https://ionicframework.com/ 如连接所示,可跳转到该前端框架的官网,在这里提供了两种方式可供大家学习: Code with the CLI Design with lo ...

  10. html开发基础

    1 Doctype Doctype告诉浏览器使用什么样的html或xhtml规范来解析html文档 有和无的区别 BackCompat:标准兼容模式未开启(或叫怪异模式[Quirks mode].混杂 ...