猛禽的编程艺术

编程是一门艺术

docker实践入门之六

最后一篇来举个栗子。

样本项目

  1. 一个基于bottle的python web项目
  2. 依赖mako
  3. 暂时只考虑部署一个版本的例子

项目有以下内容:

+-appname.py
+-config.json
+-requirements.txt
+-views
  +-index.html

requirements.txt的内容为:

bottle
mako

virtualenv部署方式

传统的python应用部署方式一般会推荐用virtualenv,它可以实现一个相对隔离的python环境供应用运行,避免因为不同的应用有不同的依赖导致不必要的冲突。

首先你需要建立一个基础环境,包括:

  • OS
  • 安装apache/nginx等webserver并配置
  • 安装相应版本的python
  • 安装virtualenv
  • 创建应用专用的virtualenv环境

之后通过hg/git更新应用代码,再用pip和requirements.txt更新依赖,再用gunicorn/uwsgi等wsgi server来启动应用(必要时辅以supervisord进行管理)

一个简单的fabric部署脚本类似这样:

with settings(warn_only=True):
    out = local("ps ax | grep appname.py | awk '{ print $1; }'")
if out and len(out) > 0:
    local("kill {0}".format(out[0]))
local("hg pull")
local("hg update")
local("pip install -r requirements.txt")
local("/path_to_virtualenv/appenv/bin/python appname.py")

功能就是检查是否已经运行了应用,如果运行则kill之,更新代码后重新运行。

这里为简单起见,没有使用wsgi server和supervisord。

这个做法存在几个问题:

首先是你需要自己手工准备一个基础环境。其次是不方便部署到多台机器。

接下来看看docker是怎么做的。

docker的部署方式

首先是docker image的准备。基础环境可以直接用前一篇文章里那个python3环境的image例子用的Dockerfile,这里不再重复。

应用环境同样可以用那个例子,区别无非是加上代码更新,而这个更新可以在build之前就在host上运行一次hg pull/hg update更新好(或者直接使用jenkins这种自动化部署工具来更新并部署),之后再build。

所以,需要做的工作只是写一个部署脚本:

def deploy_app(appname, skipbuild=False):
    if not skip_build:
        with settings(warn_only=True):
            local("docker tag {appname} {appname}:old".format(appname=appname))
            local("docker rmi {appname}".format(appname=appname))
        local("docker build -t {appname} ..".format(appname=appname))
        out = local("docker ps -a", capture=True)
        pat = re.compile("([0-9a-f]{{12}})\s+{0}".format(appname))
        m = pat.findall(out)
        if len(m) > 0:
            local("docker rm -f {0}".format(m[0]))
        with settings(warn_only=True):
            local("docker rmi {0}:old".format(appname))
    out = local("ip route | awk '/docker0/ { print $NF }'", capture=True)
    host_ip = "--add-host=dockerhost:{0}".format(out)
    local("docker run -d -p 8080:8080 --name={appname} {host_ip} -v /var/www/log:/var/www/log {appname}".format(appname=appname, host_ip=host_ip))

这样只要运行:

fab deploy_app:appname=appname

如果不需要重新构建image,还可以这样直接启动container:

fab deploy_app:appname=appname,skipbuild=True

本文毕竟号称入门实践,到这里基本算是入完门了,剩下就看你自己的。

思考

如果要部署多个版本分别用于开发、测试、生产,每个版本有各自不同的配置文件的情况要如何做?

阅读更多
个人分类: 通用技术
想对作者说点什么? 我来说一句

Docker入门实践.pdf 最新版

2018年03月04日 6.47MB 下载

docker入门实践(中文版).pdf

2017年03月09日 5.44MB 下载

Docker 入门实践.pdf

2018年02月14日 6.73MB 下载

Docker入门实践》高清版

2017年11月08日 1.41MB 下载

docker入门实践(第二版).pdf

2018年03月13日 6.54MB 下载

docker入门实践

2018年06月14日 3.35MB 下载

Docker入门实践

2018年01月24日 1.78MB 下载

Docker入门实践

2018年06月07日 3.37MB 下载

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