序論: CI/CDと自動デプロイの重要性

効率的な開発ワークフローのための自動デプロイ、すなわちCI/CD(Continuous Integration/Continuous Delivery)は、もはや選択の問題ではなく必須となっています。コードをGitHubにプッシュ(Push)した際に、ビルド・テスト・デプロイのプロセスが自動的に行われるならば、開発生産性は大きく向上するでしょう。

そのような自動デプロイを実装する方法はいくつかありますが、代表的なものとしては、GitHub自体が提供する GitHub Actions を活用する方法と、GitHubの Webhook 機能を利用してデプロイロジックを直接実装する方法があります。

なぜGitHub Actionsの代わりに直接Webhookを実装する必要があるのか?

GitHubの猫がWebhookの紙飛行機をTuxに飛ばすシーン

GitHub Actionsは確かに強力で便利なCI/CDツールです。複雑なワークフローをYAMLファイルの数行で定義し、さまざまなアクションマーケットプレイスを通じてビルド、テスト、デプロイなど多くのプロセスを自動化できます。ほとんどのプロジェクトにおいてGitHub Actionsは素晴らしい選択肢であることは否定できません。

しかし、すべての場合においてGitHub Actionsが最適な選択であるわけではありません。特に次のような状況にある開発者にとっては、GitHub Webhookを利用した直接実装方法の方がはるかに魅力的かもしれません。

  • コストに敏感な個人開発者または小規模チーム: GitHub Actionsは公開リポジトリの場合、ほぼ無制限の無料で利用できますが、非公開リポジトリの場合は一定量の無料枠(minutesおよびstorage)を超えると課金されます。どんなに少額でも予期しないコストが発生する可能性を完全に排除したいのであれば、直接実装が解決策です。

  • Raspberry Pi 5などの独自のステージングサーバーを運営中の開発者: すでに物理サーバー(VPS、クラウドインスタンスを含む)を保有しているのなら、わざわざGitHubの仮想環境(Runner)を借りる必要はなく、独自サーバーのリソースを最大限活用するのが効率的です。自分のサーバーで直接コードを受け取ってデプロイすることがコスト効率的であり、リソース利用の観点でも有利です。

  • デプロイロジックに対する完全な制御と自由を求める開発者: GitHub Actionsは定型化されたワークフローとアクションを使用しますが、直接Webhookを実装すればデプロイスクリプトのすべての部分を自分の思い通りに設計して制御できます。特定の環境に特化した複雑なカスタムロジックや、既存のパイプラインとの完璧な統合が必要な際に強みを発揮します。

このシリーズでは、まさにそのような方々のために、GitHub Webhookを活用して 自サーバーに直接デプロイロジックを実装する方法 を詳細に扱います。私たちは Python開発者を対象にしており、特にシンプルでありながら強力なウェブフレームワークである FastAPI を使用してWebhookエンドポイントを構築する予定です。DRF(Django REST Framework)も素晴らしい選択肢ですが、単にWebhookリクエストを処理する非常に軽量なロジックなので、FastAPIが最適な選択だと思います。スーパーマーケットに買い物に行くだけでわざわざスポーツカーに乗る必要はありません。軽自動車で十分です。

自動デプロイシステム構築のための基本準備物

本格的な実装は次の回から始まります。今回はスムーズな進行のためにあらかじめ準備しておくべきことを整理します。

  1. GitHubリポジトリ:

    • 自動デプロイを適用したいPythonプロジェクトが含まれたGitHubリポジトリが必要です。(公開/非公開は不問)

    • このリポジトリにコードをプッシュするたびにデプロイが開始されます。

  2. ステージングサーバー(Self-hosted Server):

    • 実際にデプロイが行われるサーバーが必要です。Raspberry Pi 5、個人用VPS(バーチャルプライベートサーバー)、クラウドインスタンス(AWS EC2、GCP Compute Engineなど)いずれも良いです。

    • パブリックIPアドレスまたはドメインを通じて外部(GitHub)からアクセス可能でなければなりません。(ファイアウォール設定に留意する必要があります。)

    • オペレーティングシステムは、Ubuntu ServerのようなLinux環境を推奨します。

    • Dockerのインストール: デプロイされるアプリケーションがDockerコンテナベースでビルドまたは実行できるように、あらかじめDockerがサーバーにインストールされている必要があります。

  3. Python開発環境:

    • ステージングサーバーにPython 3.8以上のバージョンがインストールされている必要があります。(仮想環境の使用を推奨)
  4. Git:

    • ステージングサーバーにGitがインストールされている必要があります。GitHubリポジトリから最新のコードをgit pullコマンドで取得する際に使用されます。
  5. FastAPIおよびUvicorn:

    • Python Webhookエンドポイントを実装するためのフレームワークであるFastAPIとASGIサーバーのUvicornが必要です。次回でインストールと基本設定を扱う予定です。
  6. SSHキー:

    • ステージングサーバーからGitHubリポジトリに安全にアクセスしてコードを取得するためにSSHキー設定が必要です。ほとんどの方はすでに自分のアカウントにSSHキーが登録されていると思います。(まだ登録していない方はGitHubに登録してください。デプロイキーDeploy keyを使用するのが一般的です。)
  7. ウェブサーバー(NginxまたはApache2)およびドメイン/HTTPS設定に関する理解:

    • GitHub Webhookは一般的にHTTPSによる安全な通信が推奨されます。したがって、Webhookを受信するためのdeployer.example.comのようなサブドメインを事前に準備し、このドメインに対するHTTPS証明書(例: Let's Encryptを介した無料証明書)を発行し適用することを強く推奨します。

    • まさかインターネットISPのルーターでFastAPIアプリケーションを直接ポートフォワーディングで接続する人はいないと思いますが、万が一のために補足説明すると、アプリケーションは外部に直接露出させるのではなく、NginxまたはApache2のようなウェブサーバーをリバースプロキシ(Reverse Proxy)として使用してWebhookリクエストをFastAPIアプリケーションに渡す構成が一般的で安全です。必ずサーバープログラムを使用してリバースプロキシで接続してください。これに対する基本的な理解と設定経験があれば非常に役立つでしょう。

  8. Systemdサービスに関する理解(任意ですが推奨):

    • このFastAPI Webhookサーバーはステージングサーバーに常に常駐し実行される必要があります。これを実現するためにサーバー再起動時に自動で開始され、サービス管理(開始/停止/再起動)が容易であるようにSystemdサービスとして登録して運営することを推奨します。

    • 参考: Dockerコンテナ内でgitdockerコマンドを直接実行する複雑なデプロイロジックを構成することはコンテナ設計の目的にも合致せず、docker-in-dockerdocker-out-of-dockerのような複雑な設定が必要でありセキュリティにも良くありません。すでにサーバーにgitdockerがインストールされているなら、FastAPI Webhookサーバーを軽量にSystemdサービスとして起動し、デプロイスクリプトでシステムのgitおよびdockerコマンドを直接活用する方がはるかに効率的で簡潔です。このシリーズではこの方法を中心に説明します。


これで全ての準備が整いました。次回は準備したステージングサーバーにFastAPI Webhookエンドポイントを構築し、GitHub Webhookを設定して初の自動デプロイを成功させるプロセスを詳細に扱います。ご期待ください!