docker实践入门之六

    xiaoxiao2025-01-20  10

    最后一篇来举个栗子。

    样本项目

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

    项目有以下内容:

    +-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

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

    思考

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

    转载请注明原文地址: https://ju.6miu.com/read-1295679.html
    最新回复(0)