Git を使用したデプロイ
この記事の英語版に更新があります。ご覧の翻訳には含まれていない変更点があるかもしれません。
最終更新日 2023年05月04日(木)
Table of Contents
Heroku は、ポピュラーな VCS (バージョン管理システム) である Git でアプリのデプロイを管理します。Heroku にコードをデプロイするには、Git の専門家である必要はありませんが、基本を学習しておくと役立ちます。
この記事では、Git および Heroku Git リモートを使用してコードをデプロイする方法について説明します。GitHub でコードをすでに追跡している場合、この記事の手順に従う代わりに、Heroku GitHub 統合でデプロイすることを検討してください。
前提条件: Git および Heroku CLI のインストール
Git でデプロイするには、Git および Heroku CLI がインストールされている必要があります。
Heroku にアプリをデプロイするには、ローカル Git リポジトリを初期化し、アプリケーションコードをそれにコミットします。
次の例では、example-app
ディレクトリで稼働するアプリ用の Git リポジトリの初期化について説明します。
$ cd example-app
$ git init
Initialized empty Git repository in .git/
$ git add .
$ git commit -m "My first commit"
Created initial commit 5df2d09: My first commit
44 files changed, 8393 insertions(+), 0 deletions(-)
create mode 100644 README
create mode 100644 Procfile
create mode 100644 app/controllers/source_file
...
アプリのルートディレクトリで Git リポジトリを初期化します。アプリがリポジトリのサブディレクトリにある場合、アプリは Heroku にプッシュされるときに実行しません。
これで、ローカル Git リポジトリ内のアプリのコードを追跡します。リモートサーバーにはまだ存在していません。
Heroku リモートの作成
Git リモートは、他のサーバー上で稼働するリポジトリのバージョンです。アプリに関連付けられた、Heroku でホストされる特別なリモートにコードをプッシュすることにより、アプリをデプロイします。
Heroku Git はデプロイのための便宜的なものであり、安定した Git リポジトリのためのものではありません。コードベースを追跡するには、GitHub (推奨)、GitLab、BitBucket などのバージョン管理システムを使用してください。
新規アプリの場合
heroku create
CLI コマンドは、関連した空の Git リポジトリとともに新しい空のアプリケーションを Heroku 上に作成します。アプリのルートディレクトリからこのコマンドを実行した場合、空の Heroku Git リポジトリがローカルリポジトリのリモートとして自動的に設定されます。
$ heroku create -a example-app
Creating app... done, ⬢ example-app
https://thawing-inlet-61413.herokuapp.com/ | https://git.heroku.com/example-app.git
git remote
コマンドを使用して、heroku
という名前のリモートがアプリに合わせて設定されていることを確認できます。
$ git remote -v
heroku https://git.heroku.com/example-app.git (fetch)
heroku https://git.heroku.com/example-app.git (push)
既存アプリの場合
heroku git:remote
コマンドを使用して、ローカルリポジトリにリモートを追加します。必要なものは、Heroku アプリの名前だけです。
$ heroku git:remote -a example-app
set git remote heroku to https://git.heroku.com/example-app.git
リモート名の変更
デフォルトで、Heroku CLI は、アプリ heroku
に対して作成するすべての Heroku リモートに名前を付けます。git remote rename
コマンドで、リモートの名前を変更できます。たとえば、heroku
を heroku-staging
に名前変更するには、次のようにします。
$ git remote rename heroku heroku-staging
同じコードベースを使用する複数の Heroku アプリがある場合、Heroku リモートの名前を変更しておくと便利です。この場合、各 Heroku アプリには、ローカルリポジトリに独自のリモートがあります。
Dev Center のドキュメントでは、アプリには heroku
という名前の単一の Heroku リモートがあると想定しています。
コードのデプロイ
アプリを Heroku にデプロイするには。次のように git push
コマンドを使用して、ローカルリポジトリのメインブランチから heroku
リモートにコードをプッシュします。次に例を示します。
$ git push heroku main
Initializing repository, done.
updating 'refs/heads/main'
...
最新のコミット済みバージョンのコードを Heroku にデプロイしようとする場合はいつでも、この同じコマンドを使用します。
Heroku は、リモートのマスターまたはメインブランチにプッシュするコードだけをデプロイします。heroku
リモートの別のブランチにコードをプッシュしても効果はありません。
メイン以外のブランチからのデプロイ
ローカルリポジトリの非 main
ブランチ (testbranch
など) から Heroku にコードをデプロイするには、次の構文を使用して、リモートの main
ブランチにプッシュされるようにします。
$ git push heroku testbranch:main
この方法では、他の多くの依存関係の解決方針に加え、Git サブモジュールに依存するアプリケーションがサポートされます。
Heroku は git lfs をサポートしません。この方法を使用すると、プッシュに失敗する可能性があります。
複数のリモートおよび環境
本番環境へのデプロイに使用した同じテクニックを、Heroku でのステージングアプリケーションにアプリケーションの開発ブランチをデプロイする場合にも使用できます。詳細は、「Managing Multiple Environments for an App」(アプリの複数の環境の管理) を参照してください。
ビルドプロセスからの分離
git push
で Heroku デプロイを開始した後、Ctrl + C を押して、結果のビルドプロセスから分離できます。分離によってビルドもデプロイもキャンセルされることはありません。ビルドはバックグラウンドで続行し、完了するとすぐに、新しいリリースを作成します。
同時デプロイの動作
同じアプリの以前のデプロイが完了する前にデプロイを開始することができます。たとえば、アプリの 2 人の共同作業者がほぼ同時に別々のコミットを heroku
リモートにプッシュするとします。
この状況が発生した場合、異なるバージョンのアプリが、それぞれのビルドが完了した順序で Heroku にデプロイされます。この順序は、プッシュが行われた順序とは異なる場合があります。
たとえば、A と B の 2 つのビルドを考えてみます。ビルド B がビルド A の後に開始したが、その前に終了した場合、Heroku はビルド B を最初にデプロイします。その後、やがてビルド A が完了すると、Heroku はこれをデプロイして、ビルド B を置き換えます。
HTTP Git 認証
Heroku では、その Git トランスポートとして HTTPS を使用します (SSH トランスポートはサポートされていません)。Heroku CLI は自動的に証明書を heroku login
の .netrc
ファイルに配置します。Git クライアントは、HTTP(S) リモートとやり取りするときに cURL を使用し、cURL は .netrc
ファイルの証明書を使用します。詳細については、CLI 認証の記事を参照してください。
Heroku ユーザー名 (メール) とパスワードを使用して、Heroku HTTPS Git エンドポイントで認証することはできません。Heroku HTTPS Git エンドポイントは、API キーベースの HTTP Basic 認証のみを受け入れます。このセクションでの説明どおり、API キーを使用してください。
正しくない証明書で Git サービスを認証した場合、次のエラーが表示されます。
remote: ! WARNING:
remote: ! Do not authenticate with username and password using git.
remote: ! Run `heroku login` to update your credentials, then retry the git command.
remote: ! See documentation for details: https://devcenter.heroku.com/articles/git#http-git-authentication
EGit や Tower など他の Git クライアントを使用している場合、ユーザー名に空の文字列を、パスワードにアカウント API キーを使用するように設定します。API キーは、CLI およびダッシュボードで使用できます。
Git リポジトリのリセット
アプリの Heroku Git リポジトリをリセットまたはパージするには、heroku-repo CLI プラグインを使用します。
$ heroku plugins:install heroku-repo
$ heroku repo:reset --app appname
Git リポジトリをリセットすると、すべてのソースコードと Git 履歴が削除されるため、リポジトリの別のコピーを保持していることを先に確認してください。
リポジトリのサイズを小さく維持する
リポジトリからの HEAD
のチェックアウトの圧縮されていないサイズは、復元されたサブモジュールのサイズと合わせて 1 GB 以下にする必要があります。
600 MB を超える大きいリポジトリをデプロイすることは推奨されません。タイムアウトが生じたり、プッシュが全般的に遅くなることがあります。heroku apps:info
を実行すると、リポジトリサイズが表示されます。
リポジトリが大きくなる一般的な原因としては、リポジトリにチェックインされるバイナリファイルや、絶えず変化する開発ログが挙げられます。偶然コミットされたファイルの削除は、git filter-branch で行えます。ただし、実行後は --force
オプションで変更をプッシュする必要があり、これにはチーム内の調整が必要になります。
ローカルでリポジトリのサイズを削減した後、アプリの Git リポジトリをリセットしてから、これを Heroku に再びプッシュする必要があります。
制限
Git サービスを保護するため、Heroku は、Git リポジトリの使用と内容のサイズに一定の制限を課しています。
Heroku では、ユーザーは、1 時間あたり、ユーザーごと、アプリごとに 75 件の Git リクエストの繰り返しに制限されます。この限度に達すると、Heroku ではリクエストレベルが数分間限度を下回るまで Git が拒否されます。次のようなエラーメッセージが表示されます。
! Too many requests for this Git repo. Please try again later.
この限度に達した場合、Git リポジトリをポーリングする自動化されたプロセスまたはスクリプトがないことを確認します。
さらに、リポジトリからの HEAD
のチェックアウトの圧縮されていないサイズは、復元されたサブモジュールのサイズと合わせて 1 GB 以下にする必要があります。
Subversion またはその他のリビジョン管理システムで追跡されたコードをデプロイする
Git はリビジョン管理に使用できる最善の選択肢の 1 つですが、現在のリビジョン管理システムの使用を停止する必要はありません。Git は、他のツールと併存する純粋な開発メカニズムとして使用できます。
トピックに関する記事で .gitignore
の詳細を参照できます。
たとえば、Subversion を使用している場合は、 前提条件セクションに記載されているように Git リポジトリを初期化します。続いて、.gitignore
ファイルを追加して、Git に Subversion ディレクトリを無視するように指示します。
$ git init
$ echo .svn > .gitignore
$ git add .
$ git commit -m "using git for heroku deployment"
次に Git を無視するように Subversion に指示します。
$ svn propset svn:ignore .git .
property 'svn:ignore' set on '.'
$ svn commit -m "ignoring git folder (git is used for heroku deployment)"
他の開発者のプッシュとの競合を回避するために、-f
(強制フラグ) を使用することをお勧めします。リビジョン管理には Git を使用していませんが、トランスポートとしてのみ使用しているので、強制フラグを使用する方法が合理的です。
Heroku にデプロイするたびに、次のように実行します。
$ git add -A
$ git commit -m "commit for deploy to heroku"
...
$ git push -f heroku
追加リソース
- Git on Rails は、Git を使用して Rails アプリを追跡するための一般的な方法を示します。
- Git cheat sheet (Git 早見表)
- Git - SVN Crash Course (Git - SVN クラッシュコース)
- Pro Git 書籍は、Git のすべてを取り扱う優れたリソースです。