mina-deploy / mina

Blazing fast deployer and server automation tool
https://rubygems.org/gems/mina
Other
4.35k stars 491 forks source link

Fixes 'No Rakefile found' for rails:{db_create, db_migrate, db_rollback, assetts_precompile} commands #524 #525

Closed ianheggie closed 6 years ago

ianheggie commented 7 years ago

Fixes issue #524 - 'No Rakefile found' for rails:{db_create, db_migrate, db_rollback, assetts_precompile} commands

I also clarified ssh_keyscan_domain description using style of ssh_keyscan_repo command

bartimaeus commented 6 years ago

Super helpful. Thanks @ianheggie !

d4be4st commented 6 years ago

I will not merge this as rails:db_migrate and rails:assets_precompile are meant to be used only in deploy scripts.

With these changes you broke the deploy do part of the script. As now migration will run against current folder which has the old code and not against new release folder.

to run db_migrate and assets_precomplie use mina 'rake[db:migrate]' I agree this is missing from the documentation.

bartimaeus commented 6 years ago

Thanks for the feedback @d4be4st. I think what would work best for me is if there was a way to expose the build_path.

Here is how I've updated my deploy.rb:

set :build_path, "#{fetch(:deploy_to)}/tmp/build#{"$((`ls -1t #{fetch(:deploy_to)}/tmp | head -n 1`))"}"

...

desc "Deploys the current version to the server."
task deploy: :environment do
  deploy do
    invoke :'sidekiq:quiet'
    invoke :'git:clone'
    invoke :'deploy:link_shared_paths'
    invoke :'bundle:install'
    invoke :'myapp:db_migrate'
    invoke :'myapp:assets_precompile'

    on :launch do
      ...
    end
  end
end

...

namespace :myapp do
  # Monkey patching mina's rails tasks
  # https://github.com/mina-deploy/mina/pull/525
  desc 'Migrate database'
  task :db_migrate do
    set :execution_mode, :exec
    in_path fetch(:build_path) do
      if fetch(:force_migrate)
        comment %{Migrating database}
        command %{#{fetch(:rake)} db:migrate}
      else
        command check_for_changes_script(
          at: fetch(:migration_dirs),
          skip: %{echo "-----> DB migrations unchanged; skipping DB migration"},
          changed: %{echo "-----> Migrating database"
            #{echo_cmd("#{fetch(:rake)} db:migrate")}}
        ), quiet: true
      end
    end
  end

  ...
end

The above gives me what I need without the missing Rakefile error that I get when using

invoke :'rails:db_migrate'

I can run migrations before or after I deploy like you suggested. I prefer to precompile the assets along with the deploy.

I know currently the only place I see the build_path is in https://github.com/mina-deploy/mina/blob/master/data/deploy.sh.erb#L35. I'm just wondering if there is a way to expose this as a variable so we can fix the rails tasks? Thanks!

d4be4st commented 6 years ago

I think here @ianheggie and you have different problems.

Based on #524 he wants to run mina rails:db_migrate from the command line to migrate the database manually, not in the deploy script. To that I answered that rails:* tasks are not meant to be run on their own outside deploy do block.

@bartimaeus your problem is that somehow rails:db_migrate run inside the deploy do block is throwing Rakefile not found error? From your code that shouldn't happen without the modifications. Have you tried removing :environment after the task :deploy ? That is not necessary anymore

Also here is some more information about deploy script (which I will add to documentation) In deploy do block there are a couple of stages. The commands in default stage (not within any on() do blocks) are run inside build path (tmp/random_string) The commands in build stage are run after the build path has been moved to releases folder and are run inside release path The commands in launch stage are run after the current is symlinked to the release folder and are run in current path.

bartimaeus commented 6 years ago

Thanks @d4be4st for your response. I just removed the environment from deploy and switched the invoke back rails:db_migrate. I'm still getting the same error. Here's the error:

       ...
       Files /srv/www/myapp/current/db/migrate/20170914220528_migration_61.rb and ./db/migrate/20170914220528_migration_61.rb differ
       Files /srv/www/myapp/current/db/migrate/20170914220857_migration_62.rb and ./db/migrate/20170914220857_migration_62.rb differ
       Files /srv/www/myapp/current/db/migrate/20170916143033_migration_63.rb and ./db/migrate/20170916143033_migration_63.rb differ
       Files /srv/www/myapp/current/db/migrate/20170918212507_migration_64.rb and ./db/migrate/20170918212507_migration_64.rb differ
       Files /srv/www/myapp/current/db/migrate/20170918213019_migration_65.rb and ./db/migrate/20170918213019_migration_65.rb differ
-----> Migrating database
       rake aborted!
       No Rakefile found (looking for: rakefile, Rakefile, rakefile.rb, Rakefile.rb)
       /usr/local/bin/bundle:22:in `load'
       /usr/local/bin/bundle:22:in `<main>'
       (See full trace by running task with --trace)
 !     ERROR: Deploy failed.
-----> Cleaning up build
       Unlinking current
       OK
       Connection to myapp.com closed.

 !     Run Error

I'm also using mina-multistage. I can remove that to help isolate things.

Thanks for the explanation on the order of things! From what you are saying these rails tasks are really running on the /releases directory. I could make a release_path pointing to the /releases/:current_release instead of the /tmp/build-:build_number.

But I think I really need to determine where these tasks are trying to run when they can't find the Rakefile. I'll see if I can figure that out. Thanks!

bartimaeus commented 6 years ago

@d4be4st I don't know why, but it looks like it's trying to run the rails:db_migrate in the shared directory:

desc 'Migrate database'
task :db_migrate do
  set :execution_mode, :exec
  # in_path fetch(:build_path) do
    comment %{Current Working Directory}
    command %{pwd}

    if fetch(:force_migrate)
      comment %{Migrating database}
      command %{#{fetch(:rake)} db:migrate}
    else
      command check_for_changes_script(
        at: fetch(:migration_dirs),
        skip: %{echo "-----> DB migrations unchanged; skipping DB migration"},
        changed: %{echo "-----> Migrating database"
          #{echo_cmd("#{fetch(:rake)} db:migrate")}}
      ), quiet: true
    end
  # end
end
-----> Current Working Directory
/srv/www/myapp/shared
bartimaeus commented 6 years ago

@d4be4st I know what's going on and it is completely user error! I have a custom task that runs before and changes the directory to /shared so that I can reset ownership of my log files. I'm updating that task to not change directories. I'm sorry for the trouble.

rsol11 commented 6 years ago

dealt with same error, using rake db:migrate worked for me.

d4be4st commented 6 years ago

In version 1.2.0 I have added an ensure! clause which removes the option to run rails:db_migrate and rails:assets_precompile alone :)

Sibghataziz commented 3 years ago

for me.

how that worked??