Django的结构部署

django-fabdeploy-plus的Python项目详细描述


快速启动

有完整的工作示例: https://github.com/vmihailenco/fabdeploy-example

创建fabconf.py:

from fabdeploy.api import DefaultConf

class BaseConf(DefaultConf):
    django_dir = 'project_name'

class StagingConf(BaseConf):
    address = 'user@staging-host.com'

class ProdConf(BaseConf):
    address = 'user@prod-host.com'

创建fabfile.py:

from fabdeploy import monkey; monkey.patch_all()
from fabric.api import *
from fabdeploy.api import *; setup_fabdeploy()


@task
def user_create():
    users.create.run()
    ssh.push_key.run(pub_key_file='~/.ssh/id_rsa.pub')

@task
def deploy():
    pass

FabDeploy使用两个系统(Linux)用户:

  • sudo_user执行需要sudo权限的任务(默认情况下,root)。
  • user用于其他任务(默认为ssh用户)。

在ubuntu中,rootuser在默认情况下被禁用。你可以创造特别的 fabdeploy使用以下命令的用户:

fab fabd.default_conf:address=user@host,sudo_user=user fabd.create_user

那么您应该告诉fabdeploy使用新的sudo_user

class ProdConf(BaseConf):
    sudo_user = 'fabdeploy'

可用任务列表:

fab --list

可用变量列表:

fab fabd.debug

这对于测试配置很有用:

$ fab fabd.conf:prod fabd.debug:django_path
/home/prj/src/prj

或:

$ fab fabd.conf:prod fabd.debug:cpu_count
2

或:

$ fab fabd.conf:prod fabd.debug:current_time
2011.11.27-13.40

要部署项目,您可以使用:

$ fab fabd.conf:staging deploy
$ fab fabd.conf:prod deploy

示例

控制日志的存储位置

fabconf.py:

from fabdeploy.api import DefaultConf

class ProdConf(DefaultConf):
    my_task__log_path = '/var/log/my_task'

fabfile.py:

from fabdeploy.api import Task

class MyTask(Task):
    def do(self):
        print self.conf.log_path

my_task = MyTask()

输出:

$ fab fabd.conf:prod my_task
/var/log/my_task

您还可以临时设置日志路径:

$ fab fabd.conf:prod my_task:log_path='/var'
/var

这适用于所有变量和所有任务。

多个数据库

fabconf.py:

from fabdeploy.api import DefaultConf

class ProdConf(DefaultConf):
    # default DB
    db_name = 'name1'
    db_user = 'user1'
    db_password = 'pass1'
    # logging DB
    loggingdb__db_name = 'name2'
    loggingdb__db_user = 'user2'
    loggingdb__db_password = 'pass2'

fabfile.py:

from fabdeploy import postgres

@task
def dump_db():
    postgres.dump.run()  # dump default DB
    postgres.dump.run(_namespace='loggingdb__')  # dump logging DB

内置任务定制

fabdeploy被编写为高度可配置的。例如,有 内置的tartask,它默认打包整个项目,然后上传 服务器并在那里解包。

但您可以自由使用它上载自定义目录:

from fabdeploy import tar

@task
def push_static():
    tar.push.run(
        src_dir=os.path.join(env.conf.django_ldir, 'static'),
        target_dir=posixpath.join(env.conf.django_dir, 'static'))

用于开发和生产的不同数据库

fabconf.py:

from fabdeploy import api
from fabdeploy.api import DefaultConf

class DevConf(DefaultConf):
    address = 'user@localhost'
    db = getattr(fabdeploy, 'mysql')

class ProdConf(DefaultConf):
    address = 'user@localhost'
    db = getattr(fabdeploy, 'postgres')

fabfile.py:

@task
def execute():
    print env.conf.db.execute

配置

