centOS7 搭建自己的git服务器

很多时候考虑到企业项目可维护性,大家还是希望拥有自己的代码版本库,github、gitee都是不错的选择,但是完全依赖于这些平台,对代码安全性总有疑虑,也不利于自己团队在版本管理上的成长。gitee企业版今天也出了点小问题,登录后总提示500错误。于是考虑了落实自建git服务器的计划。

Git服务器搭建过程

参考文章:

Aaron的个人技术博客 CentOS7搭建git 服务器。
正如Aaron所说,这个方案适合于自己开发,自己使用,遇到团队作战时,管理起来就不那么方便灵活了。但是熟悉Git服务器搭建过程,是继续团战的基础。本文会根据Aaron和Git中文网的资料,进行团战搭建的介绍。

本文是实践总结,主要记录按照上述文章实际搭建中遇到的问题。

  1. yum 安装 git
# yum install git
  • 备注:网上有很多从源码安装的例子,我实操下来感觉不是很有必要,yum库安装速度快,还可以避免一些目录和权限的问题,所以推荐直接yum 安装 git。
  1. 确认git版本
# git --version
git version 1.8.3.1
  • 备注:CentOS7 自带了1.8.3.1
  1. 添加git用户组和git用户
# groupadd git
# adduser git -g git
# passwd
  • 备注1:原文只使用 adduser git,但实际上他也是创建了git组的,我还是老老实实用了上面这串命令
  • 备注2:passwd执行后,要求输入密码,就是给git账号设置密码
  1. 创建git工作目录
# mkdir -p /home/git/.ssh
# chmod 700 /home/git/.ssh
# chown -R git:git /home/git
  • 备注:加上-p支持 mkdir创建多级目录
  1. 创建用户公钥保存的文件
# touch /home/git/.ssh/authorized_keys
# vi /home/git/.ssh/authorized_keys
  • 备注1:添加用户公钥时,要一行一个。
  • 备注2:windows下获取ssh公钥的方法,可在git客户端的git bash下执行如下的命令
# ssh-keygen
  • 备注3:上面的命令可以一路yes,一路默认,不输入密码。最终在windows的用户目录下的.ssh目录下,可以找到id_rsa.pub,把内容copy出来,一行一个用户的粘贴到上面的文件中即可。
  1. 创建测试代码库
# cd /home
# git init --bare test.git
Initialized empty Git repository in /home/test.git/
# chown -R git:git test.git
# ll
total 0
drwxr-xr-x  7 git     git     119 Jan 27 22:44 test.git
  1. 设置git用户只能登录执行git-shell,且每次都要登录
# vi /etc/passwd

找到git:x开头的那行改为

git:x:1001:1001:,,,:/home/git:/usr/bin/git-shell
  • 备注:上面这里的/usr/bin/git-shell是你的git-shell所在的目录,如果用yum安装git,应该就是在这个目录,如需要确认,可执行下面的命令查找
# find / | grep git-shell
find: ‘/proc/1831’: No such file or directory
/usr/bin/git-shell
/usr/share/doc/git-1.8.3.1/contrib/git-shell-commands
  1. 本地电脑远程克隆test.git测试
    这里给出两个方案:
    方案1: 如果你的ssh端口号没有变动,可能下面的命令已经可以执行了,我自己的服务器是改了ssh端口号的,所以我不知道下面的命令是否可以正常执行
# git clone git@服务器IP地址:/home/test.git
Cloning into 'test'...
warning: You appear to have cloned an empty repository.

方案2: 如果你的ssh端口号变了,要按照下面的命令来执行,才能成功。这也是我一开始没搞定的原因,特此记录。

# git clone ssh://git@服务器IP地址:ssh端口/home/test.git
Cloning into 'test'...
The authenticity of host '[服务器IP]:ssh端口 ([服务器IP]:ssh端口)' can't be established.
ECDSA key fingerprint is SHA256:************************************************.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[服务器IP]:ssh端口' (ECDSA) to the list of known hosts.
warning: You appear to have cloned an empty repository.
  • 备注:至此,git服务器搭建完成了,我们还要把自己的git库传到服务器上去,这个问题等一会儿会讲。

增加Gitosis管理,方便团队化作战

安装Gitosis

恭喜你,经过刚才的实践,你已经掌握了Git服务器的搭建方法。上面的方案有三个问题:

  1. git clone 的远程git路径,是全路径,相对来说记忆比较困难。
  2. 用户的添加是通过修改/home/git/.ssh/authorized_keys,人员增加后维护起来就比较麻烦。
  3. 这个问题应该比较关键。 git仓库无法进行多项目的权限控制,一旦增加人员,就自动获取了全部项目的代码访问权限。

