CDって何?一言でいうと「テストが通ったら“そのまま本番まで運んでくれるベルトコンベア”」
CD は大きく分けて2つあります。
Continuous Delivery(継続的デリバリー)
Continuous Deployment(継続的デプロイ)
ざっくり言うと、
Delivery
「いつでも本番に出せる状態まで自動で持っていく」
Deployment
「テストが通ったら本番に自動で出してしまう」
という違いです。
どちらも共通しているのは、
テストが通ったコードを
人間の手作業に頼らず
自動で「本番に近い環境」まで運ぶ
という考え方です。
CI が「壊れてないかを自動で確認する係」だとしたら、
CD は「壊れてないと確認できたものを、安全に届ける係」です。
CIとCDの関係をまずイメージで掴む
CIが終わった“その先”を自動化するのがCD
前回話した CI(GitHub Actions)は、だいたいこんな流れでした。
コードをチェックアウトする
依存をインストールする
テスト・型チェック・Lint を回す
ここまでが「CI」です。
CD は、その先にこういうステップを足します。
アプリをビルドする(Dockerイメージを作る、パッケージを作るなど)
ステージング環境にデプロイする
必要なら本番環境にデプロイする
つまり、
CI
「コードが正しいかを自動で確かめる」
CD
「正しいと確認できたコードを、自動で環境に反映する」
という役割分担になります。
具体例で見る:Python WebアプリのCDイメージ
想定するアプリ
例えば、こんな構成の Python Web アプリを想像してください。
FastAPI で書かれたAPIサーバー
Dockerでコンテナ化している
本番環境は、どこかのサーバー(VPS / Cloud Run / ECS など)
ローカルでは、こうやって動かしているとします。
docker build -t myapp:latest .
docker run -p 8000:8000 myapp:latest
CD では、この「ビルドしてデプロイする流れ」を自動化します。
Continuous Delivery:いつでも本番に出せる状態まで自動で持っていく
Deliveryのゴールは「ボタンを押せば本番に出せる状態」
Continuous Delivery の世界では、こういう状態を目指します。
main ブランチにマージされた時点で
テストが全部通っていて
ステージング環境に自動でデプロイされていて
「本番に出すかどうか」は人間が判断してボタンを押すだけ
つまり、「本番に出す直前まで」は自動でやるけれど、
最後の「本番に出す」は人間がトリガーする、というスタイルです。
これは、慎重に進めたいプロダクトでよく使われます。
GitHub Actionsでのイメージ
例えば、こんな流れになります。
main にマージされたら CI が走る(テスト・Lint・型チェック)
CI が全部通ったら、Dockerイメージをビルドしてレジストリにプッシュ
ステージング環境に自動デプロイ
本番デプロイ用のワークフローは「手動トリガー」にしておく
YAML でいうと、最後の本番デプロイだけ workflow_dispatch にするイメージです。
on:
workflow_dispatch:
inputs:
environment:
type: choice
options:
- production
YAML「本番に出すときだけ、人間がGitHubのボタンを押す」
これが Continuous Delivery です。
Continuous Deployment:テストが通ったら自動で本番まで行く
Deploymentのゴールは「人間が何もしなくても本番が更新される」
Continuous Deployment は、さらに一歩進めて、
main にマージされたら
テストが通ったら
そのまま本番環境に自動デプロイする
というスタイルです。
つまり、「本番に出すかどうか」も自動で決めてしまう。
人間は「コードを書く」「レビューする」だけに集中し、
デプロイ作業から完全に解放されます。
もちろん、その分「テストの信頼性」がめちゃくちゃ重要になります。
どんなときに向いているか
小さな変更を頻繁に出すプロダクト
ロールバック(元に戻す)が簡単な構成
モニタリングとアラートが整っている
こういう条件が揃っているときに、Continuous Deployment は強力です。
逆に、
一回のリリースの影響が大きい
人間の確認が必須な業務(法的なチェックなど)がある
といった場合は、Continuous Delivery 止まりにしておく方が現実的です。
CDで特に大事なポイントを深掘りする
ポイント1:CDは「手作業の手順書」をそのまま自動化するだけ
CD と聞くと、なんだか難しい魔法のように感じるかもしれませんが、
本質はとてもシンプルです。
あなたが今、手でやっているデプロイ作業を、
そのままスクリプトにして、CIの後ろにくっつけるだけです。
例えば、今こうやって本番デプロイしているとします。
git pull
docker compose pull
docker compose up -d
これを GitHub Actions から SSH でサーバーに入って実行する、
というだけでも立派な CD です。
大事なのは、
「人間が毎回同じ手順を繰り返しているなら、それは自動化できる」
という視点です。
ポイント2:CDは「品質の自信」とセットでないと危ない
CD をやる前提として、
テストが十分に書かれている
CI が安定している
ロールバック手順が用意されている
という土台が必要です。
テストがスカスカの状態で「テスト通ったら本番に出す」は、
ただのロシアンルーレットです。
だから順番としては、
ローカルでテストを整える
CI でテストを自動化する
ステージングへのデプロイを自動化する(Delivery)
本番へのデプロイも自動化する(Deployment)
というステップで少しずつ進めるのが現実的です。
ポイント3:環境ごとの差を「設定」で吸収する
CD をやるときに必ず出てくるのが、
開発環境
ステージング環境
本番環境
の違いです。
例えば、
接続するDBのURL
外部APIのエンドポイント
ログレベル
などは環境ごとに変わります。
CD では、これを「コードの中で if 文で分ける」のではなく、
環境変数や設定ファイルで切り替えるのが基本です。
Python なら、例えばこうです。
import os
DATABASE_URL = os.environ["DATABASE_URL"]
PythonCD のときは、GitHub Actions 側で環境ごとに違う DATABASE_URL を渡します。
PythonプロジェクトでのCDの具体的なイメージ
例:Docker + GitHub Actions + 本番サーバー
ざっくりした流れをイメージで書くと、こうなります。
main にマージ → CI(テスト・Lint・型チェック)
CI成功 → Dockerイメージをビルドしてコンテナレジストリにプッシュ
CDジョブ → 本番サーバーに SSH して docker compose pull && docker compose up -d
YAML でいうと、CD 部分はこんな感じになります(イメージ)。
deploy:
needs: test
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- name: Deploy to production
uses: appleboy/ssh-action@v1
with:
host: ${{ secrets.PROD_HOST }}
username: ${{ secrets.PROD_USER }}
key: ${{ secrets.PROD_SSH_KEY }}
script: |
cd /path/to/app
git pull
docker compose pull
docker compose up -d
YAMLここで大事なのは、
needs: test で「テストが通ったらだけデプロイする」secrets で本番サーバーの情報を安全に扱う
という2点です。
初心者がCDを学ぶときの現実的なステップ
ステップ1:まずは「手作業のデプロイ手順」を言語化する
今あなたがどうやって本番に出しているかを、
一度テキストに書き出してみてください。
どのサーバーに
どのブランチを
どんなコマンドで
これがそのまま「CDの設計図」になります。
ステップ2:その手順をローカルでスクリプト化してみる
次に、その手順をシェルスクリプトにしてみます。
#!/bin/bash
set -e
ssh user@server "
cd /path/to/app &&
git pull &&
docker compose pull &&
docker compose up -d
"
これをローカルから叩いて、
「ワンコマンドでデプロイできる」状態にしてみる。
ここまでできたら、
あとはそのスクリプトを GitHub Actions から呼ぶだけです。
ステップ3:最初は「ステージングだけCD」にする
いきなり本番を自動化するのが怖ければ、
ステージング環境だけ
Pull Request マージ時に自動デプロイする
という形から始めるのがおすすめです。
そこで CD の感覚を掴んでから、
本番への自動化を検討する、という順番が安全です。
まとめ(CDは「テスト済みのコードを安全に届けるための自動ベルトコンベア」)
初心者目線で整理すると、CD はこういうものです。
CI が「テスト・チェックを自動で回す仕組み」だとしたら、CD は「そのテスト済みコードを、ステージングや本番に自動で届ける仕組み」。
Continuous Delivery は「いつでも本番に出せる状態まで自動で持っていき、最後の本番デプロイは人間が決める」、Continuous Deployment は「テストが通ったら本番まで自動で出す」という違いがある。
本質は「今人間がやっているデプロイ手順を、そのままスクリプトにしてCIの後ろにくっつけること」であり、テストの信頼性・環境ごとの設定・ロールバック手順とセットで考えると、品質と開発速度の両方を一気に引き上げられる。
