Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Capistrano v3 not able to cleanup old releases

Tags:

capistrano

Since I'm running my rails app as root, it creates files that are owned by root in the tmp directory. Because of this

cap production deploy:cleanup

can't remove old releases because it is not run as root.

I've looked at the capistrano v3 code, but I don't see a way to run the cleanup command as root. Is this option missing or is this problem occurring because I'm doing something wrong in another place of the deployment flow.

I start the app as root because I need to bind to port 80.

like image 907
Karel Avatar asked Oct 23 '13 15:10

Karel


3 Answers

What you can also do is triggering a task just before cleaning up the old release :

namespace :deploy do

  before :cleanup, :cleanup_permissions

  desc 'Set permissions on old releases before cleanup'
  task :cleanup_permissions do
    on release_roles :all do |host|
      releases = capture(:ls, '-x', releases_path).split
      if releases.count >= fetch(:keep_releases)
        info "Cleaning permissions on old releases"
        directories = (releases - releases.last(1))
        if directories.any?
          directories.each do |release|
            within releases_path.join(release) do
                execute :sudo, :chown, '-R', 'deployuser', 'path/to/your/files/writtend/by/root'
            end
          end
        else
          info t(:no_old_releases, host: host.to_s, keep_releases: fetch(:keep_releases))
        end
      end
    end
  end

end

Note that you'll need to give your deployment user the right to execute this specific sudo command (with a sudoers definition file.

like image 65
foobar Avatar answered Nov 09 '22 00:11

foobar


I've looked at the capistrano v3 code, but I don't see a way to run the cleanup command as root. Is this option missing or is this problem occurring because I'm doing something wrong in another place of the deployment flow.

There is no secret sauce in Capistrano, we rely on you having correctly set up the permissions for your deploy user as documented at http://www.capistranorb.com/

Removing directories requires write permissions on the parent directory, that is to say, given the following directory structure:

/var/www/releases/
              \- 20131015180000
              \- 20131015181500
              \- 20131015183000

You need write permission on the /var/www/releases/ directory, as the list of files and directory in that directory, is stored in the directory.

From a similar StackSverflow question:

In UNIX and Linux, the ability to remove a file is not determined by the access bits of that file. It is determined by the access bits of the directory which contains the file.

From the Wikipedia article on Unix File Permissions:

The write permission grants the ability to modify a file. When set for a directory, this permission grants the ability to modify entries in the directory. This includes creating files, deleting files, and renaming files.

like image 27
Lee Hambley Avatar answered Nov 09 '22 01:11

Lee Hambley


One of the things you may want to do is to create a group called app or web on your linux box and add root and the deploy user to the same group. Then, as part of your deployment, chmod the release_path permissions to g+s which will ensure that any new files created by root user are group writable.

You should then be able to remove the old folders as deploy user.

like image 41
Coffee Bite Avatar answered Nov 09 '22 01:11

Coffee Bite