Images folder concern when deploying with Capistrano and git

Hi guys,

So I finally got around to setting up a staging server (ubuntu + apache

  • passenger) and after some headaches got Capistrano (using git as the
    scm) to deploy the app to my staging server using a basic deploy.rb
    file. Everything seems to be working well, any changes I commit and
    deploy take effect.

HOWEVER, I am storing user pictures using the paperclip plugin to the
staging server filesystem (rails_root/public/images/users/). After
creating some users and uploading their pictures (on the staging
server), I decided to deploy some changes I made to the app only to find
out that my user pictures we’re overwritten with my local (development)
user image folder.

I rolled back the deployment and all the pictures were displayed like
they were previously (on the staging server)

So I added the following line to the .gitignore file to my local
(development) machine:

public/images/users/*

I committed the change and deployed but again, the local development
machine’s user image folder replaces the staging server user image
folder contents.

Below is my deploy.rb file contents (edited):


set :application, "staging.domain.com"
set :repository,  "."

set :rails_env, "staging"
set :user, "user"
set :deploy_to, "/home/#{user}/public/#{application}"
set :use_sudo, true

set :scm, :git
set :deploy_via, :copy
set :copy_remote_dir, "/home/#{user}"

role :app, application
role :web, application
role :db,  application, :primary => true

namespace :deploy do
  desc "Restarting mod_rails with restart.txt"
  task :restart, :roles => :app, :except => { :no_release => true } do
    run "touch #{current_path}/tmp/restart.txt"
  end
  [:start, :stop].each do |t|
    desc "#{t} task is a no-op with mod_rails"
    task t, :roles => :app do ; end
  end
end

I’m pretty much stumped on this. Also, I realize doing a full copy every
time to the server isn’t the best thing to do, but it’s the only way I
can (currently) get it to work. I’m still pretty new at this
rails/scm/terminal world. :wink:

Let me know if you need any more info or code from my end that may help.

Thanks for any advice or suggestions!

-Tony

I think, if I’m understanding your situation correctly, you want to
symlink your user image directories into somewhere under your “/home/
#{user}/public/#{application}/shared” directory.

The “shared” directory created by capistrano on your staging server
does not change from release to release. Create that directory on
your local dev box and make sure that path is the same as on the
staging serve. Then on both your dev and staging boxes create
subdirectories under that perhaps “shared/images/users”. Remove the
existing “/public/images/users” then symlink to the shared directory
(from your public/images directory just do: “ln -s /home/#{user}/
public/#{application}/shared/images/users users” in case your not
familiar).

I haven’t used git but I would assume that it can version symlinks.

Hope that helps!
Tim

On Nov 1, 10:13 am, Tony T. [email protected]

That is how Capistrano is supposed to work. You checkout new code from
your repo and the current link is replaced with the latest checkout in
releases/datestamp.

Just like Tim said when you have content that needs to be shared
between releases you need to put that somewhere else LIKE the shared
directory. You should do this with a task and a after filter in your
deploy.rb file:

after “deploy:update_code”, “deploy:symlink”

task :symlink, :roles => :app do
run <<-CMD
rm -rf #{release_path}/public/images/users &&
ln -nfs #{shared_path}/users #{release_path}/public/images/users
&&
CMD
end

I’d watch out for the “rm -rf #{release_path}/public/images/users”
line. I think that would remove all your images.

Hi Tim & Freddy,

Thanks for the prompt and insightful replies. I’m glad I got it clear
that this IS how Capistrano is supposed to work and that I shouldn’t try
to fight it much.

I wouldn’t have even imagined I should have to symlink to get this to
work. I’ll give it a try and come back if I have any questions.

Thanks for the help!!!

-Tony

Tim McIntyre wrote:

I’d watch out for the “rm -rf #{release_path}/public/images/users”
line. I think that would remove all your images.

Hi Tim,

Thanks for the tip. I’ve been busy so I haven’t tried to do this just
yet but I’m sure it would remove the images. The idea is to move the
directory/contents to the shared folder prior to deploying with the
“deploy:symlink” task.

Thanks again for the tip, I’m sure a lot of people will be grateful for
that instead of finding their images gone (though nothing a simple,
rollback couldn’t fix) :slight_smile:

-Tony

Freddy A. wrote:

Hi Tony… the rm line is only there for the release_path directory
which either will have the symlink OR an empty directory that was
checked-out from git. If the developers wants a few “test” images in
git for testing you can do that but need to remove that when it is
deployed to prod before you create the symlink…

#{release_path} is the /releases/datestamp/ directory…

Thanks for that. Thankfully I already figured that out, but it’s good to
know, especially for others.

Personally I was able to get things setup properly with the help of all
of you!

Also, coincidentally, railscasts has released two screencasts which
relate to my this very question. It may help others who have had the
same issue:

http://media.railscasts.com/videos/133_capistrano_tasks.mov
http://media.railscasts.com/videos/134_paperclip.mov

Again, many thanks.

-Tony

Hi Tony… the rm line is only there for the release_path directory
which either will have the symlink OR an empty directory that was
checked-out from git. If the developers wants a few “test” images in
git for testing you can do that but need to remove that when it is
deployed to prod before you create the symlink…

#{release_path} is the /releases/datestamp/ directory…

But “#{release_path}/public/images/users” will still be symlinked to
“#{shared_path}/users #{release_path}/public/images/users” and the “r”
option will remove all files in that directory so I would just remove
the “r” option and you should be OK. No???

Tim McIntyre wrote:

But “#{release_path}/public/images/users” will still be symlinked to
“#{shared_path}/users #{release_path}/public/images/users” and the “r”
option will remove all files in that directory so I would just remove
the “r” option and you should be OK. No???

Maybe this makes some more sense:

In the deploy:symlink task (please notice that I just separated the run
commands):

# This deletes the users folder and contents that has been uploaded to 
the server when deployed (this will happen every deploy).
run "rm -rf #{release_path}/public/images/users"
#This reestablishes the users folder but as a symlink to the users 
folder in the shared directory
run "ln -nfs #{shared_path}/images #{release_path}/public/images"

So every time you deploy, you delete the users folder (that’s what the
rm -rf command does) that was uploaded to the latest release and then
you reestablish the symlink (this is what the ln -nfs command does).
Hope that makes sense.

-Tony

Jean-Marc (M2i3.com) wrote:

Hi Tony,

Look into Ryan B. Railscasts… there is one talking about
Capistrano (and his tricks when dealing with images and other “site
specific” data).

#133 Capistrano Tasks - RailsCasts

Jean-Marc
http://m2i3.com/blog/jean-marc

Hi Jean-Marc,

Thanks for the link. Coincidentally, I also linked to the same
screencast. I’m up and running just fine now but I’m sure others could
use it.

-Tony

Hi Tony,

Look into Ryan B. Railscasts… there is one talking about
Capistrano (and his tricks when dealing with images and other “site
specific” data).

Jean-Marc
http://m2i3.com/blog/jean-marc