server directory permissions /var/www

1
2
3
drwxr-xr-x  3 root root     4096 2010-09-29 11:12 .
drwxr-xr-x 14 root root     4096 2010-09-29 11:12 ..
drwxr-xr-x  5 root www-data 4096 2010-09-29 12:26 app_name

/var/www/app_name

1
2
3
4
5
drwxr-xr-x 5 root www-data 4096 2010-09-29 12:26 .
drwxr-xr-x 3 root root     4096 2010-09-29 11:12 ..
drwxr-xr-x 2 root www-data 4096 2010-09-29 11:12 current
drwxr-xr-x 2 root www-data 4096 2010-09-29 14:09 releases
drwxr-xr-x 9 root www-data 4096 2010-09-29 13:13 shared

deploy.rb

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
set :application, "app_name"
set :deploy_to, "/var/www/#{application}"
set :scm, :git
set :repository, "[email protected]:scm_username/app_name.git"
set :branch, "master"
set :deploy_via, :remote_cache

ssh_options[:keys] = [File.join(ENV["HOME"], ".ssh", "id_rsa.pub")]

default_run_options[:pty] = true

set :default_env,  'production'

set :rails_env, ENV['rails_env'] || ENV['RAILS_ENV'] || default_env

# Or: `accurev`, `bzr`, `cvs`, `darcs`, `git`, `mercurial`, `perforce`, `subversion` or `none`

set :user, 'deploy'
set :group, 'www-data'
set :www-data-user, 'www-data'
set :use_sudo, true

role :web, "server_ip"                          # Your HTTP server, Apache/etc
role :app, "server_ip"                          # This may be the same as your `Web` server
role :db,  "server_ip", :primary => true # This is where Rails migrations will run

# If you are using Passenger mod_rails uncomment this:
# if you're still using the script/reapear helper you will need
# these http://github.com/rails/irs_process_scripts

namespace :deploy do
    task :start do ; end
    task :stop do ; end
    task :restart, :roles => :app, :except => { :no_release => true } do
        run "#{try_sudo} touch #{File.join(current_path,'tmp','restart.txt')}"
    end

    after "deploy:stop" do
        dj_stop
    end
    after "deploy:start" do
        dj_start
    end

    before "deploy:restart" do
        package_assets
    end
    after "deploy:restart" do
        dj_restart
    end

    
    after "deploy:symlink" do
#        update_crontab
        chown_to_www_data
    end

    after "deploy:setup" do
        create_shared_dirs
    end
    
    after "deploy:update_code" do
        symlink_shared