为了解决上述问题,Gitosis应运而生了。

Gitosis 主要解决两个问题:

  1. 相对路径问题
  2. 项目的分组管理和人员授权访问问题。

还是先进行安装实践,我会结合实际情况,介绍解决遇到的一些问题。

  1. 安装python依赖
    Gitosis 的工作依赖于某些 Python 工具,所以首先要安装 Python 的 setuptools 包
# yum install python-setuptools

1.1 (补充) 执行上面的命令时,在一个新的阿里云服务器上出了问题

Installed /usr/lib/python2.7/site-packages/gitosis-0.2-py2.7.egg
Traceback (most recent call last):
  File "setup.py", line 64, in 
    'setuptools>=0.6c5',
  File "/usr/lib64/python2.7/distutils/core.py", line 152, in setup
    dist.run_commands()
  File "/usr/lib64/python2.7/distutils/dist.py", line 953, in run_commands
    self.run_command(cmd)
  File "/usr/lib64/python2.7/distutils/dist.py", line 972, in run_command
    cmd_obj.run()
  File "/usr/lib/python2.7/site-packages/setuptools/command/install.py", line 73, in run
    self.do_egg_install()
  File "/usr/lib/python2.7/site-packages/setuptools/command/install.py", line 101, in do_egg_install
    cmd.run()
  File "/usr/lib/python2.7/site-packages/setuptools/command/easy_install.py", line 380, in run
    self.easy_install(spec, not self.no_deps)
  File "/usr/lib/python2.7/site-packages/setuptools/command/easy_install.py", line 604, in easy_install
    return self.install_item(None, spec, tmpdir, deps, True)
  File "/usr/lib/python2.7/site-packages/setuptools/command/easy_install.py", line 655, in install_item
    self.process_distribution(spec, dist, deps)
  File "/usr/lib/python2.7/site-packages/setuptools/command/easy_install.py", line 701, in process_distribution
    distreq.project_name, distreq.specs, requirement.extras
TypeError: __init__() takes exactly 2 arguments (4 given)

搜索后确认,是yum 安装的setuptools 版本不对

# ll /usr/lib/python2.7/site-packages/
drwxr-xr-x   5 root root   4096 Mar  4 23:29 setuptools
drwxr-xr-x   2 root root   4096 Mar  4 23:29 setuptools-0.9.8-py2.7.egg-info
-rw-r--r--   1 root root 793874 Mar  5 00:10 setuptools-33.1.1-py2.7.egg
drwxr-xr-x   2 root root   4096 Nov 29 11:40 setuptools-36.4.0.dist-info
-rw-r--r--   1 root root     30 Mar  5 00:10 setuptools.pth

网上的解决方案是 删除 该目录下 所有的 setuptools文件夹,然后再重新安装

# yum remove python-setuptools
# rm /usr/lib/python2.7/site-packages/setuptool* -rf

用pip重新安装 setuptools

# wget https://bootstrap.pypa.io/ez_setup.py
--2019-03-05 00:09:44--  https://bootstrap.pypa.io/ez_setup.py
Resolving bootstrap.pypa.io (bootstrap.pypa.io)... 151.101.228.175, 2a04:4e42:36::175
Connecting to bootstrap.pypa.io (bootstrap.pypa.io)|151.101.228.175|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 12537 (12K) [text/x-python]
Saving to: ‘ez_setup.py’

100%[=============================================================================================================>] 12,537      --.-K/s   in 0.07s

2019-03-05 00:09:45 (177 KB/s) - ‘ez_setup.py’ saved [12537/12537]

#  python ez_setup.py
ez_setup.py is deprecated and when using it setuptools will be pinned to 33.1.1 since it's the last version that supports setuptools self upgrade/installation, check https://github.com/pypa/setuptools/issues/581 for more info; use pip to install setuptools
Downloading https://pypi.io/packages/source/s/setuptools/setuptools-33.1.1.zip
Extracting in /tmp/tmpi_jCtH
Now working in /tmp/tmpi_jCtH/setuptools-33.1.1
...
Installed /usr/lib/python2.7/site-packages/setuptools-33.1.1-py2.7.egg
Processing dependencies for setuptools==33.1.1
Finished processing dependencies for setuptools==33.1.1
# easy_install-2.7 pip
Searching for pip
Best match: pip 18.1
Adding pip 18.1 to easy-install.pth file
Installing pip script to /usr/bin
Installing pip3.7 script to /usr/bin
Installing pip3 script to /usr/bin

