1. 为什么要在Windows内网自己搭GitLab很多朋友可能觉得代码托管直接用GitHub、Gitee这些公开平台不就好了为啥要费劲自己搭一个这事儿我干过好几次也帮不少团队部署过感触最深的就是“可控”和“安全”。想象一下你公司的核心业务代码、还没上线的产品设计、内部的算法模型这些能随便放到外网去吗肯定不行。内网私有化部署GitLab就是把代码仓库这个“数字资产保险柜”完全搬到自己家里网络物理隔离访问权限自己说了算数据不出内网心里踏实。对于中小团队或者初创公司来说自己搭GitLab还有一个巨大的好处成本可控功能完整。GitLab社区版CE的功能已经强大到离谱从代码托管、分支管理、CI/CD流水线、到容器镜像仓库、甚至轻量的项目管理看板它几乎提供了一站式的DevOps平台。你不用为每个成员购买SaaS服务的账号一次部署全团队受益。特别是在Windows服务器环境还比较普遍的中小企业里掌握这套部署方法能立刻为团队打造一个专业、高效的协同开发环境。我自己第一次在内网部署时也遇到了不少麻烦比如Docker镜像拉不动、端口冲突、还有那个著名的中文版HTTP链接拼接端口的“坑”。但把这些都趟平之后你会发现整个过程其实很有条理。接下来我就手把手带你走一遍从准备环境到成功登录后台把每个步骤拆开揉碎保证你跟着做就能成功。2. 部署前的准备工作别急着敲命令俗话说磨刀不误砍柴工。在运行任何Docker命令之前把基础环境理顺能避免后面80%的莫名其妙的问题。2.1 搞定Docker Desktop for Windows首先你得有一台Windows机器最好是Windows 10专业版/企业版或Windows Server 2016及以上版本并且开启了Hyper-V虚拟化支持。这是运行Docker Desktop的硬性要求。去Docker官网下载Docker Desktop for Windows的安装包这个过程没啥好说的双击、下一步、完成。但这里第一个“坑”就来了镜像下载速度。由于网络原因直接从Docker Hub默认仓库拉取镜像可能会慢如蜗牛甚至直接失败。我遇到过好几次命令行卡在那里一动不动非常打击积极性。所以安装完Docker Desktop后第一件事就是配置国内镜像加速器。右键点击系统托盘里的Docker小鲸鱼图标选择“Settings”设置然后找到“Docker Engine”。你会看到一个JSON格式的配置框。我们需要在registry-mirrors这个数组里添加国内的镜像源地址。这里我推荐几个稳定常用的{ registry-mirrors: [ https://docker.mirrors.ustc.edu.cn, https://hub-mirror.c.163.com, https://mirror.baidubce.com ] }你可以选择一个添加也可以像上面一样加多个。修改完成后点击“Apply Restart”Docker会重启并应用新配置。这一步至关重要它能让你后续拉取GitLab等大型镜像的速度提升好几个数量级。2.2 规划你的磁盘和目录结构Docker容器跑起来后里面产生的所有配置、数据、日志我们都需要持久化地保存在Windows宿主机上。这样即使容器删了重建我们的数据也不会丢。所以提前规划好存放的目录能让管理变得清晰。我个人的习惯是在非系统盘比如D盘创建一个专门的工作目录。按照原始文章的建议我们这样来建在D:\根目录下新建一个文件夹就叫docker。这将成为你所有Docker相关项目的“家”。进入D:\docker再新建一个文件夹命名为gitlab。这个文件夹将存放我们这个GitLab项目所有的东西。最后在D:\docker\gitlab里面再创建三个子文件夹config、data、logs。它们分别对应容器内GitLab的配置文件、数据库和仓库数据、运行日志。为什么是这三个这是GitLab官方推荐的持久化卷映射目录。/etc/gitlab里面是核心配置文件/var/opt/gitlab是应用数据/var/log/gitlab是日志。把它们映射出来以后要修改配置、查看日志、备份数据直接在Windows文件夹里操作就行非常方便。现在你的目录树应该是这样的D:\ └── docker └── gitlab ├── config (初始为空) ├── data (初始为空) └── logs (初始为空)3. 编写Docker Compose配置核心一步准备工作做完就到了最核心的环节编写docker-compose.yml文件。这个文件定义了我们的GitLab服务要怎么跑用哪个镜像、映射哪些端口、挂载哪些数据卷、设置哪些环境变量全在这里面。我建议你用VS Code或者Notepad这类文本编辑器来写避免记事本可能带来的编码问题。就在D:\docker\gitlab这个目录下新建一个文件名字就叫docker-compose.yml。然后把下面的内容复制进去我会逐段解释每个部分的作用。version: 3.8 services: gitlab: image: twang2218/gitlab-ce-zh:latest container_name: my-gitlab restart: always hostname: gitlab.example.com environment: TZ: Asia/Shanghai GITLAB_OMNIBUS_CONFIG: | external_url http://192.168.1.100 gitlab_rails[gitlab_shell_ssh_port] 1022 unicorn[port] 8888 nginx[listen_port] 8080 # 可选配置SMTP发送邮件非常重要 # gitlab_rails[smtp_enable] true # gitlab_rails[smtp_address] smtp.your-email-provider.com # gitlab_rails[smtp_port] 465 ports: - 8080:8080 # HTTP访问端口 - 1043:443 # HTTPS访问端口暂未启用SSL时可先映射 - 1022:22 # SSH克隆代码端口 volumes: - D:\docker\gitlab\config:/etc/gitlab - D:\docker\gitlab\data:/var/opt/gitlab - D:\docker\gitlab\logs:/var/log/gitlab networks: - gitlab-net networks: gitlab-net: driver: bridge逐行解读与避坑指南image: twang2218/gitlab-ce-zh:latest这里我们使用了twang2218/gitlab-ce-zh这个镜像。它是GitLab社区版的中文汉化版本对于国内团队非常友好。latest标签表示总是拉取最新的版本。如果你需要某个特定版本以求稳定可以指定如twang2218/gitlab-ce-zh:14.10.5。hostname和environment里的external_url这是最容易出错的地方之一。hostname是容器内部识别自己的主机名可以按需修改。关键是external_url它定义了GitLab对外访问的基准URL。请务必将http://192.168.1.100替换成你Windows服务器的实际内网IP地址。例如你的电脑在内网IP是192.168.31.150这里就改成http://192.168.31.150。这个地址会用于生成仓库的克隆链接。端口映射ports8080:8080: 左边是宿主机Windows的端口右边是容器内Nginx服务监听的端口我们在下面环境变量里设置为了8080。这意味着你通过浏览器访问http://你的IP:8080就能打开GitLab网页。1022:22: 将容器内SSH服务的22端口映射到宿主机的1022端口。因为Windows的22端口可能被占用或受限我们改用1022。这样克隆代码时使用的SSH地址就是ssh://git你的IP:1022/group/project.git。1043:443: 为HTTPS预留的映射。如果你后续配置了SSL证书可以通过https://你的IP:1043访问。环境变量GITLAB_OMNIBUS_CONFIG这是GitLab Omnibus一体化安装包的配置入口可以直接写Ruby语法。我们在这里做了几件关键事gitlab_rails[gitlab_shell_ssh_port] 1022: 告诉GitLabSSH服务跑在1022端口对应上面映射的宿主机端口。unicorn[port] 8888: Unicorn是GitLab的Ruby应用服务器我们让它监听8888端口容器内部。nginx[listen_port] 8080: Nginx是前端Web服务器我们让它监听8080端口容器内部并映射到宿主机的8080。特别注意这里没有设置gitlab_rails[gitlab_shell_ssh_port]为22是因为我们映射时已经改到了1022必须在这里声明一致否则GitLab生成的SSH克隆链接端口会是错的。卷映射volumes这就是把我们之前创建的三个文件夹分别映射到容器内的关键目录。确保路径正确特别是Windows路径使用反斜杠\而映射关系是Windows路径:Linux容器路径。网络networks我们创建了一个自定义的桥接网络gitlab-net。虽然不是必须但这样做可以让服务隔离得更好未来如果需要添加其他容器比如GitLab Runner做CI/CD它们可以方便地加入同一个网络进行通信。4. 启动服务与初始化见证奇迹的时刻配置文件写好保存后我们就可以启动GitLab了。打开命令行工具CMD或PowerShell关键一步一定要切换到docker-compose.yml文件所在的目录也就是D:\docker\gitlab。# 切换盘符 D: # 进入目录 cd D:\docker\gitlab # 启动服务-d 表示后台运行 docker-compose up -d执行docker-compose up -d后Docker会做几件事首先检查本地是否有twang2218/gitlab-ce-zh:latest镜像如果没有就从配置的镜像源拉取所以前面配加速器很重要然后根据配置创建并启动容器。第一次启动需要一些时间因为GitLab要初始化数据库、创建系统表等。这个过程可能需要5-10分钟取决于你的机器性能。你可以通过以下命令观察启动状态和日志# 查看容器状态 docker-compose ps # 如果状态是 Up 就表示正在运行healthy 表示完全就绪 # 实时查看日志CtrlC退出 docker-compose logs -f在日志里你会看到大量的初始化信息。当看到诸如gitlab Reconfigured!或者系统启动完成的提示时就差不多了。更直观的方法是打开浏览器输入http://你的IP:8080。如果看到GitLab的欢迎页面或者要求你为root管理员设置密码的页面那么恭喜你服务已经成功启动了首次登录设置在浏览器打开上述地址首先会跳转到设置管理员密码的页面。为root用户设置一个强密码并牢记。这个密码就是你后续管理整个GitLab的“钥匙”。设置完成后用用户名root和你刚设置的密码登录。登录后我强烈建议你立刻去修改默认的克隆协议。进入“管理区域” (Admin Area)-“设置” (Settings)-“通用” (General)找到“可见性与访问控制” (Visibility and Access Controls)。在这里你会看到“默认克隆协议”(Default clone protocol)。请务必将其从“Both (HTTP and SSH)” 修改为 “HTTP”。这是解决中文版GitLab一个经典Bug的关键操作我后面会详细说为什么。5. 避坑指南那些我踩过的“雷”部署成功只是第一步要让团队顺畅使用还得解决几个常见的“坑”。下面这几个问题我几乎在每次部署中都会遇到。5.1 中文版HTTP链接的端口“消失”问题这是最大的一个坑也是原始文章重点提到的。现象是这样的当你创建一个项目后GitLab会提供一个HTTP克隆链接比如http://192.168.1.100/group/project.git。你会发现链接里没有端口号而我们明明是通过8080端口访问的。如果你直接用这个链接去git clone命令会尝试连接默认的80端口而我们的服务实际跑在8080端口结果肯定是连接失败。这就是中文汉化版的一个已知问题它没有正确拼接external_url中定义的端口。解决方案有两个推荐修改默认克隆协议为HTTP这就是上一步我们要求你做的。设置为HTTP后GitLab生成的HTTP克隆链接虽然还是没有端口但我们可以手动补上。克隆时使用git clone http://192.168.1.100:8080/group/project.git。注意在IP地址后加上:8080。使用SSH克隆如果你配置了SSH密钥可以使用SSH方式克隆地址是ssh://git192.168.1.100:1022/group/project.git。SSH链接会正确包含端口号1022。但这对团队成员需要分发和管理SSH密钥。为什么会有这个坑根本原因在于GitLab生成仓库URL的逻辑。英文原版会根据external_url例如http://192.168.1.100:8080完整地生成链接。但某些汉化版本在处理这个配置时可能丢失了端口部分。所以手动补全端口是最直接有效的办法。5.2 性能优化与资源调整GitLab是个“资源大户”尤其是在内存方面。在Windows上跑Docker默认分配给Docker Desktop的资源可能不够通常是2GB内存。这会导致GitLab运行缓慢甚至容器崩溃。优化建议增加Docker资源右键系统托盘Docker图标 - Settings - Resources - Advanced。在这里我建议至少将CPU核心数调到4内存调到4GB或以上交换内存Swap调到2GB。这能显著提升GitLab的运行流畅度。调整GitLab组件配置对于内网小团队可以适当调低一些后台服务的资源占用。编辑D:\docker\gitlab\config\gitlab.rb文件启动后会自动生成可以添加如下配置# 减少Sidekiq进程数后台作业处理器 sidekiq[max_concurrency] 5 # 减少Puma工作进程数GitLab 14.0后替代Unicorn puma[worker_processes] 2修改配置后进入容器执行gitlab-ctl reconfigure使配置生效或者直接重启容器docker-compose restart。5.3 邮件服务配置让通知飞起来一个没有邮件通知的GitLab是没有灵魂的。代码合并请求Merge Request、流水线状态、问题分配等都需要邮件来通知成员。不配置SMTP所有通知都会石沉大海。配置邮件需要在gitlab.rb中进行。找到D:\docker\gitlab\config\gitlab.rb文件用编辑器打开搜索smtp_enable你会看到一大段被注释的SMTP配置示例。你需要根据你的邮箱服务商比如公司自建邮箱、腾讯企业邮、阿里云企业邮等来填写。这里以腾讯企业邮为例给出一个配置片段gitlab_rails[smtp_enable] true gitlab_rails[smtp_address] smtp.exmail.qq.com gitlab_rails[smtp_port] 465 gitlab_rails[smtp_user_name] gitlabyour-company.com # 你的发件邮箱 gitlab_rails[smtp_password] your-email-password # 邮箱密码或授权码 gitlab_rails[smtp_domain] your-company.com gitlab_rails[smtp_authentication] login gitlab_rails[smtp_enable_starttls_auto] true gitlab_rails[smtp_tls] true gitlab_rails[gitlab_email_from] gitlabyour-company.com gitlab_rails[gitlab_email_reply_to] noreplyyour-company.com重要提示很多邮箱服务如QQ、163、企业邮需要使用“授权码”而不是登录密码作为smtp_password。请务必去邮箱设置里获取正确的授权码。配置完成后保存文件然后在命令行执行以下命令让配置生效# 进入GitLab容器 docker exec -it my-gitlab bash # 在容器内重新配置GitLab gitlab-ctl reconfigure # 重启GitLab服务可选reconfigure通常会触发重启 gitlab-ctl restart # 退出容器 exit之后你可以在GitLab后台的“管理区域” - “设置” - “常规” - “电子邮件”中发送一封测试邮件验证配置是否成功。5.4 备份与恢复给数据上保险任何服务器都有可能出问题定期备份是运维的好习惯。GitLab的备份非常简单。手动备份# 进入容器执行备份命令备份文件会生成在 /var/opt/gitlab/backups 目录 docker exec -it my-gitlab gitlab-backup create因为我们将/var/opt/gitlab映射到了D:\docker\gitlab\data所以备份文件实际上会出现在D:\docker\gitlab\data\backups目录下文件名类似1698765432_2023_10_31_15.0.0_gitlab_backup.tar。你需要定期将这个文件拷贝到其他安全的地方。自动备份计划任务在Windows上我们可以利用系统的“任务计划程序”来定期执行备份。创建一个批处理文件backup_gitlab.bat内容如下echo off docker exec my-gitlab gitlab-backup create打开“任务计划程序”创建一个基本任务触发器设置为每天或每周操作就指向这个批处理文件。恢复备份如果某天需要恢复先将备份文件如1698765432_2023_10_31_15.0.0_gitlab_backup.tar放到D:\docker\gitlab\data\backups目录下。然后停止并删除当前GitLab容器注意docker-compose down会删除容器但保留映射出来的数据卷确保新容器使用相同的卷映射。最后启动一个新容器并执行恢复命令# 启动服务 docker-compose up -d # 进入容器执行恢复注意文件名去掉前缀和尾缀 docker exec -it my-gitlab gitlab-backup restore BACKUP1698765432_2023_10_31_15.0.0恢复过程会覆盖现有数据请谨慎操作并在测试环境先行验证。6. 日常维护与进阶使用服务跑起来之后日常还有一些维护工作和小技巧。查看服务状态和日志# 查看容器运行状态 docker-compose ps # 查看实时日志调试时非常有用 docker-compose logs -f gitlab # 进入容器内部像操作一台Linux服务器 docker exec -it my-gitlab bash # 在容器内查看GitLab各服务状态 gitlab-ctl status升级GitLab版本升级需要谨慎务必先备份停止当前服务docker-compose down修改docker-compose.yml中的image标签为新的版本号例如twang2218/gitlab-ce-zh:15.0.0。拉取新镜像docker-compose pull重新启动服务docker-compose up -d启动后GitLab会自动运行数据库迁移等升级操作通过docker-compose logs -f监控升级过程。启用HTTPS可选在内网环境中HTTP通常足够。但如果对安全有要求可以配置SSL证书。将你的域名证书.crt和私钥.key文件放到D:\docker\gitlab\config\ssl目录下。修改gitlab.rb设置external_url https://your.domain.com并配置nginx的SSL路径。修改docker-compose.yml中的端口映射将1043:443改为443:443并确保external_url的端口是443或对应的映射端口。 这个过程相对复杂涉及证书管理和Nginx配置建议在测试环境充分验证后再上生产。最后关于团队使用我建议管理员在部署稳定后花点时间设置好群组Group、项目Project的权限结构并引导团队成员熟悉GitLab的基本工作流比如Issue跟踪、Merge Request和CI/CD流水线。一个配置得当、运行稳定的内网GitLab真的能极大提升团队的开发效率和协作体验。