代码托管是开发者的基本盘,而当你连"自己的代码、自己的 CI 流水线、自己的仓库权限"都想自托管时,选择就开始变少。轻量如 Gitea 够日常用,但当你需要更强的"GitLab Runner 构建、制品仓库、代码审查、复杂权限与合规"时,GitLab 就是那个功能更全、更接近企业级自托管 Git 平台的答案。这篇文章不是让你在 Gitea 与 GitLab 里二选一踩哪个,而是讲清 GitLab 自托管解决什么、怎么用 Docker 把它起来并配好存储与 HTTPS、它强大的 CI/CD 与 Runner 是怎么串起来的,以及它"功能强但更重"的资源与现实边界。
一、GitLab 与 Gitea 的差异:像不像把"企业 Git 平台"搬回自己家
先建立判断框架:Gitea 追求"轻、快、够用",一个跑很省资源的 Git 服务,适合个人与小组的日常仓库;GitLab(这里指自托管版本)则在"功能广度"上更接近 GitLab.com 的企业体验:内置更完整的 CI/CD、容器/制品仓库、代码评审、里程碑/迭代、审计与更精细的权限与合规能力。选择的关键不是你缺哪个功能点,而是你对"自托管 Git 平台"的定位:如果只是个人仓库 + 简单协作,轻量就够了;如果需要把"代码 + 构建 + 部署"一体化地在自己手里跑完整流程,GitLab 的价值才充分体现。
之所以要单独讲 GitLab,是因为"自托管 GitLab"有个核心甜点:你的代码、构建流水线、制品都跑在自己的服务器/ Runner 上,不依赖 GitLab.com 的额度、网络或合规条款。对重视代码私密(如想跑私有仓库、不想代码离开自己环境)的团队与个人,这比"用 SaaS 版"更可控——代价就是要自己运维这个更重的服务。
二、最小落地:Docker 起 GitLab、指好存储、挂好 HTTPS
自托管 GitLab 最省心的方式是用它的官方容器镜像,配合环境变量指定对外域名与端口。关键点比 Gitea 更寸:GitLab 是个"全家桶",除了核心 Git 服务还有 PostgreSQL、Redis 等需要的组件,配置稍多,且比较吃内存。给一个 Docker 启动的示意:
# 用 docker-compose 起 GitLab(示意,正式按官方推荐参数调整)
services:
gitlab:
image: gitlab/gitlab-ce:latest # 社区版 CE
container_name: gitlab
hostname: git.example.com
ports: ["2222:22", "80:80", "443:443"]
environment:
GITLAB_OMNIBUS_CONFIG: |
external_url 'https://git.example.com' # 对外域名(决定走 443)
gitlab_rails['gitlab_shell_ssh_port'] = 2222 # ssh 走映射端口
volumes:
- ./gitlab-config:/etc/gitlab # 配置
- ./gitlab-logs:/var/log/gitlab
- ./gitlab-data:/var/opt/gitlab # 仓库、数据库等核心数据(务必纳入备份)
shm_size: '256m'
落地时要想清楚三件事。一是"端口":HTTP(S) 对外通常走 443+80,SSH 建议映射到主机的一个独立端口(如 2222)并同步更新 `external_url` 与 `gitlab_shell_ssh_port`,否则 clone 的 SSH 地址会不对。二是"external_url":它决定 Git 地址与 HTTPS 入口,务必配成你的对外域名。三是"存储与备份":`gitlab-data` 里存着仓库、数据库等全部核心数据,要在前面接反代(Caddy/Traefik/Nginx)自动证书并做好这套数据的异地快照备份——GitLab 绝对不是"装完就不管的玩具"。
三、CI/CD 与 Runner:从"Push 代码"到"自动构建部署"的整条链
GitLab 区别于轻量 Git 托管的关键能力是内置 CI/CD。它的模型是:你只需在仓库里放一个 `.gitlab-ci.yml`,定义"阶段与作业"(如 build → test → deploy),当有提交/合并时 GitLab 会把任务分发给"Runner"(执行器)去跑。Runner 可以是已注册到某个 GitLab 的机器/容器,它拿到作业后在一个环境里执行你的构建/测试/部署命令,并把结果回传。
# .gitlab-ci.yml 极简示意:一个作业,打印并跑脚本
stages:
- build
build-job:
stage: build
script:
- echo "构建中..."
- make build
artifacts:
paths:
- dist/ # 产物留存,可在后续作业/下载使用
把这条链立起来有个现实分岔:用自己的自托管 Runner 还是共享 Runner。既然我们聊"全自托管",通常你会在自己的服务器/容器里注册 Runner:好处是构建在自己的环境、能访问自己的私有依赖,坏处是要为 Runner 提供的构建环境负责(隔离、资源、要不要 Docker-in-Docker)。建议先用一台干净容器当 Runner 跑通最简单的"build+artifact",再逐步加 test 与 deploy——避免一上来就搭复杂流水线而把自己绕晕。
四、代码评审、制品仓库与容器镜像库:一体化带来的便利
GitLab 的另一个卖点是"从代码到制品"的一体化。它内置合并请求(MR)评审:把改动以 MR 提交、用流水线在其上自动跑测试、再有人审查代码并合并,形成"代码变更经过自动化校验 + 人工确认"的标准流程。它还带制品仓库(能存放构建产物)与内置的容器镜像仓库(放 Docker 镜像),让"构建出的镜像 push 到 GitLab 仓库、再由它拉取部署"整条链在一个平台上闭环。
# 用内置容器仓库:在 CI 里登录并把镜像推到项目镜像库
# docker login $CI_REGISTRY -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD
# docker push $CI_REGISTRY_IMAGE:latest
这一体化对自托管的价值,是"减少在不同工具间跳来跳去":仓库、流水线、评审、制品、镜像库在一个界面上。但别贪多求全——初期建议只用"仓库 + 基础 CI + MR 评审",等用顺了再把制品与镜像库纳入,逐步把整条研发链路搬到同一屋檐下。平台的能力是否真的被你用上,取决于你是否真的需要这么多环节,而不是"它有我都该开"。
五、边界:功能强的代价是"更重、更吃资源、更要运维"
GitLab 最大的现实边界就是"重"。它通常需要较多内存(官方建议对 4GB 及以上更舒服)、依赖更多组件、升级与备份都比轻量方案复杂。自托管的健康姿态是"按需选择":如果你只是十几个仓库、不需要完整 CI/MR 评审体系,GitLab 的开销很可能不划算,轻量方案(Gitea)就已足够;只有当"一体化 CI/CD + 仓库 + 权限合规"确成你的刚需时,GitLab 的投入才值回票价。
决定上后,就要像养一个重量服务一样对待它:官方推荐的备份命令(GitLab 的 omnibus backup)要定期跑并异地存放;升级前读变更说明、对数据做快照;把它的资源占用与健康纳入监控;因为它的容错和单点牵动整个研发流程,别把它当成"能随便重启再说的东西"。把"该用重就重、该轻就轻"和服务"用上了就要认真养"这两层边界想清,GitLab 才会是一个长期可靠的自托管研发平台,而不是一个后期越跑越累、越来越不敢动的大负担。
结语
GitLab 自托管的价值,是把"仓库 + CI/CD + MR 评审 + 制品/镜像库"这套接近企业级 Git 平台的能力整体搬回自己手里,让代码、流水线与制品都在自己的环境闭环。落地要点:用官方镜像起服务并配好 external_url、SSH 端口与存储备份,前面接反代自动 HTTPS;用 `.gitlab-ci.yml` + 自托管 Runner 串起从 Push 到构建部署的整条链,先跑通最简单作业再逐步加 test/deploy;提前规划是否真的需要制品与镜像库。它的边界是"明显更重、更吃资源、更需认真运维",所以先判断你缺不缺这些能力再决定是否付出这份运维代价——需要,则它是把研发全链路握住自己手里的强平台;不需要,轻量方案反而更省心。




