I've added new HDD to the server and need to use it to save all users info, so I need to move public directory to new HDD.
I don't know what is the best approach in my case, but I decided to change the public directory to be symbolic link pointing to new HDD path.
Based on that I created the below capistrano task
to run after deploy:
# I'm using capistrano 3.1
namespace :public_to_symbolic do
desc 'Change public directory to symbolic link pointing to other Hdd'
task :change do
on roles(:app) do
is_directory = File.directory?("#{release_path}/public")
is_symbolic_link = File.symlink?("#{release_path}/public")
is_new_directory_exist = File.directory?('/mnt/newhdd/public')
can_change = is_directory && !is_symbolic_link && is_new_directory_exist
puts "is_directory : #{is_directory}" # prints false
puts "is_symbolic_link : #{is_symbolic_link}" # prints false
puts "is_new_directory_exist : #{is_new_directory_exist}" # prints false
puts "can_change: #{can_change}" # prints false
puts "release_path: #{release_path}" # prints /var/www/myapp/releases/20180305112922
if can_change
puts 'Changing public directory to symbolic link'
execute "mv #{release_path}/public #{release_path}/public_linked"
execute "ln -s /mnt/newhdd/public #{release_path}/public"
execute "rm -rf #{release_path}/public_linked"
end
end
end
end
after 'deploy', 'public_to_symbolic:change'
So, as commented, is_directory
, is_symbolic_link
and is_new_directory_exist
are all returns false
, but when I'm doing the same check (i.e File.directory?("#{Rails.root}/public")
or File.directory?("/var/www/myapp/current/public")
) using Rails console on deployment server, I'm getting true
and I'm able to see the public directory!
To avoid this issue I tried also to use current_path
instead of release_path
but still same results.
I have two questions:
is_directory
and is_new_directory_exist
are always false
while task is running?All suggestions are welcome
All Ruby methods that you use in your Capistrano tasks run on your local machine.
For example:
File.directory?
File.symlink?
These are always evaluated on your local filesystem. Capistrano never runs Ruby code on the remote server. These methods always return false
for you because they are trying to find e.g. "#{release_path}/public"
on your local computer, which of course does not exist.
To run code on the server, the tools available to you are Capistrano's test
and execute
methods. These take in a command string that is executed remotely via SSH.
If you want to test if a remote path is a directory, you cannot use Ruby; you have to use something that can be run in a remote shell. Here is one way to test if a path is a directory, for example:
is_directory = test("[ -d #{release_path}/public ]")
Likewise, to test if a path is a symlink:
is_symbolic_link = test("[ -h #{release_path}/public ]")