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。这类似于fabriccd和lcd任务。
目录(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中。每个 任务有自己的配置副本。配置变量是 在以下位置搜索:
- 任务关键字参数var(fab 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()