如何配置fabdeploy有一些约定:

  • 您应该扩展defaultconf:

    from fabdeploy.api import DefaultConf
    
    class BaseConf(DefaultConf):
        pass
    
  • 每个值都可以包含python格式:

    class BaseConf(DefaultConf):
        supervisor__log_dir = '%(var_dir)s/log/supervisor'
    
  • 远程路径应该有posfix_path。你可以也应该使用 任务fabd.mkdirs使用一个命令创建所有远程目录。它 会像这样:

    $ fab fabd.conf:staging_conf fabd.mkdirs
    mkdir --parents /path/to/dir1 /path/to/dir2 /path/to/dir3
    
  • 远程目录(例如var)具有后缀_dir

  • 本地路径具有后缀_lpath。本地dirs有后缀 _ldir。这类似于fabriccdlcd任务。

  • 目录(postfix_dir_ldir)和路径(postfix^{tt8})$ 并且_lpath)可以是python列表。这些列表将传递给 os.path.join()posixpath.join()。前面的示例可以 如下所示:

    from fabdeploy.api import DefaultConf
    
    class BaseConf(DefaultConf):
        supervisor__log_dir = ['%(var_dir)s', 'log', 'supervisor']
    
  • 函数可以用conf decorator修饰。例如, current_time任务如下:

    from fabdeploy.api import DefaultConf
    
    class BaseConf(DefaultConf):
        @conf
        def current_time(self):
            return datetime.datetime.utcnow().strftime(self.time_format)
    

    您可以像这样在任务中使用它:

    from fabdeploy.api import Task
    
    class MyTask(Task):
        def do(self):
            puts(self.conf.current_time)
    
  • 您可以单独配置每个任务:

    class BaseConf(DefaultConf):
        postgres__db_name = 'postgresql_db'  # module=postres
        mysql__db_name = 'mysql_db'          # module=mysql
        mysql__create_db__db_user = 'root'   # module=mysql, task=create_db
    

配置存储在任务实例变量self.conf中。每个 任务有自己的配置副本。配置变量是 在以下位置搜索:

  • 任务关键字参数varfab task:foo=bar);
  • 任务实例方法var()@conf()
  • 修饰
  • env.conf中输入var,由fabd.conftask填充;
  • 要求用户使用fabric prompt提供变量var

全局配置存储在env.conf中。

编写任务

您的任务是基于类的fabric类,fabdeploy管理除外 您的配置:

from fabric.api import puts
from fabdeploy.api import Task, conf

class MessagePrinter(Task):
    @conf
    def message(self):
        if 'message' in self.conf:
            return self.conf.message
        return 'Hi!'

    def do(self):
        if self.conf.secret == '123':
            puts(self.conf.message)
        else:
            puts('huh?')

message_printer = MessagePrinter()

然后您可以这样运行此任务:

$ fab message_printer
> secret = 123
Hi!
$ fab message_printer:message='Hello world!'
> secret = 123
Hello world!

fabfile示例

典型的fabfile可能如下:

from fabdeploy import monkey; monkey.patch_all()
from fabric.api import *
from fabdeploy.api import *; setup_fabdeploy()

@task
def install():
    users.create.run()
    ssh.push_key.run(pub_key_file='~/.ssh/id_rsa.pub')

    system.setup_backports.run()
    system.install_common_software.run()

    with settings(warn_only=True):
        postgres.create_role.run()
        postgres.create_db.run()
        postgres.grant.run()

    nginx.install.run()

    for app in ['supervisor']:
        pip.install.run(app=app)


@task
def setup():
    fabd.mkdirs.run()

    nginx.push_gunicorn_config.run()
    nginx.restart.run()

    supervisor.d()


@task
def deploy():
    fabd.mkdirs.run()
    release.create.run()

    postgres.dump.run()

    git.init.run()
    git.push.run()

    supervisor.push_configs.run()
    django.push_settings.run()
    gunicorn.push_config.run()

    virtualenv.create.run()
    virtualenv.pip_install_req.run()
    virtualenv.pip_install.run(app='gunicorn')
    virtualenv.make_relocatable.run()

    django.syncdb.run()
    django.migrate.run()
    django.collectstatic.run()

    release.activate.run()

    supervisor.update.run()
    supervisor.restart_program.run(program='celeryd')
    gunicorn.reload_with_supervisor.run()

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java如何在sqlite数据库中保存特定列的历史记录   java如何更改/更新timeseriechart名称(JFreeChart)   java如何将整数转换为可绘制的   汇编什么解释Java的字节码   java查找已编译的类版本号   我应该什么时候在ColdFusion应用程序中使用Java?   java当一个实体的两个字段为(unique=true)时,如何处理JPA异常?   java为什么在所有其他实例都正确的情况下返回错误的布尔值?   java Hibernate每次都准备语句   java停留在平均字长上   对Java和日语字符进行编码   java如何将导致异常的方法的错误消息传递给侦听器中的onTestFailure方法   java代码没有打印结果   java为什么私有内部接口的方法必须是公共的?   休眠发生错误。有关详细信息,请参阅错误日志。JAVAlang.NullPointerException