使用Gogs自建Git服务器(Docker+Nginx+Let's Encrypt)

Published: 2018-06-01

Tags: Software

本文总阅读量

环境:Centos 7 (板瓦工)

(一)安装Docker与Nginx

Docker CE(社区版)安装文档:https://docs.docker.com/install/linux/docker-ce/centos

sudo yum install -y yum-utils device-mapper-persistent-data lvm2
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo yum install docker-ce

sudo systemctl enable docker
sudo systemctl start docker

板瓦工自带的epel-release不是很新,会导致很多软件没有,比如nginx与htop等

使用fedora epel的地址安装:

yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm

更新缓存及系统

yum update

安装 Nginx

yum install nginx

systemctl enable nginx
systemctl start nginx

(二)安装Gogs

文档及说明:https://github.com/gogs/gogs/tree/master/docker

# Pull image from Docker Hub.
$ docker pull gogs/gogs

# Create local directory for volume.
$ mkdir -p /var/gogs

# Use `docker run` for the first time.
$ docker run --name=gogs -p 10022:22 -p 10080:3000 -v /var/gogs:/data gogs/gogs

# Use `docker start` if you have stopped it.
$ docker start gogs

打开http://IP:10080就会重定向到http://IP:10080/install页面进行初始化安装

简要说明,不使用Docker安装Gogs,访问http://IP:3000是HTTP页面的地址,容器绑定了外部主机的10080端口到容器内部的3000,所以访问的是10080端口,同理,使用SSH进行git操作使用的是10022端口

如果已经安装了,可以删除/var/gogs/目录下的文件,刷新一下页面可以重新初始化

先不用安装,继续进行下面的操作

(三)申请SSL证书

在使用acme.sh申请Let's Encrypt证书之前,首先需要解析域名,比如使用https://gogs.yasking.org而不是http://IP:10080浏览项目

acme.sh很方便,可以自动根据Nginx配置文件来验证域名所有者,生成证书,所以申请证书之前,需要保证http://gogs.yasking.org是可以访问服务器的

/etc/nginx/conf.d/目录下创建gogs.yasking.org.conf配置文件,内容如下:

server {
    listen       80;
    server_name  gogs.yasking.org;
    root         /usr/share/nginx/html;

    # Load configuration files for the default server block.

    location / {
    }

    error_page 404 /404.html;
        location = /40x.html {
    }

    error_page 500 502 503 504 /50x.html;
        location = /50x.html {
    }
}

重新加载Nginx配置

systemctl reload nginx

访问http://gogs.yasking.org可以看到Nginx安装后的默认页面

下面来申请证书:

curl https://get.acme.sh | sh

# 重新登入系统执行
acme.sh --issue --nginx -d gogs.yasking.org

输出如下:

[root@host ~]# acme.sh --issue --nginx -d gogs.yasking.org
[Mon May 28 09:52:51 EDT 2018] Single domain='gogs.yasking.org'
[Mon May 28 09:52:51 EDT 2018] Getting domain auth token for each domain
[Mon May 28 09:52:51 EDT 2018] Getting webroot for domain='gogs.yasking.org'
[Mon May 28 09:52:51 EDT 2018] Getting new-authz for domain='gogs.yasking.org'
[Mon May 28 09:52:51 EDT 2018] The new-authz request is ok.
[Mon May 28 09:52:51 EDT 2018] Verifying:gogs.yasking.org
[Mon May 28 09:52:51 EDT 2018] Nginx mode for domain:gogs.yasking.org
[Mon May 28 09:52:51 EDT 2018] Found conf file: /etc/nginx/conf.d/gogs.yasking.org.conf
[Mon May 28 09:52:51 EDT 2018] Backup /etc/nginx/conf.d/gogs.yasking.org.conf to /root/.acme.sh/gogs.yasking.org/backup/gogs.yasking.org.nginx.conf
[Mon May 28 09:52:51 EDT 2018] Check the nginx conf before setting up.
[Mon May 28 09:52:52 EDT 2018] OK, Set up nginx config file
[Mon May 28 09:52:52 EDT 2018] nginx conf is done, let's check it again.
[Mon May 28 09:52:52 EDT 2018] Reload nginx
[Mon May 28 09:52:57 EDT 2018] Success
[Mon May 28 09:52:57 EDT 2018] Restoring from /root/.acme.sh/gogs.yasking.org/backup/gogs.yasking.org.nginx.conf to /etc/nginx/conf.d/gogs.yasking.org.conf
[Mon May 28 09:52:57 EDT 2018] Reload nginx
[Mon May 28 09:52:57 EDT 2018] Verify finished, start to sign.
[Mon May 28 09:52:57 EDT 2018] Cert success.
-----BEGIN CERTIFICATE-----
MIIGDTCCBPWgAwIBAgISA72V1llIExw/5hFkqaTIKgvCMA0GCSqGSIb3DQEBCwUA
MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQD
ExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMzAeFw0xODA1MjgxMjUyNTdaFw0x
...
7/qifB6IsBjF4gMpozuUmq7bdO2tuxcXqPA8L4CW56lIoTbkoJjvOiLMZlyylh9C
NoODqzYCQF0vv5ZA+10sKa6cC++exAZdOFDcoUg7NZ8neUYLz6T9ZaoTaiboHNiy
sl5TntzG5D/lEpQBbWVXbIc=
-----END CERTIFICATE-----
[Mon May 28 09:52:57 EDT 2018] Your cert is in  /root/.acme.sh/gogs.yasking.org/gogs.yasking.org.cer
[Mon May 28 09:52:57 EDT 2018] Your cert key is in  /root/.acme.sh/gogs.yasking.org/gogs.yasking.org.key
[Mon May 28 09:52:57 EDT 2018] The intermediate CA cert is in  /root/.acme.sh/gogs.yasking.org/ca.cer
[Mon May 28 09:52:57 EDT 2018] And the full chain certs is there:  /root/.acme.sh/gogs.yasking.org/fullchain.cer

没有报错,生成成功

Your cert is in  /root/.acme.sh/gogs.yasking.org/gogs.yasking.org.cer
Your cert key is in  /root/.acme.sh/gogs.yasking.org/gogs.yasking.org.key

(四)Nginx跳转Gogs

修改之前添加的Nginx配置文件(/etc/nginx/conf.d/gogs.yasking.org.conf),添加如下内容并删除原有内容

server {
    listen 443 ssl http2;
    server_name gogs.yasking.org;
    ssl_certificate /root/.acme.sh/gogs.yasking.org/gogs.yasking.org.cer;
    ssl_certificate_key /root/.acme.sh/gogs.yasking.org/gogs.yasking.org.key;
    ssl_session_cache    shared:SSL:1m;
    ssl_session_timeout  5m;
    ssl_protocols TLSv1.2;
    ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;
    ssl_prefer_server_ciphers  on;

    location / {
        proxy_set_header  X-Real-IP  $remote_addr;
        proxy_pass http://127.0.0.1:10080$request_uri;
    }
}

# 以下部分表示重定向 HTTP 请求到 HTTPS
server {
    listen 80;
    server_name gogs.yasking.org;
    return 301 https://$host$request_uri;
}

重新载入Nginx配置文件

访问https://gogs.yasking.org/可以看到默认的Nginx页面已经有了小绿锁头

(四)设置Gogs

之前安装启动Gogs容器后并没有进行设置,现在配置好了域名,可以进行安装了

数据库我选择的SQLite3,默认设置

应用基本设置,运行系统用户git默认就好,docker封装的gogs里已经创建了git用户。需要注意的有域名SSH端口号应用URL

域名我填写的是gogs.yasking.org,SSH端口号填写的是10022,应用URL填写的https://gogs.yasking.org/

HTTP端口号,Gogs安装默认使用的3000,因为使用docker,所以外部访问使用的是10080端口,又因为使用Nginx代理,所以直接访问https://gogs.yasking.org就可以了

这里可以使用端口扫描工具看一下10022是不是已经【打开】正确绑定了 端口扫描工具

安装完成,新建一个test-pub工程

HTTP clone链接:https://gogs.yasking.org/yieldone/test-pub.git

SSH clone链接: ssh://git@gogs.yasking.org:10022/yieldone/test-pub.git

遗留问题:现在使用HTTPS方式Clone会报错

[root@host ~]# git clone https://gogs.yasking.org/yieldone/test-pub.git
Cloning into 'test-pub'...
fatal: unable to access 'https://gogs.yasking.org/yieldone/test-pub.git/': Peer's Certificate issuer is not recognized.

这个问题,好像是git不认这个证书,clone之前运行命令可以解决这个问题

git config --global http.sslVerify false

将公钥使用控制面板用户设置的SSH密钥导入

然后使用SSH进行clone测试

[root@host ~]# git clone ssh://git@gogs.yasking.org:10022/yieldone/test-pub.git
Cloning into 'test-pub'...
remote: Counting objects: 8, done.
remote: Compressing objects: 100% (6/6), done.
remote: Total 8 (delta 1), reused 0 (delta 0)
Receiving objects: 100% (8/8), done.
Resolving deltas: 100% (1/1), done.

写在后面:

1,文档中在Docker内不建议使用独立的SSH服务器

2,可以使用docker exec -it gogs /bin/sh命令进入容器,用户git在/home/git,git用户的authorized_keys文件不是标准的文件,查看/home/git/.ssh/authorized_keys文件,会发现是一串命令,在面板添加的ssh公钥就会生成一条这样的记录

3,主机上,docker内的gogs映射在/var/gogs目录下,gogs下的app.ini配置文件,可以进去进行修改,然后使用docker restart gogs重启

4,没事别闲着关闭iptables啥的,会导致端口映射失败,比如ssh clone 访问超时,端口显示不通

参考:

[How to config SSH settings]

使用 Let’s encrypt 证书,实现自动续签。