🧩 第03章 · 搭建自托管 GitLab

安装 + 反代 + HTTPS + 邮件 + 首登

搭建自托管 GitLab

自托管 GitLab 是把代码留在自己手里的常见做法。本章用一条完整链路:安装 GitLab(Omnibus)→ 配置为 gitlab.bangdream.xyz → 用 Nginx 反向代理到 127.0.0.1:8090 → 签 HTTPS → 配置 SMTP 邮件 → 首次登录。

本章目标:把 GitLab 跑起来,公网 https://gitlab.bangdream.xyz 可访问、能收邮件、能注册登录。

1. 前置检查与安装

⚠️ 易错:GitLab 很吃内存,Omnibus 默认需要 4GB 内存(低于 4GB 会启动失败或极慢),且大量内存被 puma、sidekiq、postgresql、redis、gitaly 占用。若内存不足,先看第 6 步调低指标。

# 安装依赖与镜像源
sudo apt install -y curl openssh-server ca-certificates postfix tzdata
# 添加官方镜像源(国内建议用清华源提速,此处以官方为例)
curl -sS https://packages.gitlab.com/install/repositories/gitlab/gitlab-ee/script.deb.sh | sudo bash
# 或安装 CE 社区版(免费)
curl -sS https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.deb.sh | sudo bash

用外部 URL 参数安装(关键一步,必须与你的域名一致):

sudo EXTERNAL_URL="https://gitlab.bangdream.xyz" apt install -y gitlab-ce
组件 监听端口 说明
nginx(GitLab 自带) 80/443 默认给它,我们改成外部反代
gitlab-workhorse 8080 HTTP 后端
puma / sidekiq 内部 Ruby/Rails 进程
postgresql / redis 内部 依赖存储

⚠️ 易错:安装耗时较长(几分钟到十几分钟)。安装完先确认配置正确,别急着重启;外部 URL 如果填错,后续反代和证书路径全乱。

2. 确认与外部 URL

GitLab 用 external_url 决定它能生成正确的链接和让 gitlab-workhorse 挂载路径。先改它再 reconfigure。

# 查看当前 external_url
sudo grep -E '^external_url' /etc/gitlab/gitlab.rb
# /etc/gitlab/gitlab.rb
external_url 'https://gitlab.bangdream.xyz'
# 让外部 URL 生效
sudo gitlab-ctl reconfigure

⚠️ 易错:gitlab-ctl reconfigure 会重跑整条 Chef,通常要几分钟。中途千万别 Ctrl+C,否则会出现「一半配置已应用、一半没有」的脏状态。耐心等它显示 gitlab Reconfigured!。

3. 用 Nginx 反向代理到 127.0.0.1:8090

我们把 HTTPS 和证书交给系统级 Nginx(第 02 章在同机已装过),让 GitLab 自带的 nginx 停掉或改端口,避免两个 nginx 抢 80/443。

# /etc/gitlab/gitlab.rb —— 关掉 GitLab 内置 nginx,改由外部 Nginx 反代
nginx['enable'] = false
# gitlab-workhorse 监听本机 8090(内置 nginx 停用后它仍要工作)
gitlab_workhorse['listen_network'] = "127.0.0.1"
gitlab_workhorse['listen_port'] = 8090
sudo gitlab-ctl reconfigure

写系统级 Nginx 配置文件(对应 02 章的模式,只是 proxy_pass 换成 8090):

# /etc/nginx/sites-available/gitlab.bangdream.xyz.conf
server {
    listen 80;
    server_name gitlab.bangdream.xyz;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name gitlab.bangdream.xyz;
    ssl_certificate     /etc/letsencrypt/live/gitlab.bangdream.xyz/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/gitlab.bangdream.xyz/privkey.pem;

    # GitLab 需要较大的 body 和较长的超时(push 大仓库)
    client_max_body_size 0;
    proxy_read_timeout 600;
    proxy_send_timeout 600;

    location / {
        proxy_pass http://127.0.0.1:8090;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}
sudo ln -s /etc/nginx/sites-available/gitlab.bangdream.xyz.conf /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx

🔒 安全:gitlab_workhorse 只监听 127.0.0.1,而 gitlab-rails 的 secret/密码全部封在内网。绝不能把 8090 暴露到公网,只让 Nginx 反代它。proxy_pass 必须指向 127.0.0.1,别填 0.0.0.0。

4. 签发 HTTPS(certbot)

sudo certbot --nginx -d gitlab.bangdream.xyz --email admin@bangdream.xyz --agree-tos --no-eff-email
sudo certbot renew --dry-run   # 验证续期

⚠️ 易错:gitlab.bangdream.xyz 必须先有 A 记录指向本机(见 02 章 DNS 步骤)。证书签不上,多半是 80/443 被防火墙或云安全组挡住了。

5. 配置 SMTP 邮件

GitLab 发通知/重置密码靠 SMTP。以网易/腾讯企业邮箱为例:

# /etc/gitlab/gitlab.rb
gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = "smtp.exmail.qq.com"
gitlab_rails['smtp_port'] = 465
gitlab_rails['smtp_user_name'] = "noreply@bangdream.xyz"
gitlab_rails['smtp_password'] = "邮箱授权码"
gitlab_rails['smtp_domain'] = "smtp.exmail.qq.com"
gitlab_rails['smtp_authentication'] = "login"
gitlab_rails['smtp_enable_starttls_auto'] = true
gitlab_rails['smtp_tls'] = false
gitlab_rails['smtp_ssl'] = true

# 发件人地址
gitlab_rails['gitlab_email_from'] = 'noreply@bangdream.xyz'
gitlab_rails['gitlab_email_reply_to'] = 'noreply@bangdream.xyz'
sudo gitlab-ctl reconfigure
# 测试邮件发送
sudo gitlab-rails console -e production
# 在 Rails console 里
Notify.test_email('you@example.com', 'Test', 'GitLab SMTP test').deliver_now
exit

⚠️ 易错:企业邮箱通常要「授权码」而非登录密码(登录密码会被拒)。很多邮箱要求 smtp_ssl=true 时不能用 465 又开启 smtp_tls,或 587 端口用 STARTTLS——先弄清你邮箱的端口和是否强制 TLS。

6. 调低资源占用(小内存服务器)

内存不足时进程会被 OOM kill,GitLab 反复起不来。改这些配置减内存:

# /etc/gitlab/gitlab.rb
puma['worker_processes'] = 2
puma['threads_min'] = 1
puma['threads_max'] = 4
prometheus_monitoring['enable'] = false
grafana['enable'] = false
nginx['enable'] = false        # 我们走外部 nginx
sudo gitlab-ctl reconfigure
# 观察内存占用
free -h
sudo gitlab-ctl status | grep -E 'run|down'

7. 首次登录

# 读取初始 root 密码(GitLab 首次装会随机生成)
sudo cat /etc/gitlab/initial_root_password

浏览器访问 https://gitlab.bangdream.xyz → 用 root + 上密码登录 → 立即修改密码。

# 验证点 命令/操作 预期
1 服务状态 sudo gitlab-ctl status 各组件 run
2 页面可开 浏览器访问 https 登录页出现
3 HTTPS curl -I https://gitlab.bangdream.xyz 200
4 反代正确 curl -s http://127.0.0.1:8090 返回 GitLab
5 邮件 Rails console 测试 邮箱收到
6 内存 free -h 有富余
# 一条命令快速验证核心
sudo gitlab-ctl status | grep -c 'run:' \
  && curl -sI https://gitlab.bangdream.xyz | head -1 \
  && curl -s http://127.0.0.1:8090 | grep -o 'GitLab' | head -1

到这里 gitlab.bangdream.xyz 已经能访问、能收发邮件、能登录。下一章搭建 RustDesk 远程协助服务器。