在Nylas,咱们喜欢使用Python进行开发。它的语法简单并富有表现力,拥有大量可用的开源模块和框架,并且这个社区既受欢迎又有多样性。咱们的后台是纯用 Python 写的,团队也常常在 PyCon 和 meetups 上演讲。你能够认为咱们是 Python 的超级粉。python
然而,Python 的一个大缺陷是没有一个明确的工具来部署 Python 服务端应用。工做的状况就像是“执行 git 的 pull 命令后剩下的就只有祈祷了”,但这并非一个好的方式,尤为当用户依赖于咱们的应用。当你的应用引用了不少仍在变化的依赖时,这会让 Python 的部署工做变得更加复杂。下面 HN 上的评论归纳了 Python 部署的糟糕状况。git
为何这么多年了,仍没有一个有效的办法帮我将 Python 编写的软件转换成 deb 格式?github
—— 来自一个受挫的 HN 用户web
在 Nylas,咱们开发了一种更好的方法能够将 Python 代码连同其依赖一块儿部署,使得咱们可以轻松地对轻量级包进行安装、升级或者删除。该方式的实现并不须要将咱们的整个栈迁移到像 Docker、 CoreOS 或者AMIs 这样的系统上。docker
Python 提供了丰富的模块。无论你搭建的是一个web 服务器仍是机器学习分类器,总会有一个合适的模块帮你启动项目。如今获取这些模块的标准方法是经过 pip 从 Python 包索引 (亦称 PyPI)中下载和安装。这就跟 apt,yum,rubgem 等命令操做是同样。缓存
大多数人搭建开发环境的第一步就是用 git 克隆份代码,而后经过 pip 安装其依赖。这也是大多数人第一次尝试部署代码的作法。部署脚本大体以下:安全
1
2
3
4
|
git clone https://github.com/company/somerepo.git
cd /opt/myproject
pip install -r requirements.txt
python start_server.py
|
可是当部署大量生产服务时,这种策略有下面几个缘由可能致使失败:服务器
PIP 并无提供“部署回滚”策略网络
pip unistall
并非每次都能正常工做,也没有办法“回滚”到上一个状态。虽然能够用Virtualenv 实现,但它并非用来管理历史环境的。架构
用 pip 安装依赖会让部署变得极其慢
使用pip install 来安装一个由C语言编写的模块常常须要从源码进行编译,对于一个新创建的virtualenv环境,这将花费几分钟的时间。但部署应用应该是一个以秒计算的快速而轻量的过程。
在每台主机上分别构建代码会有一致性问题
当你使用 pip 部署时,没法保证不一样服务器上运行的应用版本是一致的。构建过程或现有依赖中的错误致使的不一致,这是很难去调试的。
若是 PyPI 或者你的 git 服务器挂掉会致使部署失败
pip install
和 git pull
一般依赖于外部服务器。你能够选择使用第三方平台 (如 Github,PyPI)或者本身搭建服务器,重要的是确保部署过程知足正常运行时间和规模的预期。当扩展本身的基础设施,尤为是在大型部署时,外部服务每每是第一个挂掉的。
若是你在运营一我的们依赖的应用系统,并且它又是部署在多个服务器上,那么采用 git + pip 部署策略只会让你更加头痛。咱们须要的部署策略应该是快速的、一致并且可靠的。更具体地说:
有了这三样东西可让咱们将更多的时间花在功能的构建上,以更少的时间进行代码一致性迁移。
初看下,这彷佛最适合用 Docker 了,Docker 是当前盛行的容器管理工具。在一个 Dockerfile里,只要简单地添加代码仓库的引用,安装必要的库和依赖。那么咱们就建好 Docker 镜像,将它做为受版本控制的工件发往到远程主机。
然而,当咱们尝试这样操做时遇到了几个问题:
即使咱们顺利的解决了这些问题,为了调试生产上的问题,咱们的工程师团队又不得不学习如何跟 Docker 链接交互。咱们认为更快地迁移代码并不该该从新执行整个基础架构自动化和编排层。因此咱们继续调查其余方案。
PEX 是 Twitter 开发的一个智能工具,它容许 Python 代码以可执行压缩文件进行传送。这是一个很酷的想法,关于这个主题咱们建议去看Brian Wickman 在推特大学的演讲。
设置 PEX 比 Docker 还简单,由于他只须要运行生成好的可执行压缩文件,可是构建 PEX 文件倒是一项巨大的工程。咱们在构建第三方库需求时遇到问题,特别是当中包含了静态文件。咱们也遭遇到 PEX 源代码产生的混乱的堆栈跟踪,使得调试工做变得更加困难。这是个异份子,由于咱们主要目标是改善工程效率,让事情更加易懂。
使用 Docker 会增长运行时的复杂度。而 PEX 会增长构建时的复杂度。咱们须要一个方案能够最小化总体复杂度,同时提供可靠的部署,因此咱们继续调查其余方案。
几年前,Spotify 悄悄发布了一个工具叫 dh-virtualenv,你能够用来构建内含 virtualenv 的 debian 包。咱们以为这颇有意思,也已经有了不少 Debian 相关经验并在生产环境上运行。(Christine,咱们的联合创始人之一,就是一个 Debian 的开发者。)
用dh-virtualenv
能够很简单的建立一个 debian 包,它包含了 virtualenv 和罗列在requirement.txt 文件里的全部依赖。当在主机上安装这个 debian 包时, 它会将 virtualenv 放置在/usr/share/pyton/
路径下。就是它了。
这就是咱们在 Nylas 上部署代码的关键。咱们的持续集成服务器 (Jenkins) 运行 dh-virtualenv 来构建包, 用 Python 的wheel 缓存来避免对依赖从新构建。这就建立一个捆绑式工件(debian 包),而后对其进行大量的单元测试和系统测试。若是经过测试,则可认为生产上是安全的,能够上传到 s3.
这个过程的关键部分是经过均衡 Debian 的内置包管理器 dpkg,咱们能够最小化部署脚本的复杂度。部署脚本大体以下:
1
2
3
4
|
temp=$(mktemp /tmp/deploy.deb.XXXXX)
curl “https://artifacts.nylas.net/sync-engine-3k48dls.deb” -o $temp
dpkg -i $temp
sv reload sync-engine
|
要回滚的话,咱们只须要部署上一版本的工件。dpkg 工具能够免费帮你清除旧代码。
这个策略最重要的一方面是它实现了一致性和可靠性,同时匹配了咱们的开发环境。咱们的工程师已经在用virtualenv,而dh-virtualenv 只是一个将其迁往远程主机的方式。若是咱们选择 Docker 或者 PEX,明显须要改变咱们本地开发的方式又增长了复杂度。咱们一样不但愿给使用咱们开源代码的开发者带来复杂度负担。
如今,咱们用 Debian 包来迁移咱们全部的 Python 代码。完整构建咱们代码库(包含数十个依赖)只要不到2分钟时间,部署更是数秒便完成。
若是你受够了 Python 部署的折磨,那就试试 dh-virtualenv吧。它会是你不错的选择!
配置 Debian 包对于初学者而言是棘手的,因此咱们构建了 make-deb 工具来帮你入手。它会基于你 Python 项目里的 setup.py 文件生成 Debian 配置。
首先安装make-deb
工具,而后在你项目的根目录下运行它:
1
2
3
|
cd /my/project
pip install make-deb
make-deb
|
若是你的 setup.py 文件有缺失信息的话,make-deb
会要求你添加。一旦它收齐所需的信息,make-deb
会在你项目的根目录下建立一个 debian 目录,包含了 dh-virtualenv 须要的全部配置。
构建 Debian 包须要你在装有 dh-virtualenv 的 Debian 系统上进行。若是你没有 Debian 环境,咱们建议你在 Mac 或者 Windows 上用 Vagrant 和 Virtualbox 安装一个 Debian 的虚拟机。你也能够参考咱们放在 Git 仓库下 sync-engine 项目里的Vagrantfile 来做配置。
最后,运行dpkg-builpackage -us -uc
来建立 Debian 包。你不须要直接调用 dh-virtualenv,由于它已经在以前make-deb
建立好的配置规则里了。当这条命令执行好后,你就构建好一个可部署的漂亮的工件。
一段简单的部署脚本以下:
1
2
3
4
5
6
7
8
|
scp my-package.deb remote-host.example.org:
ssh remote-host.example.org
# Run the next commands on remote-host.example.org
dpkg -i my-package.deb
/usr/share/python/myproject/bin/python
>>> import myproject # it works!
|
部署时,你须要将这个工件上传到生产服务器上。运行dpkg -i my-package.deb
命令来安装。virtualenv 会被放在/usr/share/python/
目录下,全部预设在 setup.py 文件里的脚本文件则会在bin
目录里。就是它了!你这就走上了简易部署的光明大道。
在构建大型系统时,项目难点每每是在寻求合适的工具,而非从头开始重构一个新的系统。咱们认为使用 Debian 基于包的部署是部署 Python 应用的一个极佳方案,最重要的是它能够帮咱们平稳而快速的迁移代码。
声明:
本文转载自:http://python.jobbole.com/85057/