Using /usr/lib/python2.7/site-packages
Processing dependencies for pip
Finished processing dependencies for pip
# pip2.7 install --upgrade pip
Looking in indexes: http://mirrors.aliyun.com/pypi/simple/
Collecting pip
  Downloading http://mirrors.aliyun.com/pypi/packages/d8/f3/413bab4ff08e1fc4828dfc59996d721917df8e8583ea85385d51125dceff/pip-19.0.3-py2.py3-none-any.whl (1.4MB)
    100% |████████████████████████████████| 1.4MB 73.7MB/s
Installing collected packages: pip
  Found existing installation: pip 18.1
    Uninstalling pip-18.1:
      Successfully uninstalled pip-18.1
Successfully installed pip-19.0.3
# rm /usr/lib/python2.7/site-packages/setuptool* -rf
# python -m pip install --upgrade pip setuptools wheel
DEPRECATION: Python 2.7 will reach the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 won't be maintained after that date. A future version of pip will drop support for Python 2.7.
Looking in indexes: http://mirrors.aliyun.com/pypi/simple/
Requirement already up-to-date: pip in /usr/lib/python2.7/site-packages (19.0.3)
Collecting setuptools
  Downloading http://mirrors.aliyun.com/pypi/packages/d1/6a/4b2fcefd2ea0868810e92d519dacac1ddc64a2e53ba9e3422c3b62b378a6/setuptools-40.8.0-py2.py3-none-any.whl (575kB)
    100% |████████████████████████████████| 583kB 52.2MB/s
Collecting wheel
  Downloading http://mirrors.aliyun.com/pypi/packages/96/ba/a4702cbb6a3a485239fbe9525443446203f00771af9ac000fa3ef2788201/wheel-0.33.1-py2.py3-none-any.whl
Installing collected packages: setuptools, wheel
  Found existing installation: wheel 0.29.0
    Uninstalling wheel-0.29.0:
      Successfully uninstalled wheel-0.29.0
Successfully installed setuptools-40.8.0 wheel-0.33.1

最后得到 setuptools-40.8.0 这个版本
再次执行

# python setup.py install

安装成功

  1. 获取 Gitosis 源码,并安装
# git clone https://github.com/tv42/gitosis.git
# cd gitosis
# python setup.py install
  • 备注: 这会安装几个供 Gitosis 使用的工具。默认 Gitosis 会把 /home/git 作为存储所有 Git 仓库的根目录。
  1. 修改git账号的权限
# vi /etc/passwd

找到 git:x: 开头那行,改回

git:x:1001:1002::/home/git:/bin/bash
  • 备注:上一段,我们直接用Git服务器时,为了避免git账户的非法登录,我们改成每次必须登录,命令行为git命令行的方式。但是由于gitosis需要的系统命令更多,所以还是必须要改回bin/bash的模式
  1. 清掉/home/git/.ssh/authorized_keys
# rm -rf /home/git/.ssh/authorized_keys
# touch /home/git/.ssh/authorized_keys
# chown -R git:git /home/git/
  • 备注:因为Gitosis需要接管Git服务器的授权访问控制,所以authorized_keys将由Gitosis来维护,为了避免控制面的冲突,我们需要清掉authorized_keys,重新通过Gitosis来创建用户。不用担心之前的访问权限丢失,下一步将之前的账号加回来之后,权限自然恢复。
  1. 初始化Gitosis
    准备工作:用ftp或其他将你的id_rsa.pub,ssh公钥文件上传的git服务器,假设位置在/tmp/id_rsa.pub。
    然后还是在刚才的Gitosis源码目录下
# su - git
# gitosis-init < /tmp/id_rsa.pub
# cd ~
# ll
total 0
drwxr-xr-x 2 git git  27 Jan 28 01:28 gitosis
drwxr-xr-x 8 git git 124 Jan 28 01:37 repositories
  • 备注:这里我执行时,只遇到过权限导致的问题,解决方案就是 回到 root账号下,执行 chown -R git:git /home/git/
  1. 总结一下,上面干了什么

主要工作是:

  1. 利用Python安装好了Gitosis的环境
  2. 利用 /tmp/id_rsa.pub 初始化了一个管理Gitosis的账户

一切的真相在你打开 /home/git/.ssh/authorized_keys 后就知晓了。

# vi /home/git/.ssh/authorized_keys

你会看到刚才被我们清掉的authorized_keys文件里,被导入了id_rsa.pub的内容,但是和我们自己的写入的时候有所差异

### autogenerated by gitosis, DO NOT EDIT
command="gitosis-serve 用户名",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-rsa xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 

