django-recipes 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.0.0
1
+ 1.1.0
@@ -1,17 +1,5 @@
1
1
  require 'erb'
2
2
 
3
- def app_path
4
- "#{deploy_to}/#{application}"
5
- end
6
-
7
- def system_path
8
- "#{deploy_to}/system"
9
- end
10
-
11
- def media_root_path
12
- "#{deploy_to}/#{media_root}"
13
- end
14
-
15
3
  def render(template, binding)
16
4
  template = File.read("#{File.dirname(__FILE__)}/templates/#{template}.erb")
17
5
  result = ERB.new(template).result(binding)
@@ -1,92 +1,85 @@
1
1
  Capistrano::Configuration.instance(:must_exist).load do
2
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
-
3
+ desc <<-DESC
4
+ [internal] Touches up the released code. This is called by update_code \
5
+ after the basic deploy finishes. It assumes a Rails project was deployed, \
6
+ so if you are deploying something else, you may want to override this \
7
+ task with your own environment's requirements.
8
+
9
+ This task will make the release group-writable (if the :group_writable \
10
+ variable is set to true, which is the default). It will then set up \
11
+ symlinks to the shared directory for the log, system, and tmp/pids \
12
+ directories, and will lastly touch all assets in {media_root}/images, \
13
+ {media_root}/stylesheets, and {media_root}/javascripts so that the times are \
14
+ consistent (so that asset timestamping works). This touch process \
15
+ is only carried out if the :normalize_asset_timestamps variable is \
16
+ set to true, which is the default.
17
+ DESC
18
+ task :finalize_update, :except => { :no_release => true } do
19
+ run "chmod -R g+w #{latest_release}" if fetch(:group_writable, true)
20
+
21
+ run <<-CMD
22
+ ln -s #{shared_path}/system #{latest_release}/#{media_root} &&
23
+ ln -s #{django_path}/django/contrib/admin/media #{latest_release}/#{media_root}/#{admin_media_root}
24
+ CMD
25
+
26
+ if fetch(:normalize_asset_timestamps, true)
27
+ stamp = Time.now.utc.strftime("%Y%m%d%H%M.%S")
28
+ asset_paths = %w(images stylesheets javascripts).map { |p| "#{latest_release}/#{media_root}/#{p}" }.join(" ")
29
+ run "find #{asset_paths} -exec touch -t #{stamp} {} ';'; true", :env => { "TZ" => "UTC" }
30
+ end
31
+ end
32
+
33
+ desc <<-DESC
34
+ [internal] Creates upload directories in /shared/system that your app may need.
35
+ DESC
13
36
  task :create_upload_directories, :roles => :app do
14
37
  upload_directories.each do |dir|
15
- run "mkdir -p #{system_path}/#{dir}"
38
+ run "mkdir -p #{shared_path}/system/#{dir}"
16
39
  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}"
40
+ writable_directories
48
41
  end
49
-
50
- task :system_symlink, :roles => :app do
51
- run "ln -sf #{system_path} #{media_root_path}/system"
42
+ after('deploy:setup','deploy:create_upload_directories')
43
+
44
+ desc "[internal] Chgrp -R of /shared/system writable by the apache group"
45
+ task :writable_directories, :roles => :app do
46
+ sudo "chown -R #{user}:#{apache_group} #{shared_path}/system"
52
47
  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}"
48
+
49
+ desc "Starts the application server"
50
+ task :start, :roles => :app do
51
+ sudo "#{start_cmd}"
56
52
  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}"
53
+
54
+ desc "Stops the application server"
55
+ task :stop, :roles => :app do
56
+ sudo "#{stop_cmd}"
62
57
  end
63
-
64
- desc "Run django syncdb"
65
- task :syncdb, :roles => :app do
66
- run "cd #{app_path} ; ./manage.py syncdb --setting=#{settings}"
58
+
59
+ desc "Restarts the application server"
60
+ task :restart, :roles => :app do
61
+ sudo "#{restart_cmd}"
67
62
  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
