Gitを本番デプロイのツールとして使える?

tomon
2024-04-30
2024-04-30

小ネタです。
WEBサイトとかが小規模で、
gitリポジトリのワーキングディレクトリと本番サイトのディレクトリ構成が同じ場合、
本番環境へのデプロイには、git pullでリモートリポジトリから引っ張ってきてデプロイしたくなります。特に、小規模なシステム開発や制作案件とかで。
この方法は本番ではなるべく採用しないようにしましょう。

※開発環境なら便利なのでまだいいかも。

運用がすごく簡単になるのでついやりたくなるのですが、
gitはあくまでソース管理ツールで、デプロイツールではないので、
思わぬ落とし穴もあります。

例えば。。

開発リポジトリで、git管理下に入れたファイルを管理下からはずしたい。
ただし、そのファイルは運用上必要なファイルなのでワーキングディレクトリ上には残しておきたい。
このために

git rm --cached x.txt

とかしてコミットして、その後、リモートリポジトリにpushします。
--cachedをつけて実行したので、x.txtはこれを実行した環境には残ります。

ところが、本番でこれをgit pullすると、本番上のx.txtは消えてしまいます。
よく考えれば、開発環境で、--cachedをつけてx.txtを残したとしても
それだけのはなしで、pushしたときにはリモートリポジトリには
x.txtはgit管理下からはずします、という情報しか行きません。
pullしたら消えますよね。

この問題は一例で、
その他にもgitをデプロイツールとして使用しようとすると起こり得る問題があると
思いますのでお気をつけください。
本番ではデプロイツールとして使わないのがいいですね。

上の問題を実証してみました。

環境
AlmaLinux release 9.2
git version 2.39.3

ディレクトリ構造
work
├── develop :開発環境の想定 originをremoterepoに設定。変更はoriginにpush。
│   ├── 1.txt
│   ├── 2.txt
│   ├── 3.txt
│   └── x.txt
├── product :本番環境の想定 originをremoterepoに設定。originからpullするとデプロイできるはず。
│   ├── 1.txt
│   ├── 2.txt
│   ├── 3.txt
│   └── x.txt
└── remoterepo :リモートリポジトリ originの想定

※実際には、開発環境がローカルPCとかにあり、
 本番環境はグローバルの別サーバー
 リモートリポジトリ origin はまた別サーバー(とかgithubとか)
 のはずですが、いちいち、別サーバーで鍵設定して、とか面倒。
 簡略に、操作しやすくするため
 すべて同じサーバーでそれぞれのディレクトリに作成して連携させます。
  ※この方法、gitの挙動を簡易に確認するやり方として便利。

mkdir work && cd work

# リモートリポジトリ用ディレクトリ作成
mkdir remoterepo && cd remoterepo/
# git初期化 --bareをつけて。
git init --bare

# 開発環境リポジトリ用ディレクトリ作成
cd ..
mkdir develop && cd develop
git init
git remote add origin ../remoterepo
# ↑こんなふうにリモートリポジトリを同じサーバー上で相対パスでも指定できます

# 本番環境
cd ..
mkdir product && cd product
# git初期化
git init
# リモートリポジトリの設定
git remote add origin ../remoterepo

ディレクトリ構造
work
├── develop :開発環境の想定 originをremoterepoに設定。変更はoriginにpush。
├── product :本番環境の想定 originをremoterepoに設定。originからpullするとデプロイできるはず。
└── remoterepo :リモートリポジトリ originの想定


# 開発環境に、1.txt 2.txt 3.txt x.txtを作成
cd ..
cd develop

touch 1.txt
touch 2.txt
touch 3.txt
touch x.txt

git add .
git commit -m 'first commit (include x.txt)'

ディレクトリ構造
work
├── develop :開発環境の想定 originをremoterepoに設定。変更はoriginにpush。
│   ├── 1.txt
│   ├── 2.txt
│   ├── 3.txt
│   └── x.txt
├── product :本番環境の想定 originをremoterepoに設定。originからpullするとデプロイできるはず。
└── remoterepo :リモートリポジトリ originの想定

# originにpushしておきます。
git push origin master
# 本番でpullします。
cd ..
cd product
git pull origin master
ls
# 1.txt 2.txt 3.txt x.txtがあるはず。

ディレクトリ構造
work
├── develop :開発環境の想定 originをremoterepoに設定。変更はoriginにpush。
│   ├── 1.txt
│   ├── 2.txt
│   ├── 3.txt
│   └── x.txt
├── product :本番環境の想定 originをremoterepoに設定。originからpullするとデプロイできるはず。
│   ├── 1.txt
│   ├── 2.txt
│   ├── 3.txt
│   └── x.txt
└── remoterepo :リモートリポジトリ originの想定

cd ..
cd develop
# x.txtはgit管理下に置く必要なかった! けど、運用上、必要なファイルだから
# git管理下からはずすけど、ファイルを削除しないでおこう!

git rm --cached x.txt
git commit -m 'delete x.txt ,but keep x.txt'

ls
# ここで、develop/x.txt は消されず残っています。
# git statusすると、untrackのファイルに出てくるはず。
# でてこないように.gitignoreとかに登録したりするけど、ここでは省略


# originにpush
git push origin master

# productでpullする。
cd ..
cd product

# lsで。1.txt 2.txt 3.txt x.txtが存在していることを確認。
ls

git pull origin master

ls 
# 結果 =>  1.txt  2.txt  3.txt
# pullすると、git管理下に置かないが、運用上必要なファイル x.txtが消えている!! 本番なら事故発生!!

最終ディレクトリ構造
work
├── develop
│   ├── 1.txt
│   ├── 2.txt
│   ├── 3.txt
│   └── x.txt
├── product  <= x.txtが存在しない!!!
│   ├── 1.txt
│   ├── 2.txt
│   └── 3.txt
└── remoterepo

このようにgitを本番デプロイツールとして使うのはなるべく避けた方がよいでしょう。