管理Gitosis

刚才我们安装Gitosis后,发现/home/git下多了两个目录

# ll
total 0
drwxr-xr-x 2 git git  27 Jan 28 01:28 gitosis
drwxr-xr-x 8 git git 124 Jan 28 01:37 repositories

重要的目录只有一个repositories,这里面存储以后我们所有的项目的git仓库文件

# cd /home/git/repositories
# ll
total 0
drwxr-x--- 7 git git 139 Jan 28 01:28 gitosis-admin.git

目前这个目录下只有一个文件夹gitosis-admin.git,这就是Gitosis自带的管理工具了,接下来我们需要把这个工具clone到本地,来管理一下Gitosis

  1. clone Gitosis-admin
    在你刚才获得id_rsa.pub的那台电脑,一般就是你的工作机吧。
# git clone git@服务器IP:gitosis-admin.git

如果是ssh端口号改变的情况

# git clone ssh://git@服务器IP:ssh端口号/gitosis-admin.git
  • 备注1:注意到吗?gitosis-admin.git的并没有使用全路径来获取。如果你执行上面的命令成功了,说明你已经可以使用相对路径来访问git仓库了
  • 备注2:如果你遇到错误:fatal: '/gitosis-admin.git' does not appear to be a git repository ,也就是相对路径不生效。原因只是因为你可能没有清空/home/git/.ssh/authorized_keys,该文件里有不是Gitosis标准的公钥配置存在,导致了Gitosis出错了。方法就是删掉authorized_keys,走刚才的安装Gitosis时的第5步,重新初始化一下他,一般问题就解决了。
  1. clone成功,怎么通过gitosis-admin就能管理Gitosis和Git呢?

原理:gitosis-admin 通过gitosis.conf来配置项目组、用户组和权限关系,通过keydir目录保存用户的公钥,通过git提交实现对Gitosis服务配置的更新维护。

看一下gitosis-admin的目录

# dir
2019/01/28  01:15              .
2019/01/28  01:15              ..
2019/01/28  01:22               365 gitosis.conf
2019/01/28  01:21              keydir
  1. 编辑gitosis.conf,实现项目和用户管理
[gitosis]

// gitosis-admin的可访问用户设置
[group gitosis-admin]
writable = gitosis-admin  // 可读写的工程项目
members = Administrator  // 这里名字和keydir目录下的pub文件名字要保持一致,也就是说keydir目录下要有一个名为 Administrator.pub 的文件

// 组可以只有用户而没有工程项目,这种可以方便的对项目的访问权限进行用户群组管理
[group developer]
members = tom Jams KK // 开发组,完整的读写权限

[group tester]
member = miya lucy lily //测试组,只需要只读权限

// 工程项目实例
[group test1]
writable = test1 // 可读写的工程项目
member = @developer // 三个开发组成员将同时具有该项目的读写权限。

[group test1_readonly]
readonly = test1 // 只读权限
member = @tester Jack // 三个测试组成员和Jack可以克隆和获取更新,但 Gitosis 不会允许他向项目推送任何内容。
  1. 小结
    通过上面的工作,我们搞定了Gitosis管理Git服务器。Gitosis利用Git本身非常巧妙的实现了控制Git服务器的目的。

如何将已有git代码迁移到自己的git服务器

这部分估计很多人都有经验了,但是我还是记录一下,让这个经验总结有头有尾,方便大家查看。

  1. 将本地代码的变更及时缓存起来
# git add .
# git commit -m "init own git server"
  1. 在git服务器上创建空白仓库
# cd /home/git/repositories
# mkdir 仓库名.git
# cd 仓库名.git
# git init --bare
  1. 利用Gitosis赋予仓库访问权限
# vi gitosis-admin/gitosis.conf

将内容编辑为

[gitosis]

[group gitosis-admin]
members = administrator
writable = gitosis-admin

[group common]
members = Jack

[group 仓库名]
members = @common
writable = 仓库名

提交变更

# cd gitosis-admin
# git add .
# git commit -m "添加仓库"
# git push
  • 备注:到这里,仓库名.git就能够用Jack的账户进行远程更新和上传了。
  1. 修改本地代码的git remote,将代码上传到git服务器
# git remote remove origin
# git remote add origin ssh://git@服务器IP:ssh端口/仓库名.git
# git push -u origin master
# git pull
# git branch --set-upstream-to=origin/master master
# git pull

这里,Jack的本地代码和git服务器的代码就关联起来了。

你可能感兴趣的:(centOS7 搭建自己的git服务器)