使用结构部署

Fabric是类似于Makefiles的Python工具,但能够在远程服务器上执行命令。结合正确设置的Python包(Larger Applications)和一个好的配置概念(Configuration Handling),很容易将Flask应用程序部署到外部服务器。

在我们开始之前,这里有一个快速检查清单,我们必须确保预先:

  • 在本地已经安装了 Fabric 1.0 。 即这个教程完成时, Fabric 的最新版本。
  • 应用程序必须是一个包,并且需要一个工作的setup.py文件(Deploying with Setuptools)。
  • 在下文中的例子里,我们使用 mod_wsgi 作为远程服务器使用的服务端程序。 您当然也可以使用您喜欢的服务端程序,但是考虑到 Apache 和 mod_wsgi 的 组合非常简单易用且容易安装配置,并且在无 root 权限的情况下,存在一个比较 简单的方法来重启服务器。

创建第一个Fabfile

在本文中 我们将他们定义在 fabfile 里。 它命名为fabfile.py,由fab命令执行。 文件中所有的函数将被当做 fab 的子命令显示出来,他们可以在一个或 多个主机上运行。 它们在一个或多个主机上执行。 这些主机要么在 fabfile 当中定义,要么在命令输入时指定。 在这种情况下,我们将它们添加到fabfile。

这是第一个基础的例子,能够将现有源代码上传到指定服务器并将它们安装进如 一个已经存在的虚拟环境中:

from fabric.api import *

# the user to use for the remote commands
env.user = 'appuser'
# the servers where the commands are executed
env.hosts = ['server1.example.com', 'server2.example.com']

def pack():
    # build the package
    local('python setup.py sdist --formats=gztar', capture=False)

def deploy():
    # figure out the package name and version
    dist = local('python setup.py --fullname', capture=True).strip()
    filename = '%s.tar.gz' % dist

    # upload the package to the temporary folder on the server
    put('dist/%s' % filename, '/tmp/%s' % filename)

    # install the package in the application's virtualenv with pip
    run('/var/www/yourapplication/env/bin/pip install /tmp/%s' % filename)

    # remove the uploaded package
    run('rm -r /tmp/%s' % filename)

    # touch the .wsgi file to trigger a reload in mod_wsgi
    run('touch /var/www/yourapplication.wsgi')

运行Fabfiles

如何执行 fabfile 呢? 您应该使用 fab 命令。 若要发布当前版本的代码到远程 服务器上,您只需执行如下命令:

$ fab pack deploy

但这需要我们的服务器已经创建了/var/www/yourapplication文件夹,并且/var/www/yourapplication/env为虚拟环境。此外,我们不在服务器上创建配置或.wsgi文件。 因此,我们怎么样 把一个新的服务器转换为可以使用基础设备呢。

这视我们想要配置的服务器数量的不同,实现起来有所差别。 如果我们只有一个 远程应用服务器(大部分应用都是都属于此类),那么 fabfile 里添加一个专门 负责此类的命令有些小题大做。 但是显然我们可以这么做。 在这种情况下,您可能会将其命名为setupbootstrap,然后在命令行中明确传递servername:

$ fab -H newserver.example.com bootstrap

初始化一个新的服务器,您大概需要执行如下几个步骤:

  1. /var/www中创建目录结构:

    $ mkdir /var/www/yourapplication
    $ cd /var/www/yourapplication
    $ virtualenv --distribute env
    
  2. 将新的application.wsgi文件上传到服务器和应用程序的配置文件(例如:application.cfg

  3. yourapplication创建一个新的Apache配置并激活它。请务必激活监视.wsgi文件的更改,以便我们可以通过触摸来自动重新加载应用程序。(有关详细信息,请参阅mod_wsgi (Apache)

所以现在的问题是,application.wsgiapplication.cfg文件来自哪里?

WSGI文件

WSGI 文件应导入这个应用并且设定一个环境变量,这个环境变量指定了应用程序应 到哪里寻找配置文件。 这是一个简短的例子,正是这样:

import os
os.environ['YOURAPPLICATION_CONFIG'] = '/var/www/yourapplication/application.cfg'
from yourapplication import app

应用程序本身则应该向下面这样,通过查询环境变量来查找配置,以此初始化自己:

app = Flask(__name__)
app.config.from_object('yourapplication.default_config')
app.config.from_envvar('YOURAPPLICATION_CONFIG')

这种方法在本文档的 配置处理 这节中进行了详细介绍。

配置文件

现在如上所述,应用程序将通过查找YOURAPPLICATION_CONFIG环境变量找到正确的配置文件。 因此我们必须将配置文件放在应用程序可以找到的地方。 配置文件有在不同电脑上表现出不同效果的特质,所以您不应该以普通的方式 对它进行版本控制。

一个流行的做法是将不同服务器的配置文件保存在不同的版本控制仓库里,然后 在不同的服务器中分别抽取出来。 然后将对服务器有效的文件符号链接到预期的位置(例如:/var/www/yourapplication)。

我们预计只有一个或两个服务器需要部署,因此我们采用另一种方法,也就是 提前手动将配置文件上传到需要的未知。

第一部署

现在我们可以开始进行第一次部署了。 我们已经初始化了服务器以使它拥有正确的 虚拟环境和已经激活的 Apache 配置文件。 现在我们可以把应用打包然后部署了:

$ fab pack deploy

Fabric 现在就会连接到所有服务器,然后运行在 fabfile 文件中所指定的命令。 最初他会执行打包工作,为我们创建代码归档,然后他部署和上传代码到所有的 服务器,并在那里安装他们。 由于setup.py文件,我们将自动将所需的库放入我们的虚拟环境中。

后续步骤

从那时起,有这么多的可以做,使部署实际上很有趣:

  • 创建一个 bootstrap 命令用于初始化新的服务器,它将初始化一个新的虚拟环境 安装以及适当配置 Apache 等。 它可以初始化一个新的虚拟环境,适当地设置apache等。
  • 将配置文件放置到一个独立的版本控制仓库里,然后将活动的配置符号连接到 它应该在的地方。
  • 您应该将您的应用程序也放置到一个版本控制仓库中,然后在服务器中提取 最新的版本并安装,您也可以很容易的回溯到以前的版本。 这样你也可以很容易地回到旧版本。
  • 为测试提供函数接口,这样您就可以将测试代码部署到服务器上并在服务器端 执行测试套件。

使用 Fabric 是相当有趣,键入 fab deploy 并看到您的应用自动 部署到一个或多个服务器上,您会有“简直像是魔术”这样的感觉。