#       restart_sphinx
    end

    before "deploy:update" do
        check_in_git
    end

    desc 'Check in pending work to git'
    task :check_in_git do
        system 'git add .'
        system "git commit -m 'automated check in'"
        system "git push origin master"
    end

    desc "Create shared links"
    task :symlink_shared, :roles => :app  do
        #Copy the files firest
        top.upload("config/database.yml", "#{shared_path}/config", :via => :scp)
        #generate_sphinx_config_yaml
        top.upload("config/sphinx.yml", "#{shared_path}/config", :via => :scp)
        top.upload("config/config.yml", "#{shared_path}/config", :via => :scp)
        run "ln -nfs #{shared_path}/sphinx #{release_path}/db/sphinx"
        run "ln -nfs #{shared_path}/config/database.yml #{release_path}/config/database.yml"
        run "ln -nfs #{shared_path}/config/sphinx.yml #{release_path}/config/sphinx.yml"
        #        run "ln -nfs #{shared_path}/config/sphinx.conf #{release_path}/config/sphinx.conf"
        run "ln -nfs #{shared_path}/config/config.yml #{release_path}/config/config.yml"
        run "ln -nfs #{shared_path}/assets #{release_path}/public/assets"
    end

    desc "Create additional shared directories"
    task :create_shared_dirs do
        run "mkdir -p #{shared_path}/assets/images/users"
        run "run if [[ -d #{shared_path}/assets/images/users ]] then; else mkdir -p #{shared_path}/assets/images/users; fi"
        run "mkdir #{shared_path}/config"
        run "mkdir #{shared_path}/sphinx"
    end

    desc "Change group to www-data"
    task :chown_to_www_data, :roles => [ :app, :db, :web ] do
        sudo "chown -R #{user}:www-data #{deploy_to}"
        sudo "chmod -R 755 #{deploy_to}"
    end

    task :create_sphinx_db_dir, :roles => :app do
        run "mkdir -p #{shared_path}/sphinx"
    end

    task :install_log_rotate_script, :roles => :app do
        rotate_script = %Q{#{shared_path}/log/#{rails_env}.log {
        daily
        rotate 14
        size 5M
        compress
        create 640 #{user} #{group}
        missingok
        }}
        put rotate_script, "#{shared_path}/logrotate_script"
        sudo "cp #{shared_path}/logrotate_script /etc/logrotate.d/#{application}"
        delete "#{shared_path}/logrotate_script"
    end

    task :package_assets do
        set :rake_cmd, "asset:packager:build_all"
        rake_exec
    end
    
    set :rake_cmd, (ENV['RAKE_CMD'] || nil)

    task :rake_exec do
        if rake_cmd
            run "cd #{current_path} && rake #{rake_cmd} RAILS_ENV=#{rails_env}"
        end
    end

    # Clear file-based fragment and/or page cache
    task :clear_cache do
        # I usually make a custom Rake task for this
        set :rake_cmd, "tmp:cache:clear"
        rake_exec
    end


    ######################Sphinx configuration#####################

    desc 'Generate a config yaml in shared path'
    task :generate_sphinx_config_yaml, :roles => :app do
        config = {"morphology" => "stem_en", "config_file" => "#{shared_path}/config/sphinx.conf",
            "searchd_log_file" => "#{shared_path}/log/searchd.log",
            "query_log_file" => "#{shared_path}/log/searchd.query.log",
            "pid_file" =>  "#{shared_path}/log/searchd.#{rails_env}.pid",
            "mem_limit"=> "20M",
            "enable_star" => true,
            "searchd_file_path" => "#{shared_path}/sphinx"
        }
        put config.to_yaml, "#{shared_path}/config/sphinx.yml"
    end

    desc "Stop the sphinx server"
    task :stop_sphinx , :roles => :app do
        run "cd #{release_path} && rake  thinking_sphinx:stop RAILS_ENV=#{rails_env}"
    end

    desc "Start the sphinx server”"
    task :start_sphinx, :roles => :app do
        run "cd #{release_path} && rake thinking_sphinx:configure RAILS_ENV=#{rails_env} && rake thinking_sphinx:start RAILS_ENV=#{rails_env}"
    end

    desc "Restart the sphinx server"
    task :restart_sphinx, :roles => :app do
        stop_sphinx
        start_sphinx
    end

    ###########################update cron tab with whenever ################################
    desc "Update the crontab file"
    task :update_crontab, :roles => :db do
        run "cd #{release_path} && whenever --set environment=production --update-crontab #{application}"
    end

    ##########################################################################################
    #################Delayed job#############################################################
    def get_rails_env
        fetch(:rails_env, false) ? "RAILS_ENV=#{fetch(:rails_env)}" : ''
    end

    desc "Stop the delayed_job process"
    task :dj_stop, :roles => :app do
        run "cd #{current_path};#{get_rails_env} script/delayed_job stop"
    end

    desc "Start the delayed_job process"
    task :dj_start, :roles => :app do
        run "cd #{current_path};#{get_rails_env} script/delayed_job start"
    end

    desc "Restart the delayed_job process"
    task :dj_restart, :roles => :app do
        run "cd #{current_path};#{get_rails_env} script/delayed_job restart"
        #        dj_ensure
    end

    desc "Show delayed_job daemon status."
    task :dj_status, :roles => :app do
        run "if [ -d #{current_path} ]; then cd #{current_path} && sudo RAILS_ENV=#{rails_env} script/delayed_job status; fi"
    end

    desc "List the PIDs of all running delayed_job daemons."
    task :dj_pids, :roles => :app do
        run "sudo lsof | grep '#{deploy_to}/shared/log/delayed_job.log' | cut -c 1-21 | uniq | awk '/^ruby/ {if(NR > 0){system(\"echo \" $2)}}'"
    end

    desc "Kill all running delayed_job daemons."
    task :dj_kill, :roles => :app do
        run "sudo lsof | grep '#{deploy_to}/shared/log/delayed_job.log' | cut -c 1-21 | uniq | awk '/^ruby/ {if(NR > 0){system(\"kill -9 \" $2)}}'"
        run "if [-d #{current_path} ]; then cd #{current_path} && sudo RAILS_ENV=#{rails_env} script/delayed_job stop; fi" # removes orphaned pid file(s)
    end

    task :dj_ensure, :roles => :app do
        pid_from_file = capture("cat #{current_path}/tmp/pids/delayed_job.pid").strip
        running_pids = capture("ps -ef | grep [d]elayed_job").split("\n").map { |x| x.split[1] }
        if pid_from_file != running_pids.first || running_pids.size != 1
            puts ("-"*80).console_purple
            puts "Something is terribly wrong with delayed job!".console_red
            puts "Running_pid: #{pid_from_file}"
            puts "Running delayed job processes: #{capture("ps -ef | grep [d]elayed_job")}"
            puts ("-"*80).console_purple
        end
    end
end

Capistrano output

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
 * scp upload complete
  * executing "ln -nfs /var/www/app_name/shared/sphinx /var/www/app_name/releases/20100929210955/db/sphinx"
    servers: ["server_ip"]
    [server_ip] executing command
    command finished
  * executing "ln -nfs /var/www/app_name/shared/config/database.yml /var/www/app_name/releases/20100929210955/config/database.yml"
    servers: ["server_ip"]
    [server_ip] executing command
    command finished
  * executing "ln -nfs /var/www/app_name/shared/config/sphinx.yml /var/www/app_name/releases/20100929210955/config/sphinx.yml"
    servers: ["server_ip"]
    [server_ip] executing command
    command finished
  * executing "ln -nfs /var/www/app_name/shared/config/config.yml /var/www/app_name/releases/20100929210955/config/config.yml"
    servers: ["server_ip"]
    [server_ip] executing command
    command finished
  * executing "ln -nfs /var/www/app_name/shared/assets /var/www/app_name/releases/20100929210955/public/assets"
    servers: ["server_ip"]
    [server_ip] executing command
    command finished
  * executing `deploy:symlink'
  * executing "rm -f /var/www/app_name/current && ln -s /var/www/app_name/releases/20100929210955 /var/www/app_name/current"
    servers: ["server_ip"]
    [server_ip] executing command
 ** [out :: server_ip] rm: cannot remove `/var/www/app_name/current': Is a directory
    command finished
*** [deploy:symlink] rolling back
  * executing "ls -x /var/www/app_name/releases"
    servers: ["server_ip"]
    [server_ip] executing command
    command finished
*** no previous release to rollback to, rollback of symlink skipped
*** [deploy:update_code] rolling back
  * executing "rm -rf /var/www/app_name/releases/20100929210955; true"
    servers: ["server_ip"]
    [server_ip] executing command
    command finished
failed: "sh -c 'rm -f /var/www/app_name/current && ln -s /var/www/app_name/releases/20100929210955 /var/www/app_name/current'" on server_ip