Posted by Danger
29 days
ago
I’ve got one client for whom I’m building a Rails app and I
started it long before I knew anything about Capistrano. Mostly
things are pretty straightforward and all is working as it should -
but there are a couple of hangups.
Shared Resources
My site allows users to upload portraits of themselves. These
are kept right in the open in the public directory under a folder
named “portraits”. They can also upload films, documents, etc.
using the model Documents which stores its stuff in
./public/documents.
The first real hassle of converting to capistrano was dealing
with these because up until now I’ve kept them in the SVN
repository for fear of losing any data and pisisng off a user. With
the number of deployments I do I no longer want to put these files
in the repository but that would remove them from the site.
Capistrano does a fresh checkout each time it deploys and if
something’s not in SVN then it just plain doesn’t make it back into
the app.
Capistrano does allow the use of a shared folder located above
the live app directory. The trick is getting stuff into there and
making sure that capistrano can recognize it every time I
deploy.
My Solution
It turns out the Capistrano allows highly configurable
deployment options. All I needed to do was to move the folders out
of ./public and into shared
mv ./public/documents ../shared/
mv ./public/portraits ../shared/
then edit my deploy script so it links those folders up into
each new public directory
task :after_update_code do
%w{documents portraits}.each do |share|
run "ln -s #{shared_path}/#{share} #{release_path}/public/#{share}"
end
end
It didn’t take long for me to realize that I needed to do the
same with any other file that wouldn’t be in SVN. For me, this is
my database.yml file and cofig/environment.rb file
task :after_update_code do
%w{documents portraits}.each do |share|
run "ln -s #{shared_path}/#{share} #{release_path}/public/#{share}"
end
%w{database.yml environment.rb}.each do |config|
run "ln -nfs #{shared_path}/#{config} #{release_path}/config/#{config}"
end
end
There’s actually a number of tasks that you could add this code
to. You could put it right into the deploy task by using task
:deploy or you could make it run immediately after deploy is
run by task :after_deploy
So far so good with Capistrano.