はじめに: 最後のパズルのピースをはめる

こんにちは!ついに長いシリーズの最後の回です。これまでの4回では、自動デプロイシステムの理論から始まり、FastAPIのWebhookサーバーのコアロジックを実装し、Systemdサービスで安定した運用環境を構築しました。

このシリーズの以前の投稿は以下のリンクで確認できます。

① なぜ自分で実装するのか?

② 全体アーキテクチャおよびプロセス設計

③ ステージングサーバー環境設定とFastAPI Webhookサーバー基礎構築

④ デプロイハンドラー詳細およびSystemdサービス登録

しかし、まだ一段階残っています。現在、私たちのFastAPI Webhookサーバーは 8000 番ポートでのみ動作しており、HTTPSを使用していないためセキュリティに脆弱です。また、GitHubは公開ドメインとHTTPS接続を強く推奨しています。

この5回目では、最後のパズルのピースをはめてシステムを完成させます。 Nginxをリバースプロキシとして設定し、FastAPIサーバーを外部に安全に公開し、Let's Encryptを使用して無料HTTPSを適用した後、最終的にGitHub Webhookを連携させて自動デプロイシステムを完成させましょう。

ちょっと待って、なぜApache2ではなくNginxなのか? Apache2とNginxはサーバープログラム市場を二分する優れたWebサーバーです。 しかし、FastAPIのような非同期WebフレームワークはNginxとの相性が非常に良いです。 Nginxは非同期イベントベースで設計されているため、高い同時接続環境でFastAPIの非同期性能を最大限に引き出すことができます。 そのため、FastAPIコミュニティではNginxをプロダクション環境のWebサーバーとして強く推奨し、この文章でもNginxを中心に説明します。

Nginxのインストールとリバースプロキシ設定

なぜNginxを使用するべきか?

  1. リバースプロキシ: FastAPIのようなアプリケーションサーバーは外部トラフィックを直接受け取ることを目的としていません。NginxはWebhookリクエストを受け取り、FastAPIサーバーへ安全に転送するリバースプロキシの役割を果たします。

  2. セキュリティ: Nginxはさまざまなセキュリティ設定やDDoS攻撃防御機能を提供します。

  3. HTTPS適用: HTTPS証明書の管理と適用はNginxのようなWebサーバーが担当します。

Nginxのインストールと設定

ステージングサーバーにSSHで接続してNginxをインストールします。この文章を読んでいる読者の方々はすでにNginxについてのある程度の経験と知識があるという前提で、Nginxのインストール方法、ファイル構造や動作原理の詳細な説明は省略します。

sudo apt update
sudo apt install -y nginx
sudo systemctl enable nginx # 再起動時自動実行
sudo systemctl start nginx # nginx起動
sudo systemctl status nginx # Active状態確認

今度は私たちのFastAPI Webhookサーバーへのリクエストを転送するためのNginx設定ファイルを作成します。 deployer.example.comというドメインを使用することを前提とします。以下は設定の例です。

#/etc/nginx/sites-available/deployer.example.com

# HTTPリクエストをHTTPSへ308リダイレクト
server {
    listen 80;
    server_name deployer.example.com;
    return 308 https://$host$request_uri;
}

