使用Docker快速搭建一个Git Server
使用gogs搭建git server
使用docker
如何搭建一个git server
以及升级,备份等
docker 方式安装
安装和运行docker
就不说了.
1.首先docker pull gogs/gogs
拉取镜像
2.创建一个数据卷docker volume create --name gogs-data
要查看已有的数据卷,使用docker volume ls
,数据卷用于保存数据,升级时数据不会丢,切勿删除此数据卷
3.启动服务
docker run -d --name=gogs --restart always -m 200m --log-opt max-size=2m -p 10022:22 -p 10080:3000 -v gogs-data:/data gogs/gogs
使用-v gogs-data:/data
挂载刚刚的数据卷,将数据卷内的数据映射到容器的/data
路径下.
也可以前面添加一个nginx反向代理
/etc/nginx/conf.d/git.conf
server{
listen 80;
server_name git.xx.cn code.xx.cn;
gzip on;
gzip_min_length 1024;
gzip_proxied any;
gzip_comp_level 3;
gzip_types text/plain text/javascript text/css text/json application/xml application/javascript application/x-javascript application/json;
location / {
client_max_body_size 10m;
proxy_pass http://127.0.0.1:10080;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Ssl off;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Port 80;
}
}
4.升级
docker stop gogs
和 docker rm gogs
然后执行步骤3就可以了
不放心的话,可以先stop,然后rename,再步骤三启动新版本的,启动成功后再删除旧版本的.
数据备份与恢复
备份docker volume
数据
文件接收端执行 nc -l 9090 > data.tar.gz
有些nc
(busybox里的nc)可能是 nc -l -p 9090 > data.tar.gz
以只读模式挂载数据卷,挂载数据卷到/data
路径
docker run --rm -it -v gogs-data:/data:ro busybox sh -c "cd /data && tar czvf - . | nc host 9090"
挂载到本地文件夹并打包
docker run --rm -it -v gogs-data:/data:ro -v /data/backup:/backup busybox sh
cd /data && tar czvf /backup/gogs-data-2018.tgz .
使用crontab
自动备份
/usr/cron/gogs.sh
docker run --rm -v gogs-data:/data:ro -v /data/backup:/backup -w /data busybox tar czvf /backup/gogs-data-$(date '+%Y%m%d').tgz .
为root用户添加crontab
, 每5天进行一次备份
10 3 */5 * * /usr/cron/gogs.sh
打包文件并发送到目标主机
恢复docker volume
数据
如果没有这个数据卷,先创建数据卷 docker volume create --name gogs-data
docker run --rm -it -v gogs-data:/data busybox sh -c "nc -l -p 9090 | tar -C /data -zxf -"
然后通过宿主机发送数据 nc host 9090 < data.tar.gz
如果两台电脑可以直接连通
发送方 docker run --rm -it -v gogs-data:/data:ro busybox sh -c "cd /data && tar czvf - . | nc host 9090"
接收方 docker run --rm -p 9090:9090 -it -v gogs-data:/data busybox sh -c "nc -l -p 9090 | tar -C /data -zxf -"
相关错误
remote: Counting objects: 860, done.
remote: aborting due to possible repository corruption on the remote side.
fatal: protocol error: bad pack header
由于服务器端在传送 git pull
或者 git clone
时需提前压缩数据,这些数据是存放在内存中.(git pull
时服务端内存不断增长,由于我使用的docker,只分配了60M内存);当内存不够使用时造成错误.
解决方案 1. 增加服务端内存. 或者 2. 修改git客户端配置 https://stackoverflow.com/questions/4170317/git-pull-error-remote-object-is-corrupted
即客户端执行
git config --global pack.windowMemory "100m"
git config --global pack.SizeLimit "100m"
git config --global pack.threads "1"
顺便说 docker 修改内存配置
docker update gogs -m 200m --memory-swap=400m
配置网络转发
容器的http端口和ssh分别映射到10080
和10022
,我们使用域名和80端口对外服务.
添加nginx
配置
git.conf
server{
listen 80;
server_name git.xx.cn code.xx.cn;
gzip on;
gzip_min_length 1024;
gzip_proxied any;
gzip_comp_level 3;
gzip_types text/plain text/javascript text/css text/json application/xml application/javascript application/x-javascript application/json image/jpeg image/gif image/png;
location / {
client_max_body_size 10m;
proxy_pass http://127.0.0.1:10080;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Ssl off;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Port 80;
}
}
少许优化:gogs
默认没有gzip
,我们通过nginx
添加了gzip
;设置最大提交文件为10M
然后就可以使用域名直接访问,如果发现通过nginx
代理后报 502
nginx erro log
为 Permission denied
, 可能是SELinux
的问题
检查SELinux
日志 sudo cat /var/log/audit/audit.log | grep nginx | grep denied
如果发现被 SELinux
拦截, 可以执行setsebool -P httpd_can_network_connect 1
开启此条规则
附:
getsebool -a | grep httpd
可以查看 SELinux 关于 http 的配置
setsebool httpd_can_network_connect on
使本次生效
setsebool httpd_can_network_connect on -P
是persist
模式,永久生效
使用后立即生效,无需重启任何服务.
配合git hook 自动部署PHP和静态网页
写了一个server用于接受通知 https://github.com/suconghou/gitsync.git
主要是接收到用户推送代码后,不存在则clone项目,存在则更新项目.
启动服务gitsy > /var/log/gitsy.log 2>&1 &
,然后由nginx代理隐藏端口,使用域名访问
server{
server_name g.share.xx.cn;
listen 80;
gzip on;
location / {
proxy_pass http://127.0.0.1:19090;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Ssl off;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Port 80;
}
}
gitsy
启动后可通过http查看loghttp://g.share.xx.cn/log
repos
目录可由docker挂载只读,防止删除操作,请求都转发到docker内,由内部nginx-fpm
运行代码
转发到docker里的nginx
server{
server_name *.share.xx.cn;
listen 80;
gzip on;
index index.html index.php;
location / {
proxy_pass http://127.0.0.1:18001;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Ssl off;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Port 80;
}
}
docker目录的映射为docker run -v /data/share/runtime/:/www --name datafs busybox
docker run -d --name dev --restart always -m 100m --log-opt max-size=2m --volumes-from datafs -p 18001:80 -p 12201:22 suconghou/server
可以使用/data/share/runtime/:/www:ro
使用只读
docker内部的nginx处理各个vhost的请求
server {
listen 80;
server_name 0.0.0.0;
index index.html index.php;
if ($host ~* ^(([\w\-]+)\.share\.ourwill\.cn)$) {
set $subdomain $2;
}
root /www/$subdomain;
if ( !-d $document_root ){
return 404;
}
try_files $uri $uri/ /index.php?$args;
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass 127.0.0.1:9000;
fastcgi_param debug 2;
include fastcgi.conf;
}
}
也可以直接使用本地nginx+fpm请求,不使用docker,代码可本地读写
server{
listen 80;
server_name *.run.xx.cn;
index index.php index.html;
fastcgi_connect_timeout 2s;
fastcgi_send_timeout 10s;
fastcgi_read_timeout 5s;
ssi on;
gzip on;
if ($host ~* ^(([\w\-]+)\.run\.ourwill\.cn)$) {
set $subdomain $2;
}
root /data/share/runtime/$subdomain;
if ( !-d $document_root){
return 404;
}
add_header X-Root "$subdomain";
try_files $uri $uri/ /index.php?$args;
location ~ \.php$ {
try_files $uri =404;
client_max_body_size 10m;
fastcgi_param debug 2;
fastcgi_pass 127.0.0.1:9000;
include fastcgi.conf;
}
}
此两种环境都传递了变量 debug 到php-fpm
,php 代码中可使用 getenv('debug')
判断是何种环境.线上环境没有配置debug,得出false
可以通过另一容器挂载git的数据目录也可实现即时部署