阅读本文前你必须预先装好CentOS并且已经安装和配置好Nginx了。
安装GIT私服套件
- 安装centos6.5-centos7.0
- 安装Nginx
- yum install -y?git gitweb spawn-fcgi?fcgi-devel?fcgi
以上步骤执行完毕后,我们安装了:
- git服务
- Gitweb,因为git是一个光板,只支持 git clone gituser@hostname:/repositories这样的协议,对于eclipse开发者来说键入一堆的git 命令将会是一个恶梦,因此我们必须有一个图形化的界面并且让git支持http协议来支持我们的“远程协作 ”
- spawn-fcgi,这个东西特别有意思,因为Nginx默认是不支持cgi的,而gitweb是用cgi写的,因此我们才安装fastcgi,而fastcgi又要通过spawn-fcgi来启动。。。因此。。。必须要装spawn-fcgi。
- fcgi-devel 和 fcgi都属于fastcgi运行时的lib库了
安装fcgiwrap
从以下网址下载该组件:https://codeload.github.com/gnosek/fcgiwrap/legacy.tar.gz/master
运行以下命令:
全部安装完后注意检查以下必要文件是否存在
运行以下命令:
cdfcgiwrap autoreconf -i Configure Make make install
全部安装完后注意检查以下必要文件是否存在
- /etc/init.d 目录下有一个spawn-fcgi程序
- /usr/bin 目录下有一个spawn-fcgi程序
- /var/www/git目录下是gitweb所有的文件(网页版git)
- /etc/目录下有一个gitweb.conf文件
- /etc/sysconfig/目录下有一个spawn-fcgi文件
开始配置GIT私服-修改/etc/gitweb.conf文件
$projectroot = "/home/git/repositories"; @git_base_url_list= ("git://192.168.0.101","http://192.168.0.101:81"); $git_temp = "/tmp"; $home_text = "indextext.html"; @stylesheets = ("gitweb.css"); $javascript = "gitweb.js"; @diff_opts = (); $feature{pathinfo}{default} = [1]; $feature{'highlight'}{'default'} = [1];
以上配置做了这么几件事:
- 所有的git的子项目:如“hello.git”全部位于/home/git/repositories目录下
- Git的常用两种协议对外暴露的URL:
- 一个使用的是git协议
- 一个使用的是http协议,并且它的端口号为81
开始配置GIT私服-修改/etc/sysconfig/spawn-fcgi文件
# You must set some working options before the "spawn-fcgi" service will work. # If SOCKET points to a file,then this file is cleaned up by the init script. # # See spawn-fcgi(1) for all possible options. # # Example : #SOCKET=/var/run/PHP-fcgi.sock #OPTIONS="-u apache -g apache -s $SOCKET -S -M 0600 -C 32 -F 1 -P /var/run/spawn-fcgi.pid -- /usr/bin/php-cgi"
以上是原来文件的内容
# You must set some working options before the "spawn-fcgi" service will work. # If SOCKET points to a file,then this file is cleaned up by the init script. # # See spawn-fcgi(1) for all possible options. # # Example : #SOCKET=/var/run/PHP-fcgi.sock #OPTIONS="-u apache -g apache -s $SOCKET -S -M 0600 -C 32 -F 1 -P /var/run/spawn-fcgi.pid -- /usr/bin/php-cgi" FCGI_SOCKET=/var/run/fcgiwrap.socket FCGI_PROGRAM=/usr/local/sbin/fcgiwrap FCGI_USER=Nginx FCGI_GROUP=Nginx FCGI_EXTRA_OPTIONS="-M 0700" OPTIONS="-u $FCGI_USER -g $FCGI_GROUP -s $FCGI_SOCKET -S $FCGI_EXTRA_OPTIONS -F 1 -P /var/run/spawn-fcgi.pid -- $FCGI_PROGRAM"
启动spawn-fcgi
chkconfig --levels 2345 spawn-fcgi on /etc/init.d/spawn-fcgi start
把spawn-fcgi设为开机启动,并启动该服务,该服务成功启动后会在:
配置GIT服务器-初始化GIT服务
useradd gitpasswd git su git #切换到git用户 mkdir repositories #会在/home/git目录下建立repositories目录 #开始建立git的root repositories mkdir /home/git/.ssh cd /home/git/.sshssh-keygen -t rsa git gitosis-init < ~/.ssh/id_rsa.pub
以上做的事情就是:
1. 生成的gitosis-admin为Git的用户访问权限管理库,gitosis通过这个git库来管理所有git库的访问权限。
2. 通过执行初始化,该公钥的拥有者就能修改用于配置gitosis的那个特殊Git仓库了
因为git中的密钥就是通过gitosis这个特殊的repo来管理的。有了它我们就可以管理我们的GIT,包括建子项目什么的了。
配置GIT服务器-建子项目
su git cd repositories mkdir hello.git cd hello.git git --bare init sudo chmod 777 /home/git/repositories/hello.git –R
让这个目录具有读写执行权限,你也可以把权限放的小一些,如chmod +x类似的,只要让这个目录可以有读、写、执行(git特殊的unpack,pack功能)权限就可以了。
以上就是建立了一个GIT子项目,名字叫hello,我们来看看/home/git/repositories下的 hello.git这个项目吧
配置GIT服务器-使用其它用户推拉hello.git
useradd ymk passwd ymk cd /home/ymk mkdir git_repo cd git_repo mkdir hello.git cd hello.git git init
上面就在“客户端 ”初始化好了一个workspace了,此时我们可以进行“远程GIT服务”的推拉了。
touch readme #新建一个readme文本文件 vi readme #随便在此文件中写点什么然后保存退出即可 git add . 代表把当前目录内所有东西进行远程推送 git commit -a -m “init helloworld“ #代表commit所有之前add过的东东,并且带上commit时的注释 git remote add origin git@192.168.1.101:/home/git/repositories/hello.git #建立远程GIT连接 git push origin master #正式推送
看到一堆推送日志后,并看到OK, SUCCESS字样后即代表push成功了。下面就是要让我们的GIT具有基于http协议进行推送的配置了。
配置GIT服务器-配置GITWEB + Nginx
server { error_log logs/git.error.log; access_log logs/git.access.log; listen 81; server_name 192.168.0.101; index gitweb.cgi; root /home/git; location ~ \.(cgi|pl).*$ { gzip off; fastcgi_pass unix:/var/run/fcgiwrap.socket; fastcgi_param SCRIPT_FILENAME /home/git/gitweb.cgi; fastcgi_param SCRIPT_NAME gitweb.cgi; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } location ~ ^.*\.git/objects/([0-9a-f]+/[0-9a-f]+|pack/pack-[0-9a-f]+.(pack|idx))$ { root /home/git; } location ~ ^.*\.git/(HEAD|info/refs|objects/info/.*|git-(upload|receive)-pack)$ { root /home/git; fastcgi_param QUERY_STRING $query_string; fastcgi_param SCRIPT_FILENAME /usr/libexec/git-core/git-http-backend; fastcgi_param GIT_HTTP_EXPORT_ALL true; fastcgi_param GIT_PROJECT_ROOT /home/git/repositories; fastcgi_param PATH_INFO $uri; include fastcgi_params; fastcgi_pass unix:/var/run/fcgiwrap.socket; } try_files $uri @gitweb; location @gitweb { fastcgi_pass unix:/var/run/fcgiwrap.socket; fastcgi_param SCRIPT_FILENAME /var/www/git/gitweb.cgi; fastcgi_param PATH_INFO $uri; fastcgi_param GITWEB_CONFIG /etc/gitweb.conf; include fastcgi_params; }
这么一大陀配置,你可以全部复制、粘贴,因为网上所有GIT WEB的配置,全部是错的,这一陀已经在本地GIT私服上运行起来了,少一行多一行都不行。下面就来做一些核心语句块的解释吧,注意 红色加粗部分(我就喜欢粗)
server { error_log logs/git.error.log; access_log logs/git.access.log; listen 81; server_name 192.168.0.101; index gitweb.cgi; root /home/git;
我们把我们的gitweb的http服务申明在了81网段,gitweb的主页叫gitweb.cgi。
location ~ \.(cgi|pl).*$ { gzip off; fastcgi_pass unix:/var/run/fcgiwrap.socket; fastcgi_param SCRIPT_FILENAME /home/git/gitweb.cgi; fastcgi_param SCRIPT_NAME gitweb.cgi; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } location ~ ^.*\.git/objects/([0-9a-f]+/[0-9a-f]+|pack/pack-[0-9a-f]+.(pack|idx))$ { root /home/git; }
location ~ ^.*\.git/(HEAD|info/refs|objects/info/.*|git-(upload|receive)-pack)$ { root /home/git; fastcgi_param QUERY_STRING $query_string; fastcgi_param SCRIPT_FILENAME /usr/libexec/git-core/git-http-backend; fastcgi_param GIT_HTTP_EXPORT_ALL true; fastcgi_param GIT_PROJECT_ROOT /home/git/repositories; fastcgi_param PATH_INFO $uri; include fastcgi_params; fastcgi_pass unix:/var/run/fcgiwrap.socket; } try_files $uri @gitweb; location @gitweb { fastcgi_pass unix:/var/run/fcgiwrap.socket; fastcgi_param SCRIPT_FILENAME /var/www/git/gitweb.cgi; fastcgi_param PATH_INFO $uri; fastcgi_param GITWEB_CONFIG /etc/gitweb.conf; include fastcgi_params; }
以上两段做了这么两件事 :git通过http传输时会调用git-upload和git-receive或者是git-pack、git-unpack函数,因此它们会使用到一个git的类库,叫git-http-backend,因此只要url中出现git-pack、git-upload、git-receive之类的函数都会转到git-http-backend去处理。
try_files呢?即除了前面三段定义的客户浏览器端行为,其它未在定义中说明的任何请求全部走try_files段,相当于一个default的关键字。比如说: http://192.168.0.101:81/hello.git 就会被转到try_files段去。
因为在前面三段我们都只是申明客户的何种行为将要去哪找相关的类库,而只有一处就是对于git-upload,git-receive或者是git-pack/unpack的请求,我们会让NG交由git服务端的类库去处理,并未明确告诉*.git和其它的相关的请求由谁处理,因此这边来了一个try_files也是一种“简写”-当然,有更好的更精细的办法来做URL申明,可以自己去练习一下。
NG配置好了后,我们先不要急着启NG。我们先来了解一下GIT基于HTTP推送的相关原理:
客户端通过ECLIPSE的JGIT连上GIT的远程服务后会发送一个git-upload指令。
同时服务端会回一个git-receive给到客户端做“接收”请求的准备,但是git服务默认对于这个receive的值为false,因此如果你没有做特殊处理后,在eclipse连上git后会发生一个can not find git-receive这样的错误,解决办法是:
客户端通过ECLIPSE的JGIT连上GIT的远程服务后会发送一个git-upload指令。
同时服务端会回一个git-receive给到客户端做“接收”请求的准备,但是git服务默认对于这个receive的值为false,因此如果你没有做特殊处理后,在eclipse连上git后会发生一个can not find git-receive这样的错误,解决办法是:
su git cd /home/git/repositories/hello.git git config --file config http.receivepack true
这条命令发送后我们来看一下GIT服务器上的/home/git/repositories/hello.git/config这个文件的内容吧
一切准备就绪后,启动Nginx。
cd /usr/local/Nginx ./Nginx –c /usr/local/Nginx/Nginx.conf
在客户端用浏览器打开http://192.168.0.101:81网址你会看到这样的画面