# HTTPSリクエストの処理
server {
    listen 443 ssl;
    server_name deployer.example.com;

    # SSL証明書のパス設定
    ssl_certificate /etc/letsencrypt/live/deployer.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/deployer.example.com/privkey.pem;
    ssl_session_cache shared:SSL:1m;
    ssl_session_timeout 5m;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_protocols TLSv1.2 TLSv1.3;

    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_redirect off;
    }
}

  • HTTP 80番ポート設定: server_namedeployer.example.comlisten 80 ブロックはすべてのHTTPリクエストをreturn 308 https://$host$request_uri; コマンドを介して永続リダイレクトします。

  • HTTPS 443番ポート設定: listen 443 ssl; ブロックはHTTPSリクエストを処理します。

  • ssl_certificate & ssl_certificate_key: すでにLet's Encryptで発行されたことを前提に作成しています。このブロックでは発行されたSSL証明書と鍵ファイルのパスを指定します。このパスはcertbotが証明書を発行する際に自動的に生成するパスです。

  • location / ブロック: HTTPSに変換されたリクエストを私たちのFastAPIサーバー(http://127.0.0.1:8000)へ転送するリバースプロキシ設定を行います。

この設定ファイルでNginxを再起動すれば、すべてのWebhookリクエストが安全なHTTPSで処理されるようになります。

# 設定ファイルをsites-enabledディレクトリにシンボリックリンク
sudo ln -s /etc/nginx/sites-available/deployer.example.com /etc/nginx/sites-enabled/

# Nginx設定ファイルの文法エラーを確認します。
sudo nginx -t

# Nginxを再起動して変更を適用します。
sudo systemctl restart nginx

HTTPS適用 (Let's Encrypt + Certbot)

GitHub Webhookはセキュリティ上の理由からHTTPS通信を強く推奨しています。 Let's Encryptは誰でも無料でSSL/TLS証明書を取得できる非営利認証機関であり、 Certbotは証明書の発行と更新を自動化してくれる優れたツールです。ここではインストール方法については省略します。

成功裏に完了したら、ブラウザで https://deployer.example.com にアクセスし、FastAPIのAPIドキュメント(.../docs)や / エンドポイントにアクセスしてみてください。 Webhook server is running! メッセージを見ることができれば、NginxとHTTPS設定が成功したことになります。

GitHub Webhook最終連携とテスト

これですべての準備が整いました。GitHubリポジトリに私たちが構築した自動デプロイシステムを接続してみましょう。

  1. GitHubリポジトリにアクセス: 自動デプロイを適用するプロジェクトのGitHubリポジトリに移動します。

  2. Webhooks設定: 上部メニューからSettings -> 左のメニューでWebhooksをクリックします。

  3. Webhook追加: Add webhook ボタンをクリックして次の情報を入力します。

    • Payload URL: NginxおよびHTTPSを適用したWebhookサーバーのアドレスを入力します。(例: https://deployer.example.com/webhook)

    • Content type: application/jsonを選択します。

    • Secret: 3回目で~/projects/webhook_server/.env ファイルに設定したGITHUB_WEBHOOK_SECRETの値を正確にコピーして貼り付けます。

    • このWebhookをトリガーするイベント:: Just the push eventを選択します。

    • Active: チェックボックスがアクティブになっているか確認します。

  4. 保存: Add webhook ボタンをクリックしてWebhookを保存します。

GitHub Webhook設定スクリーンショット

Webhookが正常に登録されると、Recent Deliveries セクションに緑色のチェックマークが表示され、テストリクエストが正常に送信されたことを確認できます。

これで最終テストを行いましょう。

  1. ローカルでコード変更: プロジェクトのコードを少し修正し、Gitにコミットしてプッシュしてみましょう。

  2. 状態確認:

    • GitHub Webhook設定ページのRecent Deliveriesで、つい最近行ったプッシュのWebhookが成功(緑色チェック)しているか確認します。

    • ステージングサーバーにSSHで接続してsudo journalctl -u github-webhook-deployer.service -f コマンドでリアルタイムログを確認します。 Git pull successful, Deployment task finishedなどのメッセージが表示されれば成功です。

    • デプロイされたDockerコンテナの状態を確認して、最新のコードが反映されているか検証します。

結論: 自動デプロイシステムの完成!

おめでとうございます!ローカル開発環境からGitHub、そして自前で構築したステージングサーバーまで続く完全なCI/CDパイプラインを成功裏に構築されました。

このシリーズを通じて、私たちは次のことをすべて達成しました。

  • なぜ自分でWebhookベースの自動デプロイシステムを構築すべきか理解しました。

  • FastAPIを用いたWebhookサーバーのアーキテクチャを設計し実装しました。

  • Systemdを用いてサービスを安定的に運営する方法を学びました。

  • NginxとHTTPS設定を通じてセキュリティを強化しました。

  • 最終的にGitHubと連携させ、すべてのプロセスを自動化しました。

これでコードをプッシュする瞬間、あなたの手が触れなくてもサーバーが自動的に最新のコードを反映します。このシステムを基に、さらに複雑なデプロイロジックを追加したり、通知機能を連携させたりするなど、自分なりの方法で発展させてみてください。

長い旅を共にしていただき、ありがとうございます!