情シス担当のためのGit入門:サーバー設定ファイルとスクリプトをバージョン管理する最小手順
TL;DR
- Gitとは: 1本のファイルのまま、変更履歴ごと管理できるツール。bakファイルを量産せずに過去の状態に戻せる
- この記事でやること:
git initからgit pushまで7コマンド +.gitignoreによる機密情報の保護 + GitHubの無料プランでチーム共有 - 所要時間: 初回セットアップ30分、日常フロー習得1日
「nginx.conf_最新版2.bak」がなぜ危ないのか
ファイル名管理の3つの限界
例えば、こんな状況を想像してほしい。
/etc/nginx/
├── nginx.conf
├── nginx.conf_20240601_bak
├── nginx.conf_最新版.bak
└── nginx.conf_最新版2.bak
どれが現在本番に適用されているファイルか、一目では判断できない。
このような状況は3つの構造的な問題を抱えている。
1. どのファイルが本番適用済みか分からない ファイル名の末尾に日付や「最新」という文字を足していくやり方は、ファイルが増えるほど混乱が深まる。「最新版2」より新しいのはどれかを確認するには、更新日時を見るしかない。更新日時が変わっていれば、それが最新だ——でも、他の担当者がサーバー上で直接編集していたら?
2. 誰がいつ変えたか分からない ファイルのタイムスタンプは「いつ変わったか」は教えてくれる。しかし「誰が」「なぜ」変えたかは残らない。トラブル発生時に原因を追うための情報が、ファイル名管理では記録できない。
3. 間違えて上書きしたらロールバック不能
cp nginx.conf.bak nginx.conf を1コマンドミスで実行した瞬間、作業中の変更が消える。bakファイルの中身が正しいとも限らない。「どの状態に戻せばいいのか」が分からないまま、サービスが止まる——これがファイル名管理の最大のリスクだ。
Gitはこの3つを同時に解決する。「誰が・いつ・なぜ変えたか」がコミット履歴に残り、1コマンドで任意の時点の状態に戻せる構造がある。
Gitとは何か — 情シス向け1行定義
バージョン管理の本質
Gitは、プロジェクトディレクトリの中に .git/ という隠しディレクトリを作り、そこにファイルのスナップショット(コミット)を積み重ねていく仕組みだ(Git公式ドキュメント git-init)。
ファイルは1本のままで存在する。「最新版2.bak」のような複製を作る必要はない。git log を実行すれば「誰が・いつ・どんな変更をしたか」の一覧が表示され、git checkout でその時点の状態にファイルを戻せる。
GitとGitHubは別物
| ツール | 役割 |
|---|---|
| Git | ローカルサーバー上で動く変更履歴管理ツール |
| GitHub | Gitの変更履歴をクラウドに保管するサービス |
GitはGitHubがなくても単体で使える。ローカルのサーバー上だけで完結する管理であれば、GitHubへの登録は不要だ。チーム共有や外部バックアップが必要になった段階でGitHubを追加する、という順番が現実的だ。
初回セットアップ — git init まで5分
git config — 誰が変えたかを記録する設定
Pro Git Book に沿って、最初に名前とメールアドレスを設定する。これがコミット履歴に「誰が変えたか」として記録される情報になる。
git config --global user.name "Taro Yamada" # コミット履歴に表示される名前
git config --global user.email [email protected] # コミット履歴に表示されるメール
--global は「このサーバー上のすべてのリポジトリに共通適用される」オプションだ。一度設定すれば、どのリポジトリでも同じ名前がコミット履歴に残る。
git init — リポジトリを作る
Git公式ドキュメントに沿って、管理を始めたいディレクトリでリポジトリを初期化する。
git init -b main # リポジトリを初期化し、最初のブランチ名を "main" に設定する
-b main を指定する理由はGitHubの慣習に合わせるためだ。GitHubへのpushを想定するなら最初からブランチ名を統一しておくと手間が減る。
注意: -b オプションはGit 2.28以降でのみ使用できる。サーバーのGitバージョンが2.28未満の場合は代わりに次のコマンドを使う。
git init
git symbolic-ref HEAD refs/heads/main # ブランチ名を "main" に変更する
このコマンドを実行すると .git/ ディレクトリが作成される。この瞬間からそのディレクトリのバージョン管理が始まる。
必須コマンド7本 — 日常操作の全体像
「Gitは難しそう」と感じるとしたら、全体像が見えていないからかもしれない。日常の操作に必要なコマンドは7本に絞られる。
変更を記録する3コマンド(status → add → commit)
変更を記録する流れは3ステップだ。
git status # 今どのファイルが変わったか確認する(作業前に必ず実行)
git add nginx/nginx.conf # 記録したいファイルをステージ(選択)する
git commit -m "nginx: worker_connections を 2048 に変更" # スナップショットとして保存する
git status は作業前の確認習慣として固定する。 どのファイルが変更済みか、ステージ済みかを把握してからaddに進む(Git公式ドキュメント git-status)。
git add . はディレクトリ内のすべての変更をステージする。git add nginx/nginx.conf のように特定ファイルを指定すれば、意図しないファイルが混入するリスクを避けられる。情シスの用途では特定ファイルを指定する方が安全だ。
コミットメッセージは「ファイル名: 変更内容の要約」の形式が読みやすい(Git公式ドキュメント git-commit)。1か月後に git log を見たとき、何のための変更だったかが一目で分かる。
git commit -a に関する注意: -a オプションは変更済み・削除済みのファイルを自動でステージするが、新しく追加したファイルには効かない(Git公式ドキュメント git-commit)。新規ファイルは必ず git add で明示的に追加する必要がある。
チームで共有する3コマンド(clone → push → pull)
GitHubなどリモートリポジトリを使う場合の操作だ。
git clone https://github.com/yourorg/infra-configs.git # リモートリポジトリをローカルに取得する
git push origin main # ローカルの変更をリモートに送る
git pull origin main # リモートの変更をローカルに取り込む
git pull は作業開始前に実行する習慣にする。チームで共有している場合、他の担当者の変更を取り込んでから作業を始めないと、後で競合(コンフリクト)が発生するリスクがある(Git公式ドキュメント git-pull)。
初回のpushでは -u オプションが必要なケースがある。
git push -u origin main # 初回のみ: ローカルのmainとリモートのmainを紐づけながらpushする
2回目以降は git push だけで済む。
履歴確認とロールバック(log + checkout)
Gitを使う最大のメリットがここにある。
git log --oneline # コミット履歴を一行で一覧表示する
git checkout <commit-hash> -- nginx/nginx.conf # 特定のコミット時点のファイルを取り出す
git checkout HEAD -- nginx/nginx.conf # 最新コミット時点のファイルに戻す
<commit-hash> の部分には git log --oneline で確認したハッシュ値(例: a1b2c3d)を入れる。「この変更を入れた後からおかしくなった」という状況で、そのコミットの一つ前のハッシュを指定すれば、1コマンドで設定を戻せる。
.gitignoreで機密情報を守る
なぜ.gitignoreが必要か
.gitignore に書かれたパターンに一致するファイルは、Gitが追跡対象から除外する(Git公式ドキュメント gitignore)。
ただし重要な点がある。すでにGitが追跡しているファイルには .gitignore は効かない。 .gitignore の設定は、リポジトリを初期化した直後・最初のコミットより前に行う必要がある。
万が一追跡済みのファイルを除外したい場合は次のコマンドで追跡を解除できる。
git rm --cached .env # .env ファイルの追跡を解除する(ファイル自体は残る)
情シス向け.gitignoreテンプレート
リポジトリのルートに .gitignore というファイルを作成し、以下をそのままコピーして使う。
# 環境変数・シークレット類
.env
.env.*
*.env
secrets/
credentials/
# 秘密鍵・証明書
*.pem
*.key
*.p12
id_rsa
id_ed25519
# Ansibleを使う場合: vault パスワードファイル
vault_pass.txt
# OS・エディタが自動生成するファイル
.DS_Store
Thumbs.db
*.swp
*.bak
# ローカル環境固有の設定
local.conf
local.yml
特に .env ファイルは、データベースのパスワードやAPIキーを含む場合が多い。GitHubにpushした瞬間、そのリポジトリがパブリック設定であれば世界中からアクセス可能になる。プライベートリポジトリでも、誤ってパブリックに変更した場合のリスクを考えると、最初から .gitignore で除外するのが安全だ。
GitHubの無料プランで何ができるか
「GitHubは有料では?」という疑問が出るかもしれない。結論として、情シスが設定ファイルを管理する用途では無料プランで十分だ。
GitHub公式ドキュメント(2026年7月時点)に記載された無料プランの主要な仕様は次のとおりだ。
| 機能 | GitHub Free(個人アカウント) |
|---|---|
| プライベートリポジトリ数 | 無制限(一部機能制限あり) |
| コラボレーター数 | 無制限 |
| GitHub Actions | 月2,000分 |
| リポジトリ推奨サイズ上限 | 10GB(Repository limits) |
| 単一ファイルの強制上限 | 100MB |
無料プランで使えない主な機能:
- Protected branches(ブランチへの直接pushを禁止するルール設定)— Organization アカウントが必要
- Code owners(特定ファイルの変更に承認者を指定する機能)
nginx.confやBashスクリプトを数人のチームで共有する用途であれば、Protected branchesがなくても運用は成立する。サーバー設定ファイルのサイズが10GBを超えることもまずない。
実践フロー — サーバー設定ファイルをGit管理する
なぜ /etc/ 直接でなく管理ディレクトリを使うか
/etc/ 直下で git init を実行する方法もあるが、権限の問題が発生しやすい。root権限で管理されているファイルを一般ユーザーのGitで扱うと、コミット操作のたびに権限エラーが出るケースがある。
実用的なアプローチは、ホームディレクトリ以下に管理用ディレクトリを作り、設定ファイルをコピーして管理する方法だ(Qiita: システム設定ファイルをGitで管理する)。変更を確認したら本番の /etc/ に sudo cp で反映する、という2ステップの運用になる。
初回セットアップ手順
# 1. 管理ディレクトリを作成してリポジトリを初期化する
mkdir ~/server-configs && cd ~/server-configs
git init -b main
# 2. .gitignore を最初に作成する(機密情報を追跡させないために初回コミット前に行う)
touch .gitignore
# ← テンプレートの内容を .gitignore に貼り付ける
# 3. 設定ファイルをコピーして初回コミットを作る
mkdir nginx
cp /etc/nginx/nginx.conf nginx/
git add .gitignore nginx/nginx.conf
git commit -m "nginx: 初期設定を追加"
git commit -m "nginx: 初期設定を追加" が成功した時点で、最初のスナップショットが記録された。ここが第1のマイルストーンだ。この時点から、過去の状態へのロールバックが可能になる。
日常の変更管理フロー
設定を変更するときは、管理ディレクトリ上のファイルを編集してからコミットし、最後に本番へ適用する順番で進める。
# 作業前: リモートがある場合は最新を取り込む
git pull origin main
# 管理ディレクトリ上で設定ファイルを編集する
vim nginx/nginx.conf
# 変更内容を確認する
git diff nginx/nginx.conf
# コミットする
git add nginx/nginx.conf
git commit -m "nginx: worker_connections を 2048 に変更"
# 本番に反映する
sudo cp nginx/nginx.conf /etc/nginx/nginx.conf
sudo nginx -t && sudo systemctl reload nginx
sudo nginx -t は設定ファイルの構文チェックを実行するコマンドだ。nginx: configuration file /etc/nginx/nginx.conf test is successful と表示されれば、reload に進んでいい。エラーが出た場合は次のセクションのロールバック手順を使う。
問題発生時のロールバック
# どのコミットに戻るか確認する
git log --oneline
# 例: 出力が以下のようになっている場合
# a1b2c3d nginx: worker_connections を 2048 に変更
# e4f5g6h nginx: 初期設定を追加
# 一つ前のコミット時点のファイルを取り出す
git checkout e4f5g6h -- nginx/nginx.conf # <commit-hash> の部分は実際のハッシュ値に置き換える
# 本番に反映する
sudo cp nginx/nginx.conf /etc/nginx/nginx.conf
sudo nginx -t && sudo systemctl reload nginx
git log --oneline で一覧を確認し、戻したいタイミングのハッシュ値をコピーして git checkout に渡すだけだ。「どのバックアップを使えばいいか」を調べる時間はかからない。
よくあるミスと対処法
.envをpushしてしまった
pushする前に気づいた場合:
freeCodeCampに記載された手順で、コミット自体を取り消せる。
git reset HEAD^ --soft # 直前のコミットを取り消す(ファイルの変更は残る)
git rm .env --cached # .env の追跡を解除する
echo ".env" >> .gitignore # .gitignore に追加する
git add .gitignore
git commit -m "fix: .env を gitignore に追加"
pushした後に気づいた場合:
まず最初にやるべきことは、漏洩した認証情報を即時ローテーション(パスワード変更・APIキー再発行)することだ。その後で履歴の削除作業を進める。GitHubにpushした時点で、たとえプライベートリポジトリでも外部からアクセスされた可能性があるという前提で動く。
履歴の削除には git filter-repo または BFG Repo-Cleaner を使い、git push --force-with-lease でリモートを上書きする。詳細な手順は別途確認してほしい。本稿では予防策(最初から .gitignore を設定する)が最も重要な対策だと伝えておく。
間違ったファイルをコミットした(未push)
git reset --soft HEAD~1 # 直前のコミットを取り消す(ファイルの変更は残る)
HEAD~1 は「直前のコミットを取り消す」という意味だ。ファイルの変更内容は残るため、修正してから改めてコミットできる。
git reset --hard は本稿で紹介しない。 --hard はファイルの変更内容ごと消えるため、初期段階では使わない方が安全だ。
作業中のファイルを誤って退避したい
別の作業に切り替えなければならないが、変更中のファイルはまだコミットしたくない——そういうときは git stash を使う。
git stash # 作業中の変更を一時退避する(「引き出しにしまう」イメージ)
git checkout main # 正しいブランチに移動する
git stash pop # 退避した変更を元の場所に取り出す
コマンドチートシート — 情シス日常操作版
# --- 日常確認 ---
git status # 変更状態の確認(作業前に必ず実行する)
git log --oneline # コミット履歴の一覧表示
git diff nginx/nginx.conf # 特定ファイルの変更差分を確認する
# --- 変更の記録 ---
git add nginx/nginx.conf # 特定ファイルをステージする
git commit -m "変更内容の要約" # スナップショットとして保存する
# --- リモートとの同期 ---
git pull origin main # 作業前にリモートの変更を取り込む
git push origin main # ローカルの変更をリモートに送る
# --- ロールバック ---
git log --oneline # どのコミットに戻るか確認する
git checkout <hash> -- nginx/nginx.conf # <hash> を実際のハッシュ値に置き換えて実行する
Gitを使い始めたら次にやること
ブランチを使って本番に影響しない変更テストをする
ブランチは「本番設定を壊さず変更を試せる平行世界」だ(Git公式ドキュメント git-branch)。
git checkout -b feature/nginx-gzip-tuning # 新しいブランチを作成して切り替える
# ← このブランチ上で変更・テストを行う
git checkout main # 本番ブランチに戻る
git merge feature/nginx-gzip-tuning # 問題なければ本番に反映する
ブランチ運用の詳細は [関連記事: Gitブランチ運用入門] を参照してほしい。
AnsibleやShellスクリプトもGitで管理する
Ansible Playbookは設定ファイルより管理の恩恵が大きい。複数ホストへの適用内容をコードとして記録できるため、「どのサーバーにどの変更を入れたか」が差分レビューで把握できるようになる。
Gitで設定ファイルを管理し始めると、「このPlaybookを変えたときに何が起きたか」を追跡したくなる。それが IaC(Infrastructure as Code)の入口だ。
Playbookの管理方法については [関連記事: AnsibleによるPlaybook管理入門] で扱う。
設定ファイルをコードとして管理する構成相談
Gitを使い始めると、設定ファイルの管理だけでなく、「Ansibleで複数サーバーを一括管理」「インフラ変更をレビューできる体制」といった方向に自然に発展していく。
構成設計や初期セットアップについて相談したい場合は、お気軽にご連絡ください。
まとめ — Gitで「bak地獄」を終わらせる3つの変化
| 管理の側面 | Git導入前 | Git導入後 |
|---|---|---|
| ファイル管理 | nginx.conf_bak2が乱立 | 1ファイル + git log で履歴一覧 |
| 変更の追跡 | 誰が変えたか不明 | コミットメッセージで「誰が・なぜ」が追跡可能 |
| ロールバック | 手作業で恐る恐る | git checkout 1コマンド |
| チーム共有 | Slackでファイルを送受信 | GitHubプライベートリポジトリで共有 |
nginx.conf_最新版2.bak という状態は、悪意でなく「記録を残したい」という真っ当な動機から生まれる。Gitはその動機を、仕組みとして実現する。7本のコマンドを覚えれば、情シス担当がサーバー設定ファイルを安全に管理するための土台は整う。