Guest User

Untitled

a guest
May 23rd, 2018
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.01 KB | None | 0 0
  1. """
  2.  
  3. This fabric file makes setting up and deploying a django application much
  4. easier, but it does make a few assumptions. Namely that you're using Git,
  5. Apache and mod_wsgi and your using Debian or Ubuntu. Also you should have
  6. Django installed on your local machine and SSH installed on both the local
  7. machine and any servers you want to deploy to.
  8.  
  9. _note that I've used the name project_name throughout this example. Replace
  10. this with whatever your project is called._
  11.  
  12. First step is to create your project locally:
  13.  
  14. mkdir project_name
  15. cd project_name
  16. django-admin.py startproject project_name
  17.  
  18. Now add a requirements file so pip knows to install Django. You'll probably
  19. add other required modules in here later. Creat a file called requirements.txt
  20. and save it at the top level with the following contents:
  21.  
  22. Django
  23.  
  24. Then save this fabfile.py file in the top level directory which should give you:
  25.  
  26. project_name
  27. fabfile.py
  28. requirements.txt
  29. project_name
  30. __init__.py
  31. manage.py
  32. settings.py
  33. urls.py
  34.  
  35. You'll need a WSGI file called project_name.wsgi, where project_name
  36. is the name you gave to your django project. It will probably look
  37. like the following, depending on your specific paths and the location
  38. of your settings module
  39.  
  40. import os
  41. import sys
  42.  
  43. # put the Django project on sys.path
  44. sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "../")))
  45.  
  46. os.environ["DJANGO_SETTINGS_MODULE"] = "project_name.settings"
  47.  
  48. from django.core.handlers.wsgi import WSGIHandler
  49. application = WSGIHandler()
  50.  
  51. Last but not least you'll want a virtualhost file for apache which looks
  52. something like the following. Save this as project_name in the inner directory.
  53. You'll want to change /path/to/project_name/ to the location on the remote
  54. server you intent to deploy to.
  55.  
  56. <VirtualHost *:80>
  57. WSGIDaemonProcess project_name-production user=project_name group=project_name threads=10 python-path=/path/to/project_name/lib/python2.6/site-packages
  58. WSGIProcessGroup project_name-production
  59.  
  60. WSGIScriptAlias / /path/to/project_name/releases/current/project_name/project_name.wsgi
  61. <Directory /path/to/project_name/releases/current/project_name>
  62. Order deny,allow
  63. Allow from all
  64. </Directory>
  65.  
  66. ErrorLog /var/log/apache2/error.log
  67. LogLevel warn
  68.  
  69. CustomLog /var/log/apache2/access.log combined
  70. </VirtualHost>
  71.  
  72. Now create a file called .gitignore, containing the following. This
  73. prevents the compiled python code being included in the repository and
  74. the archive we use for deployment.
  75.  
  76. *.pyc
  77.  
  78. You should now be ready to initialise a git repository in the top
  79. level project_name directory.
  80.  
  81. git init
  82. git add .gitignore project_name
  83. git commit -m "Initial commit"
  84.  
  85. All of that should leave you with
  86.  
  87. project_name
  88. .git
  89. .gitignore
  90. requirements.txt
  91. fabfile.py
  92. project_name
  93. __init__.py
  94. project_name
  95. project_name.wsgi
  96. manage.py
  97. settings.py
  98. urls.py
  99.  
  100. In reality you might prefer to keep your wsgi files and virtual host files
  101. elsewhere. The fabfile has a variable (config.virtualhost_path) for this case.
  102. You'll also want to set the hosts that you intend to deploy to (config.hosts)
  103. as well as the user (config.user).
  104.  
  105. The first task we're interested in is called setup. It installs all the
  106. required software on the remote machine, then deploys your code and restarts
  107. the webserver.
  108.  
  109. fab local setup
  110.  
  111. After you've made a few changes and commit them to the master Git branch you
  112. can run to deply the changes.
  113.  
  114. fab local deploy
  115.  
  116. If something is wrong then you can rollback to the previous version.
  117.  
  118. fab local rollback
  119.  
  120. Note that this only allows you to rollback to the release immediately before
  121. the latest one. If you want to pick a arbitrary release then you can use the
  122. following, where 20090727170527 is a timestamp for an existing release.
  123.  
  124. fab local deploy_version:20090727170527
  125.  
  126. If you want to ensure your tests run before you make a deployment then you can
  127. do the following.
  128.  
  129. fab local test deploy
  130.  
  131. """
  132.  
  133. # globals
  134.  
  135. config.project_name = 'project_name'
  136.  
  137. # environments
  138.  
  139. def local():
  140. "Use the local virtual server"
  141. config.hosts = ['127.0.0.1']
  142. config.path = '/path/to/project_name'
  143. config.user = 'garethr'
  144. config.virtualhost_path = "/"
  145.  
  146. # tasks
  147.  
  148. def test():
  149. "Run the test suite and bail out if it fails"
  150. local("cd $(project_name); python manage.py test", fail="abort")
  151.  
  152. def setup():
  153. """
  154. Setup a fresh virtualenv as well as a few useful directories, then run
  155. a full deployment
  156. """
  157. require('hosts', provided_by=[local])
  158. require('path')
  159.  
  160. sudo('aptitude install -y python-setuptools')
  161. sudo('easy_install pip')
  162. sudo('pip install virtualenv')
  163. sudo('aptitude install -y apache2')
  164. sudo('aptitude install -y libapache2-mod-wsgi')
  165. # we want rid of the defult apache config
  166. sudo('cd /etc/apache2/sites-available/; a2dissite default;')
  167. run('mkdir -p $(path); cd $(path); virtualenv .;')
  168. run('cd $(path); mkdir releases; mkdir shared; mkdir packages;', fail='ignore')
  169. deploy()
  170.  
  171. def deploy():
  172. """
  173. Deploy the latest version of the site to the servers, install any
  174. required third party modules, install the virtual host and
  175. then restart the webserver
  176. """
  177. require('hosts', provided_by=[local])
  178. require('path')
  179.  
  180. import time
  181. config.release = time.strftime('%Y%m%d%H%M%S')
  182.  
  183. upload_tar_from_git()
  184. install_requirements()
  185. install_site()
  186. symlink_current_release()
  187. migrate()
  188. restart_webserver()
  189.  
  190. def deploy_version(version):
  191. "Specify a specific version to be made live"
  192. require('hosts', provided_by=[local])
  193. require('path')
  194.  
  195. config.version = version
  196. run('cd $(path); rm releases/previous; mv releases/current releases/previous;')
  197. run('cd $(path); ln -s $(version) releases/current')
  198. restart_webserver()
  199.  
  200. def rollback():
  201. """
  202. Limited rollback capability. Simple loads the previously current
  203. version of the code. Rolling back again will swap between the two.
  204. """
  205. require('hosts', provided_by=[local])
  206. require('path')
  207.  
  208. run('cd $(path); mv releases/current releases/_previous;')
  209. run('cd $(path); mv releases/previous releases/current;')
  210. run('cd $(path); mv releases/_previous releases/previous;')
  211. restart_webserver()
  212.  
  213. # Helpers. These are called by other functions rather than directly
  214.  
  215. def upload_tar_from_git():
  216. require('release', provided_by=[deploy, setup])
  217. "Create an archive from the current Git master branch and upload it"
  218. local('git archive --format=tar master | gzip > $(release).tar.gz')
  219. run('mkdir $(path)/releases/$(release)')
  220. put('$(release).tar.gz', '$(path)/packages/')
  221. run('cd $(path)/releases/$(release) && tar zxf ../../packages/$(release).tar.gz')
  222. local('rm $(release).tar.gz')
  223.  
  224. def install_site():
  225. "Add the virtualhost file to apache"
  226. require('release', provided_by=[deploy, setup])
  227. sudo('cd $(path)/releases/$(release); cp $(project_name)$(virtualhost_path)$(project_name) /etc/apache2/sites-available/')
  228. sudo('cd /etc/apache2/sites-available/; a2ensite $(project_name)')
  229.  
  230. def install_requirements():
  231. "Install the required packages from the requirements file using pip"
  232. require('release', provided_by=[deploy, setup])
  233. run('cd $(path); pip install -E . -r ./releases/$(release)/requirements.txt')
  234.  
  235. def symlink_current_release():
  236. "Symlink our current release"
  237. require('release', provided_by=[deploy, setup])
  238. run('cd $(path); rm releases/previous; mv releases/current releases/previous;', fail='ignore')
  239. run('cd $(path); ln -s $(release) releases/current')
  240.  
  241. def migrate():
  242. "Update the database"
  243. require('project_name')
  244. run('cd $(path)/releases/current/$(project_name); ../../../bin/python manage.py syncdb --noinput')
  245.  
  246. def restart_webserver():
  247. "Restart the web server"
  248. sudo('/etc/init.d/apache2 restart')
Add Comment
Please, Sign In to add comment