Program Tip

Rails 3 및 Heroku : 푸시시 자동으로 "rake db : migrate"?

programtip 2020. 11. 30. 19:47
반응형

Rails 3 및 Heroku : 푸시시 자동으로 "rake db : migrate"?


내 heroku 푸시 / 배포 프로세스에 약간의 성가심이 있습니다. 그렇지 않으면 발견하고 사용하는 것이 즐거웠습니다.

내 앱에 새 마이그레이션을 추가하면 heroku 서버로 가져올 수있는 유일한 방법은 heroku 리모컨으로 푸시하는 것입니다. 이렇게하면 업로드되고 앱이 다시 시작됩니다. 내가해야 할 수 있도록하지만, 마이그레이션을 실행하지 않습니다 heroku rake db:migrate --app myapp다음 heroku restart --app myapp. 그 동안 마이그레이션을 실행하지 않았고 코드가 마이그레이션에서 필드 / 테이블 등을 참조하기 때문에 앱이 손상되었습니다.

배포 프로세스의 rake db:migrate일부로 자동으로 실행되도록 배포 프로세스를 변경하는 방법이 있어야 하지만 해결할 수 없습니다.

내가 heroku cpanel에 설정 한 것입니까? 명령 줄에서 heroku로 전달하는 옵션입니까? 자식 후크입니까? 누구든지 나를 바로 잡을 수 있습니까? 고마워, 최대


다음은 모든 것을 한 줄로 묶는 레이크 작업입니다 (롤백도 지원함).

https://gist.github.com/362873

당신은 여전히 당신의 상사의 데모의 상단에 배포 바람 수도 있지만, 적어도 당신은 사이의 시간 입력 낭비하지 않는 git push과를 rake db:migrate.


이제 Heroku는 "출시 단계"기능의 일부로이를 처리 할 수 ​​있습니다.

당신이라는 프로세스를 추가 할 수 있습니다 release당신에게를 Procfile하고는 각각의 모든 배포시에 실행됩니다.

Rails> = 5 예제

release: bundle exec rails db:migrate

Rails <5 예

release: bundle exec rake db:migrate


이 간단한 명령 체인 솔루션은 어떻습니까?

git push heroku master && heroku run rake db:migrate

첫 번째 작업이 성공적으로 완료되는 즉시 마이그레이션이 자동으로 실행됩니다. 팁적으로 1-2 초 이하의 지연입니다.


배포시 Heroku가 자동으로 실행되도록 하는 사용자 지정 빌드 팩만들었습니다 rake db:migrate. Heroku의 기본 Ruby 빌드 팩의 포크 일 뿐이지 만 rake db:migrate작업이 추가되었습니다.

앱에서 사용하려면 다음을 수행하십시오.

heroku config:set BUILDPACK_URL=https://github.com/dtao/rake-db-migrate-buildpack

또한 작동하려면 user-env-compile Heroku Labs 기능 을 활성화해야 합니다. 방법은 다음과 같습니다.

heroku labs:enable user-env-compile

이것이 작동한다는 내 증거는 다음과 같습니다.

rake db : Heroku 배포시 마이그레이션


스키마 커밋 (마이그레이션 등) 커밋을 코드 커밋 (모델, 유효성 검사 등)에서 분리 해 볼 수 있습니다.

(다음은 대부분의 사용 사례에 대해 설명 했으므로 마이그레이션 변경 사항이 파괴적이지 않다고 가정합니다.)

배포 프로세스는 다음과 같습니다.

  1. Heroku에 스키마 변경 사항 푸시
  2. 마이그레이션
  3. Heroku에 애플리케이션 코드 푸시

이것은 물론 최적의 방법이지만 설명한 상황에서 다운 타임을 피하는 효과적인 방법입니다. 앱이 동적 필드에 대한 코드를 수신 할 때까지 DB는 이미 마이그레이션 된 것입니다.

(물론 가장 간단한 해결책은 상사가 점심을 먹으러 나가는 동안 간단히 밀어서 마이그레이션하는 것입니다 ;-D)

그렇지 않으면 스키마 수정이 자동으로 수행 되더라도 마이그레이션이 실행되기 직전에 요청이 통과 될 위험이 있습니다.


저와 같은 인터넷 검색을하는 사람들을 위해 여기에 평범한 해결책을 제시하고 싶습니다.

저는 Rails 4를 사용하고 있으며 heroku 배포에 간단한 Rake 작업을 추가해야했습니다. github에서 'deploy to heroku'버튼을 사용하고 있기 때문에 배포 직후에 "heroku run ..."을 실행할 기회가 없습니다.

