代码之家  ›  专栏  ›  技术社区  ›  EMP

一个简单的python部署问题-一个痛苦的世界

  •  21
  • EMP  · 技术社区  · 14 年前

    我们有几个python 2.6应用程序在Linux上运行。其中一些是挂架Web应用程序,另一些只是我们从命令行运行的长时间运行的进程,使用 nohup . 我们也在使用 virtualenv 在开发和生产中。 将这些应用程序部署到生产服务器的最佳方法是什么?

    在开发中,我们只需将源代码树放到任何目录中,设置一个virtualenv并运行起来就足够简单了。我们在生产中也可以这样做,也许这是最实际的解决方案,但运行起来有点错误。 svn update 在生产中。我们也尝试过 fab 但它从来没有第一次起作用。对于每个应用程序,都会出现其他问题。我突然想到整个过程 太难了 鉴于我们正在努力实现的基本上是非常简单的。这是我们在部署过程中需要的。

    1. 我们应该能跑 一个简单的命令 部署应用程序的更新版本。(如果最初的部署涉及到一些额外的复杂性,那就好了。)
    2. 当我们运行这个命令时,它应该将某些文件从Subversion存储库或本地工作副本复制到服务器上的指定“环境”,这可能意味着一个不同的virtualenv。我们在同一台服务器上同时拥有应用程序的临时版本和生产版本,因此它们需要以某种方式保持独立。如果它安装到站点包中,只要它正常工作,这也没问题。
    3. 我们在服务器上有一些应该保留的配置文件(即不被部署过程覆盖或删除)。
    4. 其中一些应用程序 从其他应用程序导入模块 ,所以他们需要能够以某种方式将彼此引用为包。这是我们遇到的最大麻烦!我不在乎它是通过相对的导入、站点包还是其他方式工作,只要它在开发和生产中都能可靠地工作。
    5. 理想情况下,部署过程应该自动安装应用程序所依赖的外部包(例如psycopg2)。

    就这样!有多困难?

    8 回复  |  直到 12 年前
        1
  •  23
  •   Marcelo Cantos    14 年前

    python代码的开发和部署通过 setuptools virtualenv pip .

    核心理念

    我发现,最棘手的部分是运行一个开发环境,尽可能地反映部署的设置,同时尊重pythonic工具和习惯用法。但事实证明,使用pip和setuptools很容易实现这一点,它们一起允许您在不移动文件的情况下将开发树“安装”到Python环境中。(实际上,SETUPTOOLS本身就可以做到这一点,但PIP更好地充当前端句柄依赖项。)

    另一个关键问题是在两个环境中准备一个具有已知包集的干净环境。在这方面,python的virtualenv是上帝派来的,它允许您使用自己选择的包来配置一个完全定制的python环境,而不需要根访问或操作系统包(rpm或dpkg),也不受安装在您的发行版上的任何包及其版本的约束。

    最后,一个令人讨厌的bug熊是很难创建命令行脚本,这些脚本可以很好地使用Python路径。安装工具也非常优雅地处理了这个问题。

    设置

    (为了简单起见,这是相当规范的。如有分歧,请自由选择。)

    1. 准备一个工作目录,您的python人员可以调用它。
    2. 从下面获取最新的virtualenv this page 把它解开(不管在哪里)。
    3. 从工作目录中,设置新的python虚拟环境:

      $ python <untarred_directory>/virtualenv.py venv
      
    4. 您将希望在这个虚拟环境中完成大部分工作。使用此命令执行此操作( . 是的快捷方式 source ):

      $ . venv/bin/activate
      
    5. 安装PIP:

      $ easy_install pip
      
    6. 为要创建的每个可安装包创建目录。

    7. 在每个目录中,都需要一个setup.py来定义包的内容和结构。StudioToo工具 documentation 是一个很好的资源,开始这方面的工作。值得花时间去吸收大块。

    发展

    一旦您的树结构准备好了,您就可以开始编码了。但是现在,相互依赖的包在部署的环境中看不到彼此。这个问题是通过安装工具提供的一个简单的小技巧来解决的,并且PIP利用了这个技巧。对于正在开发的每个包,运行以下命令(确保您处于项目的虚拟环境中,如上面的步骤3所示):

    $ pip install -e pkg1
    

    此命令将安装 pkg1 在您的虚拟环境中,它可以在不复制任何文件的情况下执行此操作。它只是在 site-packages 指向包的开发根目录并在该根目录中创建一个egg info目录。您也可以在没有PIP的情况下执行此操作,如下所示:

    $ cd pkg1
    $ python setup.py develop
    

    它通常可以工作,但是如果您有第三方依赖项(如说明所示,它应该列在setup.py中) here 在SETUPTOOLS文档中),PIP更聪明地找到它们。

    需要注意的一点是,无论是安装工具还是PIP,都不能在自己的包中找到依赖关系。如果目录B中的pkgb依赖目录A中的pkga,则 pip install -e B 将失败,因为PIP无法知道pkga可以在目录A中找到;相反,它将尝试并失败地从其在线存储库源下载pkga。解决方法只是在每个包依赖项之后安装它。

    此时,您可以启动python,加载其中一个模块并开始使用它。您可以编辑代码,下次导入时它将立即可用。

    最后,如果您想用您的包创建命令行工具。不要手写。最后你会遇到一堆糟糕的python-path黑客,它们从来都不能正常工作。只读 automatic script creation 在设置工具文档中。这会让你省去很多悲伤。

    部署

    当包准备好执行操作时,可以使用setup.py创建部署包。这里有太多的选项可供选择,但您应该先了解以下内容:

    $ cd pkg1
    $ python setup.py --help
    $ python setup.py --help-commands
    

    松端

    由于问题的广泛性,这个答案必然是不完整的。我没有处理长时间运行的服务器、Web框架或实际的部署过程本身(特别是使用pip安装 --index-url 管理第三方和内部包的私有存储库,以及 -e vcs+... 将从SVN、Git、Hg或BZR中提取包)。但我希望我已经给你足够的绳子把它们绑在一起(只是不要把自己挂在绳子上)。

        2
  •  6
  •   Shekhar    12 年前

    这真的不难。你主要需要和 buildout supervisord 国际海事组织

    虽然学习增强可能需要一点时间,但它是值得的,考虑到痛苦的数量,它减少了重复设置。

    关于NOHUP: nohup方法不适用于严重的部署。我在主管方面有很好的经验。它是运行生产python应用程序的优秀解决方案。它很容易设置。

    下面是一些具体的答案。

    1. 部署单个命令:构建是答案。我们用了几年,没什么问题
    2. 通常情况下,就像你签出源代码一样。然后运行构建。此外,让安装程序复制到站点包中可能不是一个好主意。最好把环境分开。
    3. 配置不会被覆盖。
    4. 您可以/应该考虑为普通包装制作鸡蛋。就像你可以为一个包构建一个鸡蛋(比如commonlib)并将其上传到你的代码存储库。然后您可以在buildout.cfg中将其指定为依赖项。
    5. 构建能够构建与中央/顶层安装完全分离的最基本的软件包。但是,根据我的经验,使用C扩展的python包如果安装为OS包,就容易得多。
        3
  •  5
  •   Rick    14 年前

    我一直在努力为我们的工作项目实现这一点。这涉及到几个不同的部分。

    首先,我们使用virtualenv.py的引导功能定制virtualenv.py,以添加您自己的自定义post创建函数和标志。这些允许我们定义常见的项目类型,并给我们一个命令来创建一个新的virtualenv,从git存储库签出一个项目,并使用pip和requirements.txt将任何需求安装到virtualenv中。 文件夹。

    所以我们的命令如下: python venv.py--无站点包-g$git_proj-t$tag_num$venv_dir

    http://pypi.python.org/pypi/virtualenv http://pip.openplans.org/

    现在,我们通过了对现有项目的初始检查。在我们工作和更新项目时,我们在每个项目中使用fabric命令来构建版本,然后部署它们:

    http://docs.fabfile.org/0.9.0/

    我有一个fab命令:make_标记,用于检查未使用的提交,打开需要更新版本字符串的文件,构建和上载sphinx文档,然后将最终标记提交到存储库。

    另一方面是fab deploy命令,它将通过ssh执行指定标记的git co,对任何新需求运行pip更新,运行所需的任何数据库迁移,然后在这是Web应用程序时重置Web服务器。

    以下是标记功能的示例: http://www.google.com/codesearch/p?hl=en#9tLIXCbI4vU/fabfile.py&q=fabfile.py%20git%20tag_new_version&sa=N&cd=1&ct=rc&l=143

    使用谷歌代码搜索,你可以浏览大量优秀的结构文件。我知道我骗了几张供自己使用。

    为了让事情顺利进行,它肯定很复杂,有几个部分。一旦你让它运转起来,它的灵活性和速度是非常棒的。

        4
  •  2
  •   Oddthinking    14 年前

    看一看 Buildout 用于可复制的部署。

        5
  •  0
  •   Chris Reid    14 年前

    另一个对织物的投票(还没有尝试扩建)。我们已经成功使用它几个月了。

    如果织物有问题,另一个选择是 Capistrano . 效果很好(即使对于非Rails应用程序也是如此)。只是因为使用Ruby部署python应用程序感觉很奇怪而停止使用它;)

        6
  •  0
  •   Warren P    14 年前

    我将使用rsync从生产“prime”服务器向外同步到其他服务器,从“beta测试”平台向外同步到生产“prime”服务器。

    rsync的好处是只复制那些更改过的文件,只复制部分更改过的文件的一部分,并在所有计算机上最后验证完整性和相同的内容。稍后可以轻松地继续一个部分完成并中断的更新,从而使部署更加健壮。

    在这种情况下,颠覆或反复无常也不是一个坏主意。Mercurial拥有 允许您“拉”或“推”的优势,而不仅仅是从一个中心源进行更新。您可能会发现一些有趣的案例,其中分散模型(mercurial)工作得更好。

        7
  •  0
  •   chiggsy    14 年前

    如果你是一个建筑工人,那么你应该知道 minitage.recipe.scripts 能够生成一个文件来设置您的Python环境。源到您的Web服务器和您的构建是完全可移植的。

        8
  •  0
  •   fijiaaron    12 年前

    听起来你想要的是一个构建脚本。因此,使用shell、python、ant或您最喜欢的构建工具编写一个。如果您不喜欢用XML编写, pant 允许您用Python编写Ant脚本。有几个人提到 buildout 但我对此没有任何经验。

    首先定义你的步骤。听起来你想:

    1. 从生产标签导出SVN(您不希望在Prod中有工作副本)
    2. 设置虚拟机
    3. 轻松安装或PIP安装所需的软件包(或可能使用预下载和测试版本)
    4. 将生产配置文件复制到您的目标(在源repo中保留这些信息不是一个好主意——尽管您可以单独对它们进行版本控制)
    5. 重新启动服务器并执行任何其他安装任务
    6. 运行冒烟测试并在失败时回滚

    如果您正在进行负载平衡或依赖于其他服务生产,那么您可能希望找到一种方法来扩展有限的范围,这样您的所有客户就不会同时受到影响。如果您有一个类似生产的登台环境,那么它也可以满足您的需求。