问题
之前团队一直用的Subversion来管理代码的,开发的时候还OK,但是到了上线后,问题就开始出现,往往发布了一个版本后,代码又有一部分提交,同时可能引进一些新的Bug,再发包的时候,又有新的Bug,很不爽。本身SVN的分支管理不好用,我就强烈推荐Git,之前也一直在用,直接在服务器上开SSH端口就OK,但是权限管理又是一个问题啊,又找了一些Git权限管理的东东,但都太理想。后来想是不是有Github一样的东东,后来就发现了Gitlab,但是这货太耗资源,而且搭建起来也不容易,其他人去维护它就很困难。后来一顿放狗搜,找到了一个比较好的替代Gogs,上周末两天基本就在搞这货,使用起来也是很不错的。花时间的部分主要是与主机共享22端口的问题。
现在服务器那边的环境是,服务器位于防火墙后面,防火墙只开了有限供外网使用的端口,所以Gogs必须在某个共用端口的子目录下进行访问,比如domain.com/git/
。防火墙8888端口映射到服务器4444端口,然后服务器4444端口再映射到Gogs Container的3000端口。
Docker Gogs安装
其实用Docker来安装Gogs很简单,直接参考官方的文档主OK了。
1 2 3 4 5 6 7 8 9 10 11 12 13
| $ docker pull gogs/gogs
$ mkdir -p /var/gogs
$ docker run --name=gogs -p 10022:22 -p 10080:3000 -v /var/gogs:/data gogs/gogs
$ docker run --name gogs -p 3000:3000 -p 10022:22 --link mysql:db -v /opt/my_gogs:/data -e "PUID=1002" -e "PGID=1002" -d gogs/gogs
$ docker start gogs
|
其中我运行Gogs的时候加了一些东西。将前端端口映射到Host的3000端口,将Container的SSH端口22映射到Host的1022端口,然后将另一个mysql的Container链接到Gogs,这样可以直接访问MySQL,然后就是将Gogs的配置文件和其它工作文件链接到Host的gogs目录下,然后就是设置Gogs Containerm里面git用户的uid和gid。如果不设置uid和gid的话,container默认的是1000,一般情况下都不是我们想要的结果。一般是在Host新建一个git的用户,将container的uid和gid设置成Host上git用户对应的值,比如我的就是1002和1002。
Gogsl配置
Docker Gogs运行起来后,就可以直接浏览器连3000端口进行配置,配置界面很明了,一看就OK。但此时我用的MySQL也是用的Docker,因为之前用了--link mysql:db
,表示我有一个container的名称为mysql,映射到gogs的container的名称为db,这样我可以直接用db:3306就可以连上了。在配置界面点确定前,需要在MySQL里新建一个仓,具体代码可以参考官方脚本。
等界面配置好后就再对Gogs进行详细的修改,具体可以参考官方文档
app.ini1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
| APP_NAME = Gogs RUN_USER = git RUN_MODE = prod
[database] DB_TYPE = mysql HOST = db:3306 NAME = gogs USER = root PASSWD = mysql_password SSL_MODE = disable PATH = data/gogs.db
[repository] ROOT = /data/git/gogs-repositories FORCE_PRIVATE = true DISABLE_HTTP_GIT = true
[repository.upload] ENABLED = false
[server] DOMAIN = yourdomain.com HTTP_PORT = 3000 ROOT_URL = http://localhost:3000/git/ DISABLE_SSH = false SSH_PORT = 22 START_SSH_SERVER = false OFFLINE_MODE = false
[mailer] ENABLED = true DISABLE_HELO = true HOST = smtp.xxx.com:587 SUBJECT = GIT FROM = "GIT" <xxx@xxx.com> USER = xxx@xxx.com PASSWD = xxx SKIP_VERIFY = false USE_PLAIN_TEXT = false
[service] REGISTER_EMAIL_CONFIRM = true ENABLE_NOTIFY_MAIL = true DISABLE_REGISTRATION = true ENABLE_CAPTCHA = true REQUIRE_SIGNIN_VIEW = true
[picture] DISABLE_GRAVATAR = true ENABLE_FEDERATED_AVATAR = true
[session] PROVIDER = file
[log] MODE = file LEVEL = Info ROOT_PATH = /app/gogs/log
[security] INSTALL_LOCK = true SECRET_KEY = qHtSV2KhCcMA0Xl
[other] SHOW_FOOTER_BRANDING = false SHOW_FOOTER_VERSION = false SHOW_FOOTER_TEMPLATE_LOAD_TIME = false
|
现在可以在浏览http://localhost:3000/git/来访问页面了。
Nginx反向代理
对于Nginx反向代理官方也给出了具体配置,还包括Apache和Lighttpd。其中Nginx中很重要的一点就是必须**要最后的反斜框[/]**。
1 2 3 4 5 6
| location /git/ { proxy_pass http://localhost:3000/; } location = /git { proxy_pass http://localhost:3000/; }
|
官方文档只提到了上面的一条,后面一条是根据我的实情情况加的。我发现登录的时候,点一次登录好长时间没有反应,过段时间后,返回的地址却是domain.com:4444/git/
,很无语,不知道为啥跳到4444端口呢。后来发现登录跳转的路径是domain.com/git
,没有最后的一个反斜框,Nginx无法知道怎么代理,这块搞了我快一两个小时,一直没有查出来原因。后来加了下面一条就解决了。
与Host共享22端口的问题
刚开始放狗搜了好久,都没有好的解决方案,有的提到sshd_config里面使用ForceCommand,看着比较靠谱,但好像也不成功。后来发现官方文档推荐一篇不错的文章。看守实操了一遍,大致原理是Host和Container用同一个uid的用户(假定为git),这时候连接到Host的git用户再转到container的10022端口,并运行特定的命令来进行git操作。
新建git用户
1 2 3 4 5 6 7 8 9
| $ sudo useradd -s /bin/bash -d /opt/my_gogs -m git $ id git uid=1002(git) gid=1002(git) groups=1002(git) $ su - git $ cd ~ $ ssh-key -t rsa $ cd ~/.ssh $ cat id_rsa.pub >> authorized_keys $ chmod 600 authorized_keys
|
这里我新建的git用户的uid和gid是1002,与之前运行gogs container需要对应。同时为了安全起见,将authorized_keys前加一些配置。
1
| no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty rsa...
|
字面意思就很好理解了。因为之前Docker运行Gogs时已经设置-v /opt/my_gogs:/data -e "PUID=1002" -e "PGID=1002"
, 这样在Host和Container的git用户主目录是同一个,uid和gid也一样,这样Host的git用户直接ssh -p 10022 127.0.0.1
是可以直接连接到Container的。
配置git用户登录问题
经过上面一步的设置,在外网就可以直接用git用户的密钥进行登录了,但是因为安全设置,没有tty等。然后就是设置像github那样,用户自己在web端导入自己的公钥,就可以用密钥拉取、推送代码。新建/app/gogs/gogs
,脚本如下。
1 2 3 4 5 6 7
| mkdir -p /app/gogs/ cat >/app/gogs/gogs <<'END'
ssh -p 10022 -o StrictHostKeyChecking=no git@127.0.0.1 \ "SSH_ORIGINAL_COMMAND=\"$SSH_ORIGINAL_COMMAND\" $0 $@" END chmod 755 /app/gogs/gogs
|
对共享22端口不熟悉的话,可以认真看看这篇文件。SSH真是神器。 :) Happy coding…