二人で全てを回す:実際に機能するシンプルなパイプライン
あなたは二人だけでデジタルプロダクトを開発している。在庫管理の簡易Webアプリかもしれないし、ビジネスパートナー向けのAPIサービスかもしれない。チームは小さく、予算は限られており、目標は数ヶ月ではなく数週間で使えるものを作ることだ。この時点で最初に考えるべきは、パイプラインやCI/CDではない。「ユーザーが使い始めたとき、毎回サーバーにログインせずに新しいバージョンをどうやって届けるか?」という問いだ。
小さなスタートアップでは、手動のプロセスが自然に感じられる。SCPでファイルをサーバーに送り、SSHでサービスを再起動し、データベースのクエリをコピペする。最初の数回のリリースではそれで十分だ。しかし3〜4回繰り返すと、ひび割れが見え始める。手順を忘れる。間違ったファイルをコピーする。マイグレーションをスキップする。さらに、ステージングと本番のように複数の環境がある場合、それぞれに正しい順序を覚えておき、何も漏れないことを願うしかない。
ここでシンプルなパイプラインの出番だ。大掛かりなプロジェクトではなく、コードが変更されるたびに同じ手順を実行するツールとして導入する。リポジトリに1つの設定ファイルを置き、ビルド、テスト、デプロイの3つのステップを定義する。ビルドはコードを実行可能なアーティファクトに変換する。テストは自動チェックを実行する(例えば、新機能が古い機能を壊していないか)。デプロイはアーティファクトをターゲットサーバーに送信する。
シンプルなパイプラインの姿
小さなスタートアップでは、ツールは複雑である必要はない。GitHub Actions、GitLab CI、クラウドプロバイダーの組み込みCIで十分だ。重要なのは、特定のブランチにプッシュしたときにパイプラインが自動的に実行されることだ。例えば、mainにプッシュするとビルド、テスト、ステージングへのデプロイがトリガーされる。すべてが成功すれば、1クリックまたは1コマンドで本番にデプロイする。
具体的な例を示そう。小さなVPSでホストされているNode.jsのWebアプリを想像してほしい。パイプラインファイルは次のようになる:
以下がパイプラインの視覚的な概要だ:
実際のパイプライン設定は次のようになる:
name: Simple Pipeline
on:
push:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm install
- run: npm run build
test:
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm install
- run: npm test
deploy-staging:
needs: test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm install
- run: npm run build
- run: |
rsync -avz --delete dist/ user@staging-server:/var/www/app/
ssh user@staging-server 'systemctl restart myapp'
mainへのプッシュ時:依存関係のインストール、テストの実行、アプリのビルド、ビルドアーティファクトのステージングサーバーへのコピー、サービスの再起動。- 手動トリガーまたはタグ時:同じ手順を繰り返すが、デプロイ先は本番。
これだけだ。Kubernetesも、コンテナオーケストレーションも、多段階の承認ゲートもない。毎回一貫して実行される3つのステップだけだ。
完全所有権は痛みも伴う
完全所有権とは、あなたとチームメイトがこのパイプラインに対して全責任を負うことを意味する。専任のDevOpsチームも、長い承認プロセスもない。パイプラインを書き、実行し、壊れたら直す。プレッシャーに感じるかもしれないが、実は利点でもある。アプリケーションがどのようにデリバリーされるかを正確に理解している。何が問題になるかを知っている。そして、自分で構築したからこそ、修正方法もわかっている。
何かが失敗したとき(必ず失敗する)、他のチームの対応を待つ必要はない。ログを確認し、壊れたステップを特定し、修正する。この実践的な経験は非常に貴重だ。どんな本やコースでも再現できない方法で、デリバリーの基礎を教えてくれる。
ダッシュボードにこだわらない基本的な可観測性
パイプラインが成功したか失敗したか、失敗した場合はどのステップで失敗したかを知る必要がある。ほとんどのパイプラインツールはログと通知を提供している。今はそれで十分だ。ダッシュボード、アラート、分散トレーシングを備えた完全な可観測性スタックは必要ない。
アプリケーション自体に1〜2つのシンプルなメトリクスを追加する。受信リクエスト数、エラー率、平均応答時間を追跡する。この3つの数値で、新しいバージョンがデプロイ後に正常に動作しているかどうかがわかる。エラー率が急上昇したり応答時間が跳ね上がったりしたら、何かがおかしい。パイプラインのログを確認して何が変更されたかを調べ、必要ならロールバックする。
小規模チームが忘れがちなこと
ドキュメントだ。誰も読まないような長く詳細なものではない。パイプラインの仕組み、失敗時の対処法、以前のバージョンへのロールバック方法を簡潔にメモしたものだ。頭の中でまだ新鮮なうちに書き留めておく。このメモは、あなたが飛行機の中、病気、休暇などで連絡が取れず、何か問題が発生したときに重要になる。また、チームが成長して新しいメンバーがデリバリープロセスを理解する必要があるときにも役立つ。
リポジトリ内のシンプルなMarkdownファイルで十分だ。以下を含める:
- 各環境へのデプロイをトリガーするブランチ
- 手動ロールバックを実行するコマンド
- ステップが失敗した場合のログの場所
- 二人とも対応できない場合の連絡先
このパターンが機能しなくなる時
このシンプルなパイプラインは永遠に適合するわけではない。チームが成長し、アプリケーションが複雑になり、ユーザーベースが拡大するにつれて、より多くの構造が必要になる。並列テスト実行、データベースマイグレーションステップ、コンプライアンスのための承認ゲート、ブルーグリーンやカナリアリリースのようなデプロイ戦略が必要になるかもしれない。ビルド、テスト、デプロイを異なる責任を持つ別々のステージに分離する必要が出てくるだろう。
しかし、素早く動く必要がある小さなスタートアップにとっては、シンプルなパイプラインと完全所有権から始めるのが正しい選択だ。複雑なツールに埋もれることなく、デリバリーの基礎を学べる。ニーズの変化に応じて進化できる基盤を構築できる。そして、実際に人々が使うプロダクトができる前に過剰にエンジニアリングするという罠を避けられる。
最初のパイプラインのための実践的チェックリスト
- ビルド、テスト、デプロイの3つのステップを定義する
- 1つのCIツールを選ぶ(GitHub Actions、GitLab CI、クラウドプロバイダー組み込み)
mainへのプッシュでパイプラインがトリガーされるように設定する- 本番用の手動デプロイステップを追加する
- アプリにリクエスト数、エラー率、応答時間のログを追加する
- ロールバック方法を1ページにまとめたドキュメントを作成する
- 意図的にパイプラインを壊して修正し、テストする
まとめ
コードを所有する人々によって構築されたシンプルなパイプラインは、他の誰かが管理する複雑なシステムよりも優れている。小さく始め、プロセスを所有し、プロダクトとともに基盤を成長させよう。パイプラインを運用して最初の1ヶ月で学ぶことは、1年間読書するよりもはるかに多い。