내가 한 일 : heroku에 배포하는 동안 자동으로 실행되는 표준 Rake Task 'assets : clean'확장했습니다 . 작업은 여전히 ​​정상적으로 실행되지만 끝 부분에 내 물건을 첨부했습니다. 이것은 'enhance' 방법으로 수행됩니다. 아래 예에서는 대부분의 사람들이 원하는 것일 수 있으므로 db : migrate를 추가합니다.

# in lib/tasks/assets_clean_enhance.rake
Rake::Task['assets:clean'].enhance do
  Rake::Task['db:migrate'].invoke
end

나는 이것이 완벽한 해결책이 아니라는 것을 인정합니다. 그러나 heroku Ruby Buildpack은 여전히 ​​다른 방법을 지원하지 않습니다. 그리고 내 자신의 빌드 백을 작성하는 것은 너무 간단한 일에 약간의 과잉 인 것처럼 보였습니다.


I use a rake task to put the app in maintenance mode, push, migrate and move it off maintenance mode.


I wrote SmartMigrate buildpack which is a simple Heroku buildpack to warn of pending migrations after a ruby build whenever new migrations detected. This buildpack is intended to be part of a Multipack that has a preceding Ruby buildpack.

With due respect to other solutions here, this buildpack has 3 advantages over those:

  1. No need for maintenance mode
  2. No need for out-dated ruby buildpack forks that just insert the migration at the end
  3. No need to run migrations ALL THE TIME, a warning is only displayed if new migrations are detected since the last deployment

I think David Sulc's approach is the only one which ensures that you avoid requests getting through while the app is in a broken state.

It is a bit of a pain, but may be necessary in some circumstances.

As he stated, it does require that the db migrations are non-destructive.

However, it can be difficult to push your migrations and schema changes prior to the rest of the code, as the obvious approach ('git push heroku {revnum}') relies on you having checked the migrations in before the rest of the code.

If you haven't done that, it's still possible to do this using a temporary branch:

  • Create a branch, based at the git revision that you most recently pushed to heroku:

    git branch <branchname> <revnum-or-tag>
    
  • Check out that branch:

    git checkout <branchname>
    
  • If your db migration commits only contained migrations, and no code changes, cherry-pick the commits that contain the database changes:

    git cherry-pick <revnum1> <revnum2>...
    
  • If you commited your db changes in revisions which also contained code changes, you can use 'git cherry-pick -n' which won't automatically commit; use 'git reset HEAD ' to remove the files that aren't db changes from the set of things that are going to be commited. Once you've got just the db changes, commit them in your temporary branch.

    git cherry-pick -n <revnum1> <revnum2>...
    git reset HEAD <everything that's modified except db/>
    git status
    ... check that everything looks ok ...
    git commit
    
  • Push this temporary branch to heroku (ideally to a staging app to check that you've got it right, since avoiding downtime is the whole point of jumping through these hoops)

    git push heroku <branchname>:master
    
  • Run the migrations

    heroku run rake db:migrate
    
  • At this point, you might think that you could just push 'master' to heroku to get the code changes across. However, you can't, as it isn't a fast-forward merge. The way to proceed is to merge the remainder of 'master' into your temporary branch, then merge it back to master, which recombines the commit histories of the two branches:

    git checkout <branchname>
    git merge master
    git diff <branchname> master
    ... shouldn't show any differences, but just check to be careful ...
    git checkout master
    git merge <branchname>
    
  • Now you can push master to heroku as normal, which will get the rest of your code changes across.

In the second-to-last step, I'm not 100% sure whether merging master to {branchname} is necessary. Doing it that way should ensure that a 'fast-forward' merge is done, which keeps git happy when you push to heroku, but it might be possible to get the same result by just merging {branchname} to master without that step.

물론 '마스터'를 사용하지 않는 경우 위의 관련 위치에서 적절한 지점 이름으로 대체하십시오.


나는 한동안 배포 도구로 heroku_san gem을 사용하고 있습니다. 푸시 + 마이그레이션을위한 작고 집중적 인 도구입니다. 다른 기능 (예 : 콘솔)에 쉽게 액세스 할 수있는 다른 레이크 명령을 추가합니다. 데이터베이스 마이그레이션을 기억할 필요가없는 것 외에도 내가 가장 좋아하는 기능은 Heroku 구성 파일입니다. 따라서 모든 서버 (프로덕션, 스테이징, 플레이 그라운드 4, shirley)의 이름을 원하는대로 지정할 수 있으며 머리 속에 그대로 유지할 수 있습니다.

참고 URL : https://stackoverflow.com/questions/5966290/rails-3-and-heroku-automatically-rake-dbmigrate-on-push

반응형