63
 
76
- desc "Reloads apache"
77
- task :reload, :roles => :app do
64
+ desc "Reloads the application server"
65
+ task :reload, :roles => :app do
78
66
  sudo "#{reload_cmd}"
79
67
  end
80
-
81
- desc "Enables the website"
82
- task :enable, :roles => :app do
83
- run "rm #{system_path}/maintenance.html"
68
+
69
+ desc "Deletes everything in #{deploy_to}"
70
+ task :clobber, :roles => :app do
71
+ sudo "rm -rf #{deploy_to}/*"
84
72
  end
73
+
74
+ # tasks that don't do anythign with django
75
+ no_ops = ['migrate', 'migration']
76
+ no_ops.each do |name|
77
+ task name do ; end
78
+ end
85
79
 
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"
80
+ desc "Runs syncdb"
81
+ task :syncdb, :roles => :app do
82
+ run "cd #{app_path} ; ./manage.py syncdb --setting=#{settings}"
90
83
  end
91
84
  end
92
85
  end
@@ -2,7 +2,7 @@ Capistrano::Configuration.instance(:must_exist).load do
2
2
  namespace :django do
3
3
  desc "Runs a command from manage.py"
4
4
  task :manage, :roles => :app do
5
- run "cd #{app_path}; ./manage.py #{ENV['command']} --settings=#{settings}"
5
+ run "#{deploy_to}/#{application}/manage.py #{ENV['command']} --settings=#{settings} --pythonpath=#{deploy_to}"
6
6
  end
7
7
  end
8
8
  end
@@ -0,0 +1,17 @@
1
+ Capistrano::Configuration.instance(:must_exist).load do
2
+ namespace :vhost do
3
+ desc "Displays the vhost for your application"
4
+ task :show do
5
+ puts render('django_vhost.vhost',binding)
6
+ end
7
+
8
+
9
+ desc "Creates a vhost for your application and uploads to server"
10
+ task :upload, :roles => :app do
11
+ put render('django_vhost.vhost',binding), "/tmp/#{vhost_name}"
12
+ sudo "mv /tmp/#{vhost_name} #{vhost_path}/#{vhost_name}"
13
+ end
14
+ after('deploy:setup', 'vhost:upload')
15
+
16
+ end
17
+ end
@@ -5,7 +5,7 @@
5
5
  SetEnv DJANGO_SETTINGS_MODULE <%= application %>.<%= settings %>
6
6
  PythonPath "['<%= deploy_to %>/<%= application %>', '<%= deploy_to %>'] + sys.path"
7
7
  PythonDebug Off
8
- Alias /<%= media_root %> <%= media_root_path%>
8
+ Alias /<%= media_root %> <%= current_path %>/<%= media_root %>
9
9
 
10
10
  <Directory "<%= deploy_to %>">
11
11
  Options FollowSymLinks
@@ -18,7 +18,7 @@
18
18
  </Location>
19
19
 
20
20
  RewriteEngine On
21
- RewriteCond <%= system_path %>/maintenance.html -f
21
+ RewriteCond <%= shared_path %>/system/maintenance.html -f
22
22
  RewriteCond %{REQUEST_URI} !/<%= media_root %>/system/maintenance.html
23
23
  RewriteRule $ /<%= media_root %>/system/maintenance.html [R=302,L]
24
24
 
data/readme.markdown CHANGED
@@ -1,118 +1,52 @@
1
1
  # Django Recipes
2
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
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
- deploy:web:disable # Disable the website
18
- deploy:web:enable # Enables the website
19
- django:manage # runs a command from manage.py ie cap django:manage command=syncdb
20
-
21
- # How it Works
22
- Capistrano uses ssh to connect to your server and create a directory structure. It uses this directory structure:
23
-
24
- /+
25
- |- application
26
- |- system
27
- /+ media_root # symlinked from media_root from application
28
- |- system # symlinked to the root level system
29
- |- admin_media_root # symlinked to django/contrib/admin/media
30
-
31
- 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.
4
+ # Get It Done
5
+
6
+ gem install django-recipes
7
+ require 'django-recipes' # in your Capfile
8
+ cap deploy:setup cap deploy
9
+ http://www.yoursite.com/
32
10
 
33
11
  # Requirements
34
12
  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:
35
13
 
36
14
  * Python, Apache, mod_python, and your DBMS installed
37
- * User with sudo access (for linking to admin media)
38
- * top level media directory
39
- * ruby & rubygems installed
15
+ * User with sudo access
16
+ * Ruby & Rubygems installed
40
17
 
41
18
  # Setting on Your Capfile
42
19
  Lets take an example application and the associated config file.
43
20
 
44
- ## Application Structure
45
- /mysite
46
- /settings
47
- production.py
48
- development.py
49
- /pictures
50
- /avatars
51
- /public # media_root
52
- /images
53
- /stylesheets
54
- /system
55
- /pictures # for uploaded pictures
56
- /avatars # for uploaded avatars
57
- /templates
58
-
59
21
  ## Settings: production.py
60
22
 
61
23
  # only relavent settings for deployment are included
62
- MEDIA_ROOT = os.path.join(os.path.dirname(os.path.abspath(__file__)), "../public") # refers to /public because /settings/production.py
24
+ MEDIA_ROOT = '/public'
63
25
  ADMIN_MEDIA_PREFIX = '/public/admin/'
64
- MEDIA_URL = 'http://mydomain.com/public/'
65
26
 
66
- ## Capfile Configuration
67
-
68
- ### SCM Setup ###
69
- repository # Git only
70
- application # Name of your project
71
-
27
+ ## Capfile Configuration
28
+
72
29
  ### Deployment Settings ###
30
+ current_dir # !!! Don't forget this !!! set to your applications name
73
31
  deploy_to # this directory should already exist and the user should have control over it
74
- apache_user # name of apache user on your server
32
+ apache_group # name of apache user on your server
75
33
  server_name # for the ServerName entry in the vhost
76
34
  vhost_name # name of vhost to create
77
35
  vhost_path # location to put vhost file on your server (no trailing slash)
78
36
  reload_cmd # command to reload apache (ex: service httpd reload)
37
+ start_cmd #
38
+ reload_cmd #
39
+ stop_cmd #
79
40
 
80
41
  ### Django Settings ###
81
42
  django_path # path to where django is installed. User for linking admin media
82
43
  settings # settings to use (must be specified)
83
44
  upload_directories # Array of directories to create in /system (must be an array)
45
+ # set to [] if you don't have any
84
46
 
85
47
  media_root # corresponds to your MEDIA_ROOT
86
48
  admin_media_root # corresponds to your ADMIN_MEDIA_PREFIX
87
49
 
88
- ## The VHost Template
89
-
90
- <VirtualHost *:80>
91
- ServerName <%= server_name %>
92
- SetHandler python-program
93
- PythonHandler django.core.handlers.modpython
94
- SetEnv DJANGO_SETTINGS_MODULE <%= application %>.<%= settings %>
95
- PythonPath "['<%= deploy_to %>/<%= application %>', '<%= deploy_to %>'] + sys.path"
96
- PythonDebug Off
97
- Alias /<%= media_root %> <%= media_root_path%>
98
-
99
- <Directory "<%= deploy_to %>">
100
- Options FollowSymLinks
101
- Order deny,allow
102
- Allow from all
103
- </Directory>
104
-
105
- <Location "/<%= media_root %>">
106
- SetHandler None
107
- </Location>
108
-
109
- RewriteEngine On
110
- RewriteCond <%= system_path %>/maintenance.html -f
111
- RewriteCond %{REQUEST_URI} !/<%= media_root %>/system/maintenance.html
112
- RewriteRule $ /<%= media_root %>/system/maintenance.html [R=302,L]
113
-
114
- </VirtualHost>
115
-
116
50
  # Time to Deploy
117
51
  ## Step 1:
118
52
 
@@ -130,37 +64,37 @@ Lets take an example application and the associated config file.
130
64
  ## Step 3: Prepare your cap file
131
65
 
132
66
  require 'django-recipes' # require django-recipes
67
+ ### Set up your regular SCM settings
133
68
 
134
- ### SSH Options ###
135
- set :user, "deployer"
136
- default_run_options[:pty] = true
137
-
138
- ### SCM Setup ###
139
- set :repository, "git@github.com:Adman65/broadcastingadam.git" # git only
140
- set :application, "broadcastingadam"
141
-
142
- ### Servers Setup ###
143
- role :web, "www.broadcastingadam.com"
144
- role :app, "www.broadcastingadam.com"
145
- role :db, "www.broadcastingadam.com", :primary => true
146
- role :db, "www.broadcastingadam.com"
69
+ ### Apache settings
70
+ set :reload_cmd, "service httpd reload"
71
+ set :start_cmd, "service httpd start"
72
+ set :stop_cmd, "service httpd stop"
73
+ set :restart_cmd, "service httpd reload"
74
+ set :apache_group, "apache"
147
75
 
148
76
  ### Deployment Settings ###
149
- set :deploy_to, "/var/www/html/www.broadcastingadam.com" #this directory should already exist and the user should have control over it
150
- set :apache_user, "apache"
151
- set :server_name, "broadcastingadam.com" #for the ServerName entry in the vhost
77
+ set :deploy_to, "/var/www/html/www.broadcastingadam.com"
78
+ set :server_name, "broadcastingadam.com"
152
79
  set :vhost_name, "#{server_name}.vhost"
153
- set :vhost_path, "/etc/httpd/vhost.d" #no trailingslash
154
- set :reload_cmd, "service httpd reload"
80
+ set :vhost_path, "/etc/httpd/vhost.d"
155
81
 
156
82
  ### Django Settings ###
157
83
  set :django_path, "/usr/lib/python2.6/site-packages/Django-1.1.1-py2.6.egg"
158
- set :settings, "settings.production" # this example uses split settings, but you can just use settings like normal
159
- set :upload_directories, ['covers','projects'] # must be an array
84
+ set :settings, "settings.production"
85
+ set :upload_directories, ['covers','projects']
160
86
 
161
87
  set :media_root, "public"
162
88
  set :admin_media_root, "admin"
163
89
 
164
90
  ## Step 4: Deploy
165
91
 
166
- cap deploy:cold
92
+ cap deploy:setup cap:deploy
93
+ # at this point you may need to ssh into your machine to run syncdb because of problems with user input
94
+ # IE creating a super user, if aren't using admin
95
+ cap django:manage command=syncdb
96
+
97
+ # Notes
98
+
99
+ You should use the system directory for files have to maintain between deployments, IE user uploads.
100
+ When running the deploy:web* tasks, capistrano will show you a warning about adding rewrite conditions to your vhost file. You don't have to worry about it. They are already there.
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: django-recipes
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adam Hawkins
@@ -29,8 +29,8 @@ files:
29
29
  - lib/django-recipes/helpers.rb
30
30
  - lib/django-recipes/recipes/deploy.rb
31
31
  - lib/django-recipes/recipes/django.rb
32
+ - lib/django-recipes/recipes/vhost.rb
32
33
  - lib/django-recipes/templates/django_vhost.vhost.erb
33
- - lib/django-recipes/templates/maintenance.html.erb
34
34
  - readme.markdown
35
35
  has_rdoc: true
36
36
  homepage: http://github.com/Adman65/django-recipes
@@ -1,13 +0,0 @@
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
-