使用Nginx搭建并代理GitLab服务器

本文作记录自己通过使用单独的Nginx服务器代理运行一个远端GitLab应用的过程。

安装

1. 准备

在安装gitlab之前,先要看一遍gitlab官方的安装指导,虽然网上有很多关于gitlab安装、配置等博客,但是还是推荐直接到官网按照指示安装。
最重要的是硬件需求,第一次安装没注意,直接装了,导致出现了诡异的事情,最后内存不足启动失败。
官方的配置要求
gitlab_requirements

gitlab是非常消耗性能的软件,最低推荐配置是4G内存,2核心,对于日常使用的云服务器来说,这是奢侈配置,所以找了个实体的主机,废旧笔记本电脑加点内存搭了一个。
gitlab_pc

7年前的笔记本,2核心4线程,6G内存,安装ubuntu server 16.04 ,除了gitlab还能放点其他应用。

2. 安装步骤

这里就复制官方的步骤

  • 安装和配置依赖的环境

    openssh、ca依赖

    1
    2
    sudo apt-get update
    sudo apt-get install -y curl openssh-server ca-certificates

    安装邮件通知服务Postfix,这个软件作用是可以建立一个以gitlab运行的域名为邮箱域的邮件服务,gitlab的操作通知会通过此软件传输。

    1
    sudo apt-get install -y postfix

    Postfix安装时全部默认配置就可以工作,详细功能就不研究了,当然这里还支持自定义的SMTP服务,官方有说明。

  • 添加gitlab软件包库并安装

    1
    curl https://packages.gitlab.com/install/repositories/gitlab/gitlab-ee/script.deb.sh | sudo bash

    接下来就可以直接安装gitlab了

    1
    sudo EXTERNAL_URL="http://gitlab.example.com" apt-get install gitlab-ee

    EXTERNAL_URL是用于配置整个gitlab实例的访问入口,就是gitlab中的所有关于软件的基本链接都会被替换为此链接,系统会根据链接生成一些相关的回调和仓库地址等,非常重要,当然必须得把这个链接部署好,保证链接的确是gitlab的地址。这里就默认安装完成后再进入配置文件修改。
    安装后gitlab默认自己先配置启动了一次。

配置

1. 主要运行端口和配置文件

gitlab完成自动配置后启动的端口情况如下图:
netstat
进程端口的介绍:

  • 第一个nginx的8060端口向外网暴露,暂时不明确用途
  • redis_exporter的9121,是gitlab内置redis数据库,只向本机暴露
  • prometheus的9090端口,向本机暴露,用途应该是创建和管理时间序列事件的触发,如通知那些功能
  • postgres_expoter的9187,是gitlab内置的postegres数据库,向本机暴露
  • config.ru的9093,gitlab使用ruby的unicorn作为app server运行,管理worker等功能,比较重要,默认为8080,由于8080比较受欢迎,这个端口基本上都得改,暴露可自行设定;
  • 第二个nginx的端口,就是gitlab实例的主端口,所有外部访问的http均通过gitlab内置的nginx服务器处理,并使用该端口,当然暴露地址为外网0.0.0.0
  • node_exporter的9100,一个nodejs进程,用于实现测量所在的机器的资源状态比如cpu、内存、硬盘等数据的功能
  • gitlab-workhors的9229,一个是用go语言写的组件,是gitlab发展途中添加进来的用于优化git over http的组件,具体历史可以查看这里了解gitlab-workhors的由来
  • ruby的9168,一个ruby进程?暂时不知道是什么,或许是主进程
  • sidekiq的8082,是一种多线程后台处理系统,用于实现gitlab异步运行任务
  • gitaly的9236,是一个能够提供访问git仓库的RPC远程调用功能的服务,属于gitlab的一个托管组件
    gitlab的配置文件位于/etc/gitlab/gitlab/gitlab.rb,使用vim等工具可以直接修改,各种参数配置修改可以参考官方文档,因为服务器放在家中,家里的集体网络有一个固定IP比较方便,在这里我就按照这样的一个框架配置运行:
    gitlab服务器框架
    自己的Nginx服务器是一个云服务器,而gitlab所在的服务器是在家中的一个固定ip网络内的主机。
    这样部署的特点是:
  • 使用外部的Nginx进行路由代理,Nginx的服务器与gitlab服务器不一定是同一台服务器,外部的Nginx内可包含其他应用,互不干涉;
  • gitlab所在服务器内的gitlab应用无需做特别的Nginx替换,随时可以脱离外部Nginx独立运行,将来更换域名或移动应用等至需要修改外部Nginx配置以及external_url即可;
  • 外部的Nginx通常使用同一个域名IP,方便进行二级域名的SSL管理,无需gitlab应用内部配置单独的ssl。

2. external_url配置

external_url的配置直接影响到gitlab系统中所有http入口的地址,比如git仓库的http地址,gitlab访问页面的地址,注册回调的地址,邮件验证的地址等。

  • 当url的协议为https时,gitlab内部的内置Nginx自动会切换为https模式,此时需要配置ssl证书文件等,同时gitlab内的http请求自动更变为ssl加密请求;

  • 当url的端口被定义,比如https://localhost:88 ,此时,内置的Nginx的主端口会监听88,整个gitlab应用的入口则使用88端口;
    在本此情况下,gitlab将作为一个外部Nginx反向代理服务后的后端服务运行,当然ssl也添加上,在gitlab.rb中加入:

  • 1
    external_url 'https://git.hobairiku.site'

    接着进行内置的Nginx配置

3. 内置Nginx配置

内置Nginx配置为nginx['name']格式进行定义,本次部署内部Nginx不替换,独立使用,详细的Nginx配置可参考官方的Nginx配置文档

  • 主端口

    作为外部Nginx代理的上游,需要定义一个端口,可自由命名,在gitlab.rb中加入:

    1
    nginx['listen_port'] = XXXXX

    后续外部Nginx配置反向代理时填写gitlab所在服务器IP+该端口即可

  • 外部的http+ssl模式

    external_url的配置中已经说明,当定义为https时,需要设置ssl证书,但我们想通过外部的Nginx服务器进行ssl配置,也就是proxied SSL,在官方的文档中是这样描述的:
    proxied_SSL
    大意就是如果你的gitlab运行在一个反向代理后,一般都想在那个反向代理断面上设置SSL,此时需要关闭内置nginx对ssl的监听,由外部的ssl代理来实现,如果不加,可能会出现422等错误
    gitlab.rb中添加:

    1
    2
    3
    4
    5
    nginx['listen_https'] = false
    nginx['proxy_set_headers'] = {
    "X-Forwarded-Proto" => "https",
    "X-Forwarded-Ssl" => "on"
    }
  • max_body_size配置

    gitlab是可以使用http和ssh两种方式来进行git操作的,当使用http时,是通过post请求发送内容,若nginx在代理时没有设置body_size时将会收到:413 Request Entity Too Large的错误push不了代码,内外部的nginx都需要配置,在gitlab.rb中添加:

    1
    nginx['client_max_body_size'] = '20m'

    ps:大小可以自由设置,理论上,内部的Nginx此配置可以不设置,默认根据gitlab应用内的限制进行,但外部的nginx必须配置,详见下文。

4. unicorn端口

前面介绍说到了unicorn是gitlab的一个主要端口,若默认的8080占用,可以通过gitlab.rb中添加:

1
2
unicorn['port'] = 9093
unicorn['listen'] = '127.0.0.1'

如果8080没有被占用,可以忽略,listen也可以变为监听所有网络而不是本机。

5. ssh端口修改

既然使用外部的Nginx服务器,那么当用户使用ssh进行git时,肯定需要访问至gitlab所在的服务器的sshd服务,而外部Nginx服务器也存在自己的sshd服务,所以在这样的方案中,必须修改默认的22端口,在gitlab.rb中添加:

1
gitlab_rails['gitlab_shell_ssh_port'] = 24

这样git仓库就会显示为比如:ssh://git@git.hobairiku.site:24/hobairiku/XXX.git,意在外部Nginx使用tcp反向代理时,监听外部Nginx的24端口,并转发至gitlab所在服务器的ssh端口。
若果gitlab在外部Nginx服务器的本机上运行,则此步骤可忽略。

6.外部Nginx配置

内部的Nginx的配置完成后,需要进行外部的Nginx配置进行配合。Nginx的配置文件一般位于 /etc/nginx/nginx.conf

  • 配置gitlab的入口

    编辑http模块:

    1
    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
    http{
    ...
    #在http模块中添加以下内容
    #当用户访问http时,强制重定向为https
    server{
    listen 80;
    server_name git.hobairiku.site;
    rewrite ^(.*)$ https://$host$1 permanent;
    }
    #主访问入口
    server {
    listen 443;
    server_name git.hobairiku.site;
    ssl on;
    root html;
    index index.html index.htm;
    #ssl证书配置
    ssl_certificate cert/git.pem;
    ssl_certificate_key cert/git.key;
    ssl_session_timeout 5m;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;
    #入口反向代理
    location / {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_set_header X-Forwarded-Proto https;
    proxy_redirect off;
    #配置反向代理地址
    proxy_pass http://gitlab所在服务器的IP或域名:内部nginx的主端口;
    proxy_http_version 1.1;
    #一定记得要配置body_size
    client_max_body_size 1024m;
    }
    }
    }

    在此,gitlab所在的服务器时运行在一个固定ip的地址上的,如果是本机运行,则使用127.0.0.1,或可以使用aotussh+ssh反向隧道技术进行内网穿透,也可以使用花生壳那些DDNS,详细可自行学习。
    ps:ssl证书的制作申请等可以通过阿里云的免费证书或者FreeSSL进行申请

  • 配置ssh的反向代理

    ssh是使用在tcp协议上的,而不是http,所以反向代理也要单独配置,使用Nginx的stream功能实现tcp代理。编辑stream模块:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    stream {
    upstream ssh{
    hash $remote_addr consistent;
    server gitlab所在服务器的IP地址:22 max_fails=3 fail_timeout=10s;
    }
    server{
    listen 24;
    proxy_connect_timeout 20s;
    proxy_timeout 5m;
    proxy_pass ssh;
    }
    }

    ps:stream{}是与http{}并列的。
    如果gitlab运行在外部Nginx本机,上此设置可以忽略,因为用户访问的ssh端口就是本机的端口。同样,在两台不同服务器上,可以使用ssh反向隧道技术,要不然就得找固定IP的,因为tcp是没有域名的。

    使用

    所有配置完成,外部nginx reload,内部的gitlab运行sudo gitlab-ctl reconfigure访问https://git.hobairiku.site 就可以进入gitlab了,通过root账号可以进行初始的操作:

  1. 第一个注册的账号是root账号,最好不要忘记,忘记了得到服务器用命令找回或者添加;
  2. root账号可以通过管理员功能修改很多配置,比如可以关闭或者限制注册;
  3. 限制用户上传代码的大小;
    更多功能和git仓库操作在这里就不演示了,和github一样。
    另外本文的url就是本人自用的一个gitlab服务器,因为GitHub不提供私有仓库,而且bitbucket的网站访问奇慢,干脆就自己搭建了一个gitlab很方便。
Author: Hobai Riku
Link: https://blog.hobairiku.site/2018/02/26/gitlab-setup/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.