Git を利用した開発環境・テスト環境・本番環境の構成について解説いたします。
Git とは本来ソースコードなどのバージョン管理を目的として作られたシステムですが、その仕組みを利用することで環境の複製が容易に実現できるため、テスト環境や本番環境も Git で管理しておくと修正プログラムの適用等に大変便利です。
図では開発環境・テスト環境・本番環境がそれぞれ Git で管理されています。
中央リポジトリが実際にソースコードのバージョン管理をしている箇所で、リポジトリと呼ばれるアクセス起点がネットワーク上に公開されています。
その他の環境は公開されたリポジトリにアクセスして最新のソースプログラムをすばやく自身の環境に取り込むことができます。
Git には フック【hooks】 という仕組みがあり、Git に対するアクションをトリガーとしてなんらかのスクリプト処理を行うことができます。
例えば中央リポジトリに修正コードをpush
したタイミングでテスト環境にもその修正コードを自動で反映させるということもできます。
このような仕組みを利用することにより、テスト環境や本番環境を常に安全に、そして最新の状態に保つことが可能となります。
リポジトリの2つの分類
リポジトリには、リモートリポジトリとローカルリポジトリという分類があります。
リモートリポジトリ
リモートリポジトリはネットワーク上で公開され、複数の作業者から共有されます。
ローカルリポジトリ
ローカルリポジトリはリモートリポジトリから環境を復元(クローン)したもので、リモートリポジトリで管理されているファイル群の取得やファイルの編集履歴情報を追跡することができます。
他者からは見えません。
また、ノンベアリポジトリとベアリポジトリという分類も存在します。
ノンべアリポジトリ
Git で管理されている実際のファイル群が存在する作業フォルダ(ワーキングディレクトリ)のあるリポジトリ。
べアリポジトリ
ワーキングディレクトリのないリポジトリ。
管理されているファイルの履歴情報のみが存在します。
中央リポジトリ
(remote, bare)
実際のバージョン管理を担っているリポジトリです。
複数の作業者から共有されるリモートリポジトリであり、Git の管轄外から直接ファイルを編集されることを避けるようワーキングディレクトリの存在しないベアリポジトリを使用します。
開発環境からはpull
およびpush
が行われ、ステージング環境やプロダクション環境からはpull
が行われます。
中央リポジトリはワーキングディレクトリもなく非常にコンパクトなので、ステージング環境やプロダクション環境内に置くような物理サーバ構成が一般的かと思います。
まずは Git をインストールします。
>yum -y install git # CentOS
>apt-get install git # Ubuntuなど
remote.gitという名前でリモートリポジトリを作成します。
>cd /path/to
>git init --bare --shared remote.git
Initialized empty shared Git repository in /path/to/remote.git/
リポジトリを SSH 接続で参照させたい場合は、中央リポジトリサーバに SSHD を設定する必要があります。
参考: SSHD の設定
開発環境
(local, non-bare)
まずは中央リポジトリをgit clone
コマンドで複製します。
中央リポジトリにはまだ何もないので、warning が出ていますね。
>cd /path/to
>git clone /path/to/remote.git # 自サーバ内に中央リポジトリがある場合
>git clone https://github.com/sendgrid/sendgrid-php.git # Web上に公開されているリポジトリの場合
Cloning into 'remote'...
warning: You appear to have cloned an empty repository.
中央リポジトリが別サーバに存在する場合、リポジトリが見えていないと以下のようなエラーが出力されます。
Cloning into 'remote'...
fatal: '/path/to/remote.git' does not appear to be a git repository
fatal: Could not read from remote repository.
このような状況が発生した場合は、中央リポジトリをドキュメントルートに置いて Web 上に公開するか、SSH 接続にてリポジトリを見つけます。
セキュリティの観点から、リポジトリは SSH 接続がお勧めです。
# 中央リポジトリを複製する
>git clone https://myserver.com/remote.git # Web上に公開されているリポジトリ
>git clone ssh://ec2-user@myserver.com:/path/to/remote.git # SSH接続(myserver.comにec2-userでSSH接続)
>git clone ssh://ec2-user@12.34.56.78:/path/to/remote.git # SSH接続(IP指定)
SSH 接続に公開鍵が必要な場合、以下のようなエラーが出力されます。
Cloning into 'remote'...
ec2-user@myserver.com: Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
fatal: Could not read from remote repository.
このような場合には、以下のように-c
オプションにてcore.sshCommand
を指定するか、SSH 接続のコンフィグファイルにあらかじめエイリアスを設定しておきます。
# 中央リポジトリを複製する
>git -c core.sshCommand="ssh -i ./keys/pubkey.pem" clone ec2-user@myserver.com:/path/to/remote.git
Cloning into 'remote'...
warning: You appear to have cloned an empty repository.
# エイリアスを指定
>vim /home/ec2-user/.ssh/config # CentOS ユーザec2-userの場合
>vim c:\Users\{ユーザ名}\.ssh\config # Windows
Host rep
Hostname myserver.com
User ec2-user
IdentityFile /path/to/keys/pubkey.pem
>git clone rep:/path/to/remote.git
Cloning into 'remote'...
warning: You appear to have cloned an empty repository.
remote
というディレクトリが作成され、その中にリポジトリの複製ができました。git remote
コマンドで確認します。
>cd /path/to/remote
>git remote -v
origin ec2-user@myserver.com:/path/to/remote.git (fetch)
origin ec2-user@myserver.com:/path/to/remote.git (push)
コミット前にユーザー名と Email アドレスを設定しておきましょう。
全ての Git のコミットにこの情報が付与されます。
# ユーザー名とEmailアドレスを設定する
>git config --local user.name "John Doe"
>git config --local user.email johndoe@example.com
ちなみに以下のエラーが出た場合は、configファイルのアクセス権を変えることで解決します。
Bad owner or permissions on /home/ec2-user/.ssh/config
fatal: The remote end hung up unexpectedly
>chmod 600 /home/ec2-user/.ssh/config
リポジトリの複製が完了したら、次は管理するファイルをコミットしましょう。git add
コマンドでインデックスに追加し、git commit
コマンドでコミットします。
>cd /path/to/remote
>cp /src/index.html . # index.htmlをコミットします
>git add .
>git commit -m "First Commit"
[master (root-commit) 8d19ac7] First Commit
1 file changed, 11 insertions(+)
create mode 100644 index.html
>git status
On branch master
Your branch is based on 'origin/master', but the upstream is gone.
(use "git branch --unset-upstream" to fixup)
nothing to commit, working tree clean
これでローカルリポジトリのmaster
ブランチにindex.html
がコミットされました。
次に中央リポジトリにコミット内容をpush
します。
>git push origin master
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Delta compression using up to 3 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 314 bytes | 314.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
To myserver.com:/path/to/remote.git
* [new branch] master -> master
下記のエラーが発生した場合は、中央リポジトリの存在するディレクトリ配下にアクセス権限がない状態ですので、アクセス権限を付与します。
error: remote unpack failed: unable to create temporary object directory
これで中央リポジトリのmaster
ブランチにソースファイルがpush
されました。git status
、git log
などのコマンドで確認します。
>git status
On branch master
Your branch is up to date with 'origin/master'.
nothing to commit, working tree clean
>git log
commit bb58af04e8501a2e71962478a217d51d19f16d0c (HEAD -> master, origin/master)
Author: John Doe <John@myserver.com>
Date: Wed Feb 3 11:53:53 2021 +0900
First Commit
中央リポジトリの方もpush
が反映されているか確認してみます。
>git log
commit bb58af04e8501a2e71962478a217d51d19f16d0c (HEAD -> master)
Author: John Doe <John@myserver.com>
Date: Wed Feb 3 11:53:53 2021 +0900
First Commit
ステージング環境、本番環境
(local, non-bare)
開発環境と同じく、まずは中央リポジトリをgit clone
コマンドで複製します。
>git clone ec2-user@myserver.com:/path/to/remote.git
Cloning into 'remote'...
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (3/3), done.
remote
というディレクトリが作成され、その中にリポジトリの複製ができました。
先ほどpush
したindex.html
も存在します。
>cd remote
>ls
index.html
各種コマンドで確認します。
>git remote -v
origin ec2-user@myserver.com:/path/to/remote.git (fetch)
origin ec2-user@myserver.com:/path/to/remote.git (push)
>git status
On branch master
Your branch is up to date with 'origin/master'.
nothing to commit, working tree clean
>git log
commit bb58af04e8501a2e71962478a217d51d19f16d0c (HEAD -> master, origin/master, origin/HEAD)
Author: John Doe <John@myserver.com>
Date: Wed Feb 3 11:53:53 2021 +0900
First Commit
開発環境から中央リポジトリへソースファイルの修正が行われた際、ステージング環境や本番環境にその修正を反映します。
通常、これらはフックを利用して自動的に行われます。
一般的にステージング環境はdevelop
ブランチ、本番環境はmaster
ブランチへのpush
を反映します。
>git pull origin develop # develoopブランチへのpushをステージング環境へ反映
>git pull origin master # masterブランチへのpushを本番環境へ反映
参考: Git ワークフロー(ブランチモデル)とその手順
参考: Git コンフリクトの解消
参考: Git のフックを利用したデプロイの方法
参考: git push を Chatwork や Slack へ通知する方法
コメント