django-recipes 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -0
- data/Rakefile +16 -0
- data/VERSION +1 -0
- data/lib/django-recipes.rb +4 -0
- data/lib/helpers.rb +17 -0
- data/lib/recipes/deploy.rb +92 -0
- data/lib/recipes/django.rb +8 -0
- data/lib/templates/django_vhost.vhost.erb +25 -0
- data/lib/templates/maintenance.html.erb +13 -0
- data/readme.markdown +165 -0
- metadata +64 -0
data/.gitignore
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# Rakefile
|
2
|
+
begin
|
3
|
+
require 'jeweler'
|
4
|
+
Jeweler::Tasks.new do |gemspec|
|
5
|
+
gemspec.name = "django-recipes"
|
6
|
+
gemspec.summary = "Set of capistrano recipies for deploying django applications."
|
7
|
+
gemspec.description = "Set of capistrano recipies for deploying django applications."
|
8
|
+
gemspec.email = "Adman1965@gmail.com"
|
9
|
+
gemspec.homepage = "http://github.com/Adman65/django-recipes"
|
10
|
+
gemspec.authors = ["Adam Hawkins"]
|
11
|
+
end
|
12
|
+
Jeweler::GemcutterTasks.new
|
13
|
+
rescue LoadError
|
14
|
+
puts "Jeweler not available. Install it with: sudo gem install jeweler -s http://gemcutter.org"
|
15
|
+
end
|
16
|
+
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.1
|
data/lib/helpers.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
def app_path
|
2
|
+
"#{deploy_to}/#{application}"
|
3
|
+
end
|
4
|
+
|
5
|
+
def system_path
|
6
|
+
"#{deploy_to}/system"
|
7
|
+
end
|
8
|
+
|
9
|
+
def media_root_path
|
10
|
+
"#{deploy_to}/#{media_root}"
|
11
|
+
end
|
12
|
+
|
13
|
+
def render(template, binding)
|
14
|
+
require 'erb'
|
15
|
+
template = File.read("#{File.dirname(__FILE__)}/templates/#{template}.erb")
|
16
|
+
result = ERB.new(template).result(binding)
|
17
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
2
|
+
namespace :deploy do
|
3
|
+
desc "Prepares system for deployment"
|
4
|
+
task :setup, :roles => :app do
|
5
|
+
run "mkdir -p #{deploy_to}/system"
|
6
|
+
run "cd #{deploy_to}; git clone #{repository}"
|
7
|
+
create_upload_directories
|
8
|
+
make_system_writable
|
9
|
+
symlink
|
10
|
+
vhost
|
11
|
+
end
|
12
|
+
|
13
|
+
task :create_upload_directories, :roles => :app do
|
14
|
+
upload_directories.each do |dir|
|
15
|
+
run "mkdir -p #{system_path}/#{dir}"
|
16
|
+
end
|
17
|
+
make_system_writable
|
18
|
+
end
|
19
|
+
|
20
|
+
desc "Deploys to an unitialized server"
|
21
|
+
task :cold, :roles => :app do
|
22
|
+
setup
|
23
|
+
syncdb
|
24
|
+
django #runs the deploy:django task
|
25
|
+
end
|
26
|
+
|
27
|
+
desc "Deploy your django app"
|
28
|
+
task :django, :roles => :app do
|
29
|
+
disable
|
30
|
+
run "cd #{deploy_to}/#{application}; git pull"
|
31
|
+
reload
|
32
|
+
enable
|
33
|
+
end
|
34
|
+
|
35
|
+
task :make_system_writable, :roles => :app do
|
36
|
+
run "chgrp -R #{apache_user} #{system_path}"
|
37
|
+
run "chmod -R g+wx #{system_path}"
|
38
|
+
end
|
39
|
+
|
40
|
+
task :symlink, :roles => :app do
|
41
|
+
media_root_symlink
|
42
|
+
admin_symlink
|
43
|
+
system_symlink
|
44
|
+
end
|
45
|
+
|
46
|
+
task :media_root_symlink, :roles => :app do
|
47
|
+
run "ln -sf #{app_path}/#{media_root} #{media_root_path}"
|
48
|
+
end
|
49
|
+
|
50
|
+
task :system_symlink, :roles => :app do
|
51
|
+
run "ln -sf #{system_path} #{media_root_path}/system"
|
52
|
+
end
|
53
|
+
|
54
|
+
task :admin_symlink, :roles => :app do
|
55
|
+
sudo "ln -sf #{django_path}/django/contrib/admin/media #{media_root_path}/#{admin_media_root}"
|
56
|
+
end
|
57
|
+
|
58
|
+
desc "Creates a vhost for your application and uploads to server"
|
59
|
+
task :vhost, :roles => :app do
|
60
|
+
put render('django_vhost.vhost',binding), "/tmp/#{vhost_name}"
|
61
|
+
sudo "mv /tmp/#{vhost_name} #{vhost_path}/#{vhost_name}"
|
62
|
+
end
|
63
|
+
|
64
|
+
desc "Run django syncdb"
|
65
|
+
task :syncdb, :roles => :app do
|
66
|
+
run "cd #{app_path} ; ./manage.py syncdb --setting=#{settings}"
|
67
|
+
end
|
68
|
+
|
69
|
+
desc "Destroys this app on the server"
|
70
|
+
task :destroy, :roles => :app do
|
71
|
+
run "rm -rf #{deploy_to}/*"
|
72
|
+
sudo "rm #{vhost_path}/#{vhost_name}"
|
73
|
+
reload
|
74
|
+
end
|
75
|
+
|
76
|
+
desc "Reloads apache"
|
77
|
+
task :reload, :roles => :app do
|
78
|
+
sudo "#{reload_cmd}"
|
79
|
+
end
|
80
|
+
|
81
|
+
desc "Enables the website"
|
82
|
+
task :enable, :roles => :app do
|
83
|
+
run "rm #{system_path}/maintenance.html"
|
84
|
+
end
|
85
|
+
|
86
|
+
desc "Disable the website"
|
87
|
+
task :disable, :roles => :app do
|
88
|
+
put render('maintenance.html',binding), "/tmp/maintenance.html"
|
89
|
+
run "mv /tmp/maintenance.html #{system_path}/maintenance.html"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
<VirtualHost *:80>
|
2
|
+
ServerName <%= server_name %>
|
3
|
+
SetHandler python-program
|
4
|
+
PythonHandler django.core.handlers.modpython
|
5
|
+
SetEnv DJANGO_SETTINGS_MODULE <%= application %>.<%= settings %>
|
6
|
+
PythonPath "['<%= deploy_to %>/<%= application %>', '<%= deploy_to %>'] + sys.path"
|
7
|
+
PythonDebug Off
|
8
|
+
Alias /<%= media_root %> <%= media_root_path%>
|
9
|
+
|
10
|
+
<Directory "<%= deploy_to %>">
|
11
|
+
Options FollowSymLinks
|
12
|
+
Order deny,allow
|
13
|
+
Allow from all
|
14
|
+
</Directory>
|
15
|
+
|
16
|
+
<Location "/<%= media_root %>">
|
17
|
+
SetHandler None
|
18
|
+
</Location>
|
19
|
+
|
20
|
+
RewriteEngine On
|
21
|
+
RewriteCond <%= system_path %>/maintenance.html -f
|
22
|
+
RewriteCond %{REQUEST_URI} !/<%= media_root %>/system/maintenance.html
|
23
|
+
RewriteRule $ /<%= media_root %>/system/maintenance.html [R=302,L]
|
24
|
+
|
25
|
+
</VirtualHost>
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
|
2
|
+
"http://www.w3.org/TR/html4/loose.dtd">
|
3
|
+
<html>
|
4
|
+
<head>
|
5
|
+
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
|
6
|
+
<meta http-equiv="Content-Language" content="en-us">
|
7
|
+
<title>AFK, Out for a Drink</title>
|
8
|
+
</head>
|
9
|
+
<body>
|
10
|
+
<h1>Sorry, the site is down for maintenance.</h1>
|
11
|
+
</body>
|
12
|
+
</html>
|
13
|
+
|
data/readme.markdown
ADDED
@@ -0,0 +1,165 @@
|
|
1
|
+
# Django Recipes
|
2
|
+
Django Recipes is a set of capistrano recipes created to automate deployment of simple Django powered websites. Once you've configured your capfile and server, you can go from no app, to running app.
|
3
|
+
|
4
|
+
# Features
|
5
|
+
* One command deployment for setup servers: from no app to running app
|
6
|
+
* Maintenace Page
|
7
|
+
* Generated Vhost File
|
8
|
+
* Git based
|
9
|
+
|
10
|
+
# Tasks
|
11
|
+
deploy:cold # Deploys to an unitialized server (runs deploy:setup then deploy:django)
|
12
|
+
deploy:destroy # Destroys this app on the server
|
13
|
+
deploy:django # Deploy your django app
|
14
|
+
deploy:reload # Reloads apache
|
15
|
+
deploy:syncdb # Run django syncdb
|
16
|
+
deploy:vhost # Creates a vhost for your application and uploads it
|
17
|
+
web:disable # Disable the website
|
18
|
+
web:enable # Enables the website
|
19
|
+
|
20
|
+
# How it Works
|
21
|
+
Capistrano uses ssh to connect to your server and create a directory structure. It uses this directory structure:
|
22
|
+
|
23
|
+
/+
|
24
|
+
|- application
|
25
|
+
|- system
|
26
|
+
/+ media_root # symlinked from media_root from application
|
27
|
+
|- system # symlinked to the root level system
|
28
|
+
|- admin_media_root # symlinked to django/contrib/admin/media
|
29
|
+
|
30
|
+
There is some Rails style going on here. Application is where your django code lives. System is a directory that survives through different deployments. You should use system for user file uploads and things like that. Your stylesheets, images, and javascript live in media_root. These folders are symlinked to create access for your webserver.
|
31
|
+
|
32
|
+
# Requirements
|
33
|
+
Before you deploy your app, your server needs to be running apache and mod_python. If you are using Fedora you can use my [gem](http://github.com/Adman65/fedora) to make this process go very quickly. Django recipes assumes that you have a top level folder for your media root. Recapped:
|
34
|
+
|
35
|
+
* Python, Apache, mod_python, and your DBMS installed
|
36
|
+
* User with sudo access (for linking to admin media)
|
37
|
+
* top level media directory
|
38
|
+
* ruby & rubygems installed
|
39
|
+
|
40
|
+
# Setuping on Your Capfile
|
41
|
+
Lets take an example application and the associated config file.
|
42
|
+
|
43
|
+
## Application Structure
|
44
|
+
/mysite
|
45
|
+
/settings
|
46
|
+
production.py
|
47
|
+
development.py
|
48
|
+
/pictures
|
49
|
+
/avatars
|
50
|
+
/public # media_root
|
51
|
+
/images
|
52
|
+
/stylesheets
|
53
|
+
/system
|
54
|
+
/pictures # for uploaded pictures
|
55
|
+
/avatars # for uploaded avatars
|
56
|
+
/templates
|
57
|
+
|
58
|
+
## Settings: production.py
|
59
|
+
|
60
|
+
# only relavent settings for deployment are included
|
61
|
+
MEDIA_ROOT = os.path.join(os.path.dirname(os.path.abspath(__file__)), "../public") # refers to /public because /settings/production.py
|
62
|
+
ADMIN_MEDIA_PREFIX = '/public/admin/'
|
63
|
+
MEDIA_URL = 'http://mydomain.com/public/'
|
64
|
+
|
65
|
+
## Capfile Configuration
|
66
|
+
|
67
|
+
### SCM Setup ###
|
68
|
+
repository # Git only
|
69
|
+
application # Name of your project
|
70
|
+
|
71
|
+
### Deployment Settings ###
|
72
|
+
deploy_to # this directory should already exist and the user should have control over it
|
73
|
+
apache_user # name of apache user on your server
|
74
|
+
server_name # for the ServerName entry in the vhost
|
75
|
+
vhost_name # name of vhost to create
|
76
|
+
vhost_path # location to put vhost file on your server (no trailing slash)
|
77
|
+
reload_cmd # command to reload apache (ex: service httpd reload)
|
78
|
+
|
79
|
+
### Django Settings ###
|
80
|
+
django_path # path to where django is installed. User for linking admin media
|
81
|
+
settings # settings to use (must be specified)
|
82
|
+
upload_directories # Array of directories to create in /system (must be an array)
|
83
|
+
|
84
|
+
media_root # corresponds to your MEDIA_ROOT
|
85
|
+
admin_media_root # corresponds to your ADMIN_MEDIA_PREFIX
|
86
|
+
|
87
|
+
## The VHost Template
|
88
|
+
|
89
|
+
<VirtualHost *:80>
|
90
|
+
ServerName <%= server_name %>
|
91
|
+
SetHandler python-program
|
92
|
+
PythonHandler django.core.handlers.modpython
|
93
|
+
SetEnv DJANGO_SETTINGS_MODULE <%= application %>.<%= settings %>
|
94
|
+
PythonPath "['<%= deploy_to %>/<%= application %>', '<%= deploy_to %>'] + sys.path"
|
95
|
+
PythonDebug Off
|
96
|
+
Alias /<%= media_root %> <%= media_root_path%>
|
97
|
+
|
98
|
+
<Directory "<%= deploy_to %>">
|
99
|
+
Options FollowSymLinks
|
100
|
+
Order deny,allow
|
101
|
+
Allow from all
|
102
|
+
</Directory>
|
103
|
+
|
104
|
+
<Location "/<%= media_root %>">
|
105
|
+
SetHandler None
|
106
|
+
</Location>
|
107
|
+
|
108
|
+
RewriteEngine On
|
109
|
+
RewriteCond <%= system_path %>/maintenance.html -f
|
110
|
+
RewriteCond %{REQUEST_URI} !/<%= media_root %>/system/maintenance.html
|
111
|
+
RewriteRule $ /<%= media_root %>/system/maintenance.html [R=302,L]
|
112
|
+
|
113
|
+
</VirtualHost>
|
114
|
+
|
115
|
+
# Time to Deploy
|
116
|
+
## Step 1:
|
117
|
+
|
118
|
+
# install ruby & ruby gems if you haven't done that already
|
119
|
+
gem install gemcutter
|
120
|
+
gem tumble
|
121
|
+
gem install capistrano
|
122
|
+
gem install django-recipes
|
123
|
+
|
124
|
+
## Step 2: Capify
|
125
|
+
|
126
|
+
cd myproject
|
127
|
+
capify .
|
128
|
+
|
129
|
+
## Step 3: Prepare your cap file
|
130
|
+
|
131
|
+
require 'django-recipes' # require django-recipes
|
132
|
+
|
133
|
+
### SSH Options ###
|
134
|
+
set :user, "deployer"
|
135
|
+
default_run_options[:pty] = true
|
136
|
+
|
137
|
+
### SCM Setup ###
|
138
|
+
set :repository, "git@github.com:Adman65/broadcastingadam.git" # git only
|
139
|
+
set :application, "broadcastingadam"
|
140
|
+
|
141
|
+
### Servers Setup ###
|
142
|
+
role :web, "www.broadcastingadam.com"
|
143
|
+
role :app, "www.broadcastingadam.com"
|
144
|
+
role :db, "www.broadcastingadam.com", :primary => true
|
145
|
+
role :db, "www.broadcastingadam.com"
|
146
|
+
|
147
|
+
### Deployment Settings ###
|
148
|
+
set :deploy_to, "/var/www/html/www.broadcastingadam.com" #this directory should already exist and the user should have control over it
|
149
|
+
set :apache_user, "apache"
|
150
|
+
set :server_name, "broadcastingadam.com" #for the ServerName entry in the vhost
|
151
|
+
set :vhost_name, "#{server_name}.vhost"
|
152
|
+
set :vhost_path, "/etc/httpd/vhost.d" #no trailingslash
|
153
|
+
set :reload_cmd, "service httpd reload"
|
154
|
+
|
155
|
+
### Django Settings ###
|
156
|
+
set :django_path, "/usr/lib/python2.6/site-packages/Django-1.1.1-py2.6.egg"
|
157
|
+
set :settings, "settings.production" # this example uses split settings, but you can just use settings like normal
|
158
|
+
set :upload_directories, ['covers','projects'] # must be an array
|
159
|
+
|
160
|
+
set :media_root, "public"
|
161
|
+
set :admin_media_root, "admin"
|
162
|
+
|
163
|
+
## Step 4: Deploy
|
164
|
+
|
165
|
+
cap deploy:cold
|
metadata
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: django-recipes
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Adam Hawkins
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-11-08 00:00:00 -08:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: Set of capistrano recipies for deploying django applications.
|
17
|
+
email: Adman1965@gmail.com
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files: []
|
23
|
+
|
24
|
+
files:
|
25
|
+
- .gitignore
|
26
|
+
- Rakefile
|
27
|
+
- VERSION
|
28
|
+
- lib/django-recipes.rb
|
29
|
+
- lib/helpers.rb
|
30
|
+
- lib/recipes/deploy.rb
|
31
|
+
- lib/recipes/django.rb
|
32
|
+
- lib/templates/django_vhost.vhost.erb
|
33
|
+
- lib/templates/maintenance.html.erb
|
34
|
+
- readme.markdown
|
35
|
+
has_rdoc: true
|
36
|
+
homepage: http://github.com/Adman65/django-recipes
|
37
|
+
licenses: []
|
38
|
+
|
39
|
+
post_install_message:
|
40
|
+
rdoc_options:
|
41
|
+
- --charset=UTF-8
|
42
|
+
require_paths:
|
43
|
+
- lib
|
44
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ">="
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: "0"
|
49
|
+
version:
|
50
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: "0"
|
55
|
+
version:
|
56
|
+
requirements: []
|
57
|
+
|
58
|
+
rubyforge_project:
|
59
|
+
rubygems_version: 1.3.5
|
60
|
+
signing_key:
|
61
|
+
specification_version: 3
|
62
|
+
summary: Set of capistrano recipies for deploying django applications.
|
63
|
+
test_files: []
|
64
|
+
|