基於OS X Server 搭建 Git 倉庫

任務:

# 配置可讀取Git倉庫
# 配置可寫入Git倉庫

# 配置 Gitweb

系統環境:

# OS X 10.9.2,系統自帶 Apache httpd , 版本 2.2.26 (Unix)
# OS X Server 3.1.1,爲了避免Server這個詞跟其他語境產生混淆,要是提到了OS X Server就用Server( app)替代
# Xcode 5.1,有了Xcode就有了Git,版本 1.8.5.2

描(tu)述(cao):

爲什麼要本地搭建Git服務器呢?代碼的版本管理、集中管理是必須的,雖然現在寫的代碼還不是什麼大項目,但是將代碼有條理的管理起來總是好的;虛擬機裏面還跑着3+個系統,Win7,XP都會用到,有了Git服務就可以將虛擬機的Git庫推送到主機,不用拷來拷去麻煩;最吸引眼球的是Gitweb,搭建好以後就打開瀏覽器就可以查看所有代碼,Get!
整個配置過程挺糾結的,主要是參考的資料太多、看的太雜,重點沒看到反而被繞了個大圈子(很多配置方法包括Git官方Book都能成功的略過各種重要細節,給跪了;當然,我承認我還有很多需要學習的地方)。不過話說回來,當你被各種天花亂墜的教程弄得暈頭轉向還是解決不了問題的時候,回到官方文檔纔是王道,雖然是英文的(爲什麼一開始不看官方文檔,一來文檔太多,動手之前都不知道該從哪裏看起;二來難懂啊!)。
另外就是Server(app)這個軟件,沒有Server(app)完全可以搭建起環境來,但是爲了作死,一定要用Server(app)來與系統進行高度整合,目的只是爲了用一下開關而已。這裏要注意的就是,Apple官網對Server(app)的描述有這麼一句話“它是如此簡單易用,以至於你不再需要IT部門”,這句話信息量巨大,你會發現,某些情況下修改好conf配置文件後,再回到Server(app)裏面進行某些配置的話,conf文件是會被覆蓋重寫的,所以要麼就單獨修改conf文件,要麼就在Server配置,當然也不用全部手動配置,呃,發現說不清楚了,文章後面提到再描述吧。


下面開始一步一步在Mac裏搭建本地的Git服務器

基本配置
  • 配置 Server(app)

打開Server(app),目前Websites服務的狀態是這樣的(默認是關閉的,這裏截圖截晚了,PHP默認也是關閉的)

wKiom1Nw8rSSeBfOAAKdkMaUcgI746.jpg

當前網站列表裏有兩個默認網站,一個80端口,一個443端口。看見默認網站就想刪?好的,開始折騰,最後你發現刪不了!修改配置文件也不行,刪除後自動又生成了,所以,要意識到現在用的是Server,不是Apache Httpd。不過通過上面是動作有如下收穫:

1、httpd服務的配置文件的路徑爲/Library/Server/Web/Config/apache2/httpd_server_app.conf,打開這個文件

#
# Mac OS X Server App
#
# When Server App is installed, this file is used instead of /etc/apache2/httpd.conf
......


也就是說這個配置文件已經替代了apache的httpd.conf。這裏只是說明在Server(app)中配置WEB服務應該到這個地方來改,不要去 /etc/apache2/裏面去找配置文件,因爲現在我們是在Server(app)中架設網站。對,只是說明而已,其實我們的整個過程都沒有修改過這個文件,最多就是查看而已,下面纔是需要修改的地方。


2、http服務的網站配置路徑爲 /Library/Server/Web/Config/apache2/sites,這個目錄下面就是之前看到的兩個默認網站的配置文件

  • 0000_any_80_.conf 對應80端口的網站(主戰場)

  • 0000_any_443_.conf 對應443端口的網站

  • ...

這兩個文件還有對應的以 .default 、.prev ,可能還有 .syntaxError 結尾的文件,這按名稱就可以知道其文件內容分別是默認配置、上一次配置、出錯的配置文件,這就是剛開始說的,如果你之前在conf文件裏面填寫過參數,然後又回到Server(app)裏面調整過參數的話,生效的conf文件就會被重寫,那麼之前你自己寫的配置文件就需要到prev裏面找。
其實我想表達的就是,我們可以在Server(app)裏面對要創建的網站做一個大概的配置(比如說新建網站),然後就不用理會這裏的其他選項,細節內容到conf裏面進行修改就可以。

繼續下面的操作

回到Server(app),將Websites服務的開關調到ON,在瀏覽器輸入 http://localhost,顯示如下內容說明服務正常

wKiom1Nw8tvDGZu6AAIuG3-1HLk771.jpg

查看日誌到 Server(app) Logs標籤,右側的左下角選擇 Error Log (Server Websites) 查看,跟Apache日誌是一致的。

既然默認網站刪不掉,那麼就在默認80端口網站上架設服務好了:
第一步,選擇網站路徑
假設網站的根目錄用如下文件夾(放GoogleDrive裏面是可以備份到網盤~~)
/Volumes/Macintosh/GoogleDrive/Website/

第二步,架設站點
選中Websites列表裏面80端口的默認網站,直接雙擊打開配置窗口,第一行,”Store Site Files In”後面的下拉列表點開,選中other..,彈出對話框選擇網站路徑 /Volumes/Macintosh/GoogleDrive/Website/,OK!僅此而已,可以點確定了。你會發現我們的網站根目錄下自動產生了幾個文件,這就是默認的html文件(但是是鏈接,也就是快捷方式),其他的html文件可以刪除,到 /Applications/Server.app/Contents/ServerRoot/usr/share/web/locales/zh_CN.lproj 找到原身 default.html,複製到我們的站點跟目錄,習慣性的重命名爲 index.html

第三步,修改conf文件(編輯虛擬主機)
sudo vim /Library/Server/Web/Config/apache2/sites/0000_any_80_.conf
注意:這裏爲了確保配置文件的有效更改,修改配置文件前將Web服務暫停,修改之後再開啓服務,即Server(app)裏面的OFF/ON開關
(這裏配置文件的內容跟Apache是一樣的語法)

修改文件內容如下:

<VirtualHost *:80>
#管理員郵箱,要想放上自己的郵箱就填上,可選
ServerAdmin [email protected]
#網站根路徑,第一步的內容
DocumentRoot "/Volumes/Macintosh/GoogleDrive/Website/"
#默認文件
DirectoryIndex index.html
#下面9行保持默認值
CustomLog "/var/log/apache2/access_log" combinedvhost
ErrorLog "/var/log/apache2/error_log"
<IfModule mod_ssl.c>
SSLEngine Off
SSLCipherSuite "ALL:!aNULL:!ADH:!eNULL:!LOW:!EXP:RC4+RSA:+HIGH:+MEDIUM"
SSLProtocol -ALL +SSLv3 +TLSv1
SSLProxyEngine On
SSLProxyProtocol -ALL +SSLv3 +TLSv1
</IfModule>
#設置站點根目錄屬性,注意紅色部分修改,把 ExecCGI 前面的 - 改爲 +,後面架設git服務需要使用CGI
<Directory "/Volumes/Macintosh/GoogleDrive/Website/">
Options All -Indexes +ExecCGI -Includes +MultiViews
AllowOverride All
<IfModule mod_dav.c>
DAV Off
</IfModule>
<IfDefine !WEBSERVICE_ON>
Deny from all
ErrorDocument 403 /customerror/websitesoff403.html
</IfDefine>
</Directory>
</VirtualHost>

開啓站點服務,瀏覽地址 http://localhost 目前站點如下所示,這裏只是開始,後面的Gitweb會出現在這裏(這個頁面完全可以自定義,不過看着好看,暫時留着吧)

wKiom1Nw8xKQ4KWsAAIdESQAQEI716.jpg


  • 配置 Git

這裏參考過 Git Book (http://git-scm.com/book/zh)。
第一步,創建Git倉庫
架設Git服務你肯定得有個git倉庫,倉庫跟工作目錄不一樣,是工作目錄下隱藏的 .git 裏面的內容。
一切從頭開始,先在桌面上創建一個文件夾 library,然後將這個文件夾初始化爲git庫:

Desktop $ mkdir library
Desktop $ git init library
//參數- - bare用來建立一個裸倉庫,當然也可以從一個已經存在的工作目錄中clone
Desktop $ git clone - - bare library library.git

得到了這個 library.git 庫,看似是一個文件夾,其實他是個git庫,而且千萬不要把它看做一個文件夾,這是來自404的忠告。

第二步,將Git倉庫移到站點目錄下
站點根目錄爲 /Volumes/Macintosh/GoogleDrive/Website/

爲了方便管理,在根目錄新建一個git文件夾,將剛纔的library.git放到裏面,現在的結構爲 /Volumes/Macintosh/GoogleDrive/Website/git/library.git


第三步,配置站點
基本思路:利用Git針對HTTP協議的CGI程序 git-http-backend 來實現智能的HTTP傳輸協議。
Git針對HTTP,有啞協議和智能協議兩種傳輸協議(具體說明參見git官方book的Git內部原理 > 傳輸協議),實際上這裏我是參考了《Git權威指南》這本書才知道有這麼一件事的。這裏採用智能協議,雖然說是這種協議效率不是很高,但本地用,基本不影響,再者,智能協議能夠顯示百分比。

現在的任務是找到這個 git-http-backend 在哪裏。就如剛開始強調的一樣,有了Xcode就有個Git,所以你會發現Git的核心程序文件在這裏:
/Applications/Xcode.app/Contents/Developer/usr/libexec/git-core/
使用 ln 命令,在 /usr/libexec/git-core 創建替身以便引用(快捷方式)
sudo ln -s /Applications/Xcode.app/Contents/Developer/usr/libexec/git-core/  /usr/libexec/git-core

基於前面的conf配置文件,繼續修改(添加)內容
sudo vim /Library/Server/Web/Config/apache2/sites/0000_any_80_.conf
添加部分如下,#後面的註釋可以忽略
# Git Setting
# 設置版本庫根目錄(爲了便於擴展,這裏指向的是前面的"git"目錄)
SetEnv GIT_PROJECT_ROOT "/Volumes/Macintosh/GoogleDrive/Website/git/"
# 設置所有版本庫均可訪問,話說是因爲默認情況下默認只有版本庫目錄中存在 git-daemon-export-ok 文件時,該版本庫纔可以訪問
SetEnv GIT_HTTP_EXPORT_ALL
# 設置 ScriptAlias ,有點CGI的意思,引用的正是我們上面的那個替身,可以理解爲 git 這個虛擬目錄指向 /usr/libexec/git-core/git-http-backend/
ScriptAlias /git/ /usr/libexec/git-core/git-http-backend/


第四部,站點目錄權限

權限!還是權限!萬惡的根源!
還記得我們的站點根目錄嗎?
/Volumes/Macintosh/GoogleDrive/Website/
現在我們把這個地方當作站點根目錄,也就是Apache Httpd服務的一個目錄,當我們通過瀏覽器訪問站點的時候,其實是以Apache Httpd的身份在訪問Website這個文件夾。爲了避免後面的問題,需要把根目錄權限設置爲755,Git倉庫還要支持上傳,權限設置爲775,問題是這權限給誰呢?別照搬網上的。打開 /Library/Server/Web/Config/apache2/httpd_server_app.conf ,找到以下內容:
User _www
Group _www
說明我們架設的站點是以用戶 "_www",組"_www" 的身份在訪問,現在知道權限給誰了吧。到站點根目錄的上一級,也就是 GoogleDrive 目錄運行命令,把整個站點的組改爲 _www
GoogleDrive $ sudo chgrp -R _www Website
設置git目錄權限爲組可寫
GoogleDrive $ chmod -R 775 Website/git

第五步,獲取與推送
經過上面的努力,現在終於可以測試成果了。
#將當前路徑定位到桌面
$ cd ~/Desktop
# 獲取Git倉庫副本
Desktop $ git clone http://localhost/git/library.git gitt
# 現在桌面上將產生一個 gitt 文件夾(剛開始手動創建的 library 文件夾可以清理掉)
到這一步我們的任務一已經基本完成,創建可讀取的Git倉庫
# 現在這個 gitt 文件夾就是我們的工作目錄,可以在裏面隨便寫點內容用於測試,例如touch一個index文件
Desktop $ cd gitt
gitt $ touch index
# 將index提交
gitt $ git add index
gitt $ git commit -m ’test’
# 將當前庫推送到git服務站點,運行push
gitt $ git push origin master
# 此時,不出意外會出現錯誤提示,查看日誌發現如下內容
Service not enabled: 'receive-pack’
# 這一點我表示某些指南上並沒有細說,可能是當時我理解的不夠透徹,又折騰許久發現要作如下配置
# 對服務站點的Git庫 /Volumes/Macintosh/GoogleDrive/Website/git/library.git 的屬性進行修改
git config --local http.receivepack true
# 也就是對 library.git 目錄下的 config 文件增加了如下內容,注意排版
[http]
     receivepack = true
# 原理是使用智能HTTP傳輸協議上傳數據的時候,Git 使用 send-pack 和 receive-pack 進程,send-pack 進程運行在客戶端,receive-pack運行在服務器端。

現在回到桌面的gitt工作目錄,再次推送
gitt $ git push origin master
結尾看到 master -> master’ 則說明推送成功。

現在任務二也基本完成了~


第六步,訪問控制
如果只在本地使用Git服務的話,以上的匿名訪問方式已經可以達到預期了;但是,對於追求完美主義的強迫症患者,或者身處局域網想保護自己的倉庫的話,需要對倉庫進行權限限制,這裏只涉及簡單的權限設置,太複雜的方式以後再折騰~

這種加密方式處於Apache層,跟系統目錄神馬的沒有關係。
使用Apache 的 htpasswd 創建用戶信息,將會產生一個文件,把這個文件和apache配置文件放到一個目錄下

# 最後面的 ’git’ 字符爲自己定義的用戶名
Desktop $ sudo htpasswd -m -c /Library/Server/Web/Config/apache2/git-user.htasswd git
# sudo 命令要求你輸入當前系統密碼,別搞混了,驗證通過之後纔是htpasswd提示 鍵入 ‘git’ 用戶的密碼
New password: (自定義的密碼爲git)
Re-type new password:

# 現在要加密的是我們的第一個git library,繼續編輯conf文件(配置完成後重啓站點服務)
sudo vim /Library/Server/Web/Config/apache2/sites/0000_any_80_.conf
# 還是在之前的基礎上添加如下內容,Location 標籤指向當前站點的相對目錄,目前只有一個library倉庫,多個倉庫就用多個Location標籤
## Auth
<Location /git/library.git>
AuthType Basic
AuthName "Git Access"
AuthUserFile /Library/Server/Web/Config/apache2/git-user.htpasswd
Require valid-user
</Location>

這裏暫時有個疑問,權限控制在終端裏面難道有緩存?多次測試後clone就不需要密碼了,用SourceTree這個客戶端來clone倒是需要驗證用戶信息的。


  • 配置GitWeb

我自己在剛開始弄這一步的時候,由於很傻很天真,爲了這個gitweb組件還各種下源代碼各種編譯,後來知道真心的我眼淚掉下來,這貨好好的放在xcode裏面呢!( ⊙ o ⊙ )
由於後面需要修改cgi文件,所以將Xcode裏面的gitweb拷貝出來

sudo cp -r /Applications/Xcode.app/Contents/Developer/usr/share/gitweb /var/www/cgi-bin/


修改站點配置文件,增加如下內容

# Gitweb Setting
     Alias /gitweb /var/www/cgi-bin/gitweb/
     <Directory /var/www/cgi-bin/gitweb/>
          Options ExecCGI +FollowSymLinks +SymLinksIfOwnerMatch
          AddHandler cgi-script cgi
          DirectoryIndex gitweb.cgi
          AllowOverride All
          Order Allow,Deny
          Allow from all
     </Directory>

依然和上一步一樣,引用同一個git-user.htpasswd文件對站點進行簡單訪問限制,這裏是對瀏覽器的訪問限制,比較直觀,在配置文件裏面增加如下內容

<Location /gitweb>
          AuthType Basic
          AuthName "Git Access"
         AuthUserFile /Library/Server/Web/Config/apache2/git-user.htpasswd
          Require valid-user
</Location>


打開瀏覽器,測試當前配置,要求輸入密碼,輸入驗證信息git/git

wKioL1Nw8_ihQZDmAADDSKbvSIw509.jpg

看到如下404提示,說明距離成功已經不遠了。

wKiom1Nw9DTAPrmHAAB1qn--uGI126.jpg

打開/var/www/cgi-bin/gitweb/gitweb.cgi這個文件,定位到第686行,即
our $GITWEB_CONFIG_SYSTEM = $ENV{'GITWEB_CONFIG_SYSTEM'} || “/etc/gitweb.conf”;


同樣的,gitweb的多個配置文件是有順序的,目前我們只需要在 /etc/gitweb.conf 這個文件裏面進行配置就可以,當然也可以定位到其他地方。一般情況下這個文件是不存在的,這裏就按照默認到/etc/目錄下,新建gitweb.conf文件,作如下編輯

注:projectroot 參數指向站點的git目錄,不要指向library.git,不然就404了;GIT 參數跟前面保持一致,指向/usr/libexec/git-core/git,前面那個是目錄,所以結尾帶斜槓,後面的是指向了git這個文件
# path to git projects (<project>.git)
$projectroot = "/Volumes/Macintosh/GoogleDrive/Website/git/";
# Git bin root
$GIT = "/usr/libexec/git-core/git";


配置好路徑之後,刷新頁面即可看到項目列表。


如果項目路徑中有中文字符,點擊瀏覽的時候可能會看不到,解決方法如下:

把gitweb.cgi中所有 file_name=>”$basedir$t->{‘name’}” 替換爲 file_name=>”$basedir” . to_utf8($t->{‘name’}) 即可。

引用自:http://blog.mylover.cn/2014/01/關於gitweb中中文文件名亂碼及代碼高亮的問題

需要注意的是,替換的時候覈對一下字符是不是全部匹配,不出意外應該是要替換9個地方。


另外localhost帶地球那個頁面,也就是index.html那個文件,可以自己修改,加入Giteweb的鏈接,這是html的內容,作相應修改就可以了。

wKiom1Nw9H2zR0-cAAFTYtjtVtQ521.jpg


PS: 從EverNote裏面複製出來的筆記,儘量保持版面整齊,越到後面寫的越趕了,主要是時間拖的太久,要是能給同樣在糾結這個東西的人提供一點小建議那就很欣慰了。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章