Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between current_path vs release_path in Capistrano?

What is the difference between the current_path and release_path path variables in Capistrano, as in

task :path do
    on roles :app do
        puts "Release path: #{release_path}"
        puts "Current path: #{current_path}"
    end
end

Does the current_path always contain the most up to date code?

like image 894
Derek Avatar asked Jun 18 '14 00:06

Derek


2 Answers

Since this hasn't got a satisfactory answer I'll add what I've found out.

Looking at this blog post we can see where path variables point:

current_path – path of deploy_to + current_dir (e.g. /u/apps/example/current ) release_path – path of releases_path + release_name (e.g. /u/apps/example/releases/20100624000000 )

So to answer your question: yes, current_path does point to the most up to date code (the most recent deployment). It points here through a symlink to the latest release directory. Take a look at the capistrano structure if you're interested in what all the folders mean.

The difference with release_path is that it points to the path of the release you are currently deploying. This is useful if you want to reference a file in your repo during the deployment, such as run a script.

However, release_path is only updated during the deploy:starting namespace, at any other time, it's exactly the same as current_path. See this github isssue for more information.

My particular use case was I wanted to run a composer install using the composer.phar that's located in the root of my repo. So, following the documentation I did this:

SSHKit.config.command_map[:composer] = "#{release_path}/composer.phar"

But that didn't work, because at the time this is defined, release_path still points to the current_path.

The workaround I found for this comes from this answer and it's to evaluate the release_path lazily:

SSHKit.config.command_map[:composer] = lambda { "#{release_path}/" + fetch(:src_path) + "/composer.phar" }

So as long as the variable is accessed after the deploy:starting namespace, release_path will be set as we expect it.

like image 104
Yep_It's_Me Avatar answered Nov 10 '22 22:11

Yep_It's_Me


I feel compelled to answer here to clarify some things about current_path and release_path

Capistrano works in stages, so for the sake of this answer I will describe the important stages as follows.

Stage 1: before current_dir is relinked

In my version of Capistrano that I'm looking at, the "linking" of the 'current' directory occurs in task

deploy:create_symlink

But you should check your capistrano setup for the exact taskname. It is easy to see in the capistrano terminal output, just look for the sshkit call to "ln -s".

PRIOR to this step running:

  • current_dir is the path to the symlink, pointing to the last directory creating by the last [not current] run of capistrano. NOT REALLY CURRENT IS IT? Or not for long anyway.....
  • release_dir is the most recently checked out version created in this run of capistrano.

So take special note, anything working in current_dir at this stage is working in the wrong place.

Stage 2: after current_dir is relinked

AFTER the symlinking step runs [it will run "ln -s" on the release_dir, linking to current_dir (its not really a directory, its a link. Anyway.....)]

  • current_dir is the path to the symlink, pointing to the release_dir. Now it really is current.
  • release_dir is the most recently checked out version created in this run of capistrano.

At this stage, it no longer matters whether your tasks are working in release_dir or current_dir, they are pointing at the "same" files on the disk.

Why is this important?

Working before the symlink is changed is typically preferable because, if there's a failure, nothing is disrupted. At this stage, you must use release_dir.

If you are working after the symlink has changed, you could still use release_dir. If you are using current_dir, ask yourself why not use release_dir, and ask yourself why you have these build steps running after the symbolic link changes. If you can move them before the symlink changes, you should. In the setup I am looking at, I do this with

before "deploy:create_symlink",  "a_task_that_must_use_release_dir"

If you are working in current_dir after the symlink changes, and before your webserver restarts, and you encounter a problem, you may have trashed your environment.

Does this make current_dir evil? I don't think so, with great power comes great responsibility.

like image 33
Bret Weinraub Avatar answered Nov 10 '22 22:11

Bret Weinraub