尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Windows Docker 环境搭建 GitLab CI/CD 流水线

Windows Docker 环境搭建 GitLab CI/CD 流水线 Windows Docker 环境搭建 GitLab CI/CD 流水线从零到一的完整实践引言GitLab CI/CD 是持续集成与持续部署工具之一。它天然集成在 GitLab 代码仓库中无需额外搭建 Jenkins 等第三方 CI 平台开箱即用。本文将记录在 Windows 环境下使用 Docker 部署 GitLab 和 GitLab Runner并成功跑通一条完整 CI/CD 流水线的全过程包括环境搭建、原理剖析、踩坑与解决希望能为同样在 Windows 上进行 DevOps 实践的开发者提供一份可复用的参考。一、环境准备1.1 基础环境操作系统WindowsDocker Desktop 运行于 WSL 2 后端容器运行时Docker Desktop目标技术栈Java Maven 多模块项目1.2 部署 GitLab 服务端使用 Docker 一键拉起 GitLab CE 社区版容器dockerrun-d--namegitlab\--shm-size1g\-p8012:8012\-eGITLAB_OMNIBUS_CONFIGexternal_url http://host.docker.internal:8012;\gitlab/gitlab-ce:latest关键参数说明--shm-size1g增加共享内存大小避免 GitLab 运行时因内存不足而崩溃。-p 8012:8012将容器内 8012 端口映射到宿主机 8012 端口此处将默认的 80 端口改为 8012。external_url设置 GitLab 的外部访问地址。host.docker.internal是 Docker Desktop 在 Windows/Mac 下提供的特殊域名容器内可通过它访问宿主机Linux 下需要额外配置或改用宿主机 IP。示例中未挂载数据卷生产环境需要挂载。完整部署流程可参考《使用 Docker 部署 GitLab》。1.3 部署 GitLab RunnerRunner 是 GitLab CI/CD 的执行引擎负责拉取并执行流水线任务。dockerrun-d--namegitlab-runner\-v//var/run/docker.sock:/var/run/docker.sock\gitlab/gitlab-runner:v18.8.0核心挂载说明-v //var/run/docker.sock:/var/run/docker.sock将宿主机的 Docker 套接字挂载到 Runner 容器内。在 Windows 下//var/run/docker.sock实际对应 Windows 命名管道\\.\pipe\docker_engine。该挂载让 Runner 容器内的 Docker 客户端能够与宿主机 Docker 守护进程通信从而启动 CI/CD 任务容器。Linux 下可直接使用-v /var/run/docker.sock:/var/run/docker.sock。1.4 注册 Runnerdockerexec-itgitlab-runner gitlab-runner register\--non-interactive\--urlhttp://host.docker.internal:8012\--registration-token xxxx\--descriptionlocal-docker-runner\--executordocker\--docker-image maven:3.9-eclipse-temurin-17-alpine\--docker-pull-policy if-not-present参数说明--non-interactive非交互式注册通过命令行一次性完成配置。--url http://host.docker.internal:8012指定 GitLab 服务器地址。host.docker.internal在 Windows/Mac 下可解析到宿主机若在 Linux 宿主机上运行 Docker可改用http://172.17.0.1:8012或使用--network host模式。--registration-token xxxx注册令牌从 GitLab 项目或组的 Settings → CI/CD → Runners 页面获取。--description local-docker-runnerRunner 的描述性名称便于在后台识别。--executor docker使用 Docker 执行器每个 CI Job 会启动一个全新的 Docker 容器运行结束后销毁。--docker-image maven:3.9-eclipse-temurin-17-alpine默认基础镜像包含 Maven 3.9 和 Java 17。--docker-pull-policy if-not-present镜像拉取策略优先使用本地镜像本地不存在时才从 Docker Hub 拉取可显著加快本地流水线速度。二、GitLab CI/CD 核心原理2.1 Runner 的工作机制拉取而非推送在项目根目录下编写.gitlab-ci.yml文件定义流水线。代码推送到 GitLab 后GitLab 解析该文件并生成任务放入队列。Runner 主动轮询 GitLab 服务器每隔几秒向 GitLab API 发送请求询问是否有待执行任务。若有则领取并执行否则继续等待。这种拉取模式的优势在于Runner 可部署在内网无需 GitLab 主动穿透防火墙。GitLab 短暂重启后Runner 可在下一轮询周期自动重试。2.2 Docker 执行器的工作流程当 Runner 领取到一个 Job 后Docker 执行器按以下步骤执行准备阶段创建并启动所需的服务容器。预作业阶段克隆代码仓库、恢复缓存、下载前一阶段的制品。作业阶段在用户指定的 Docker 镜像中执行构建脚本如mvn package。后作业阶段创建缓存、上传制品到 GitLab。Runner 通过数据卷挂载将代码目录共享给 Job 容器。三、流水线配置实战3.1 多阶段流水线设计将流水线拆分为编译、测试、打包、部署四个阶段实现完整链路。stages:-compile-test-package-deployvariables:MAVEN_OPTS:-Dmaven.repo.local$CI_PROJECT_DIR/.m2cache:key:maven-cachepaths:-.m2/compile:stage:compileimage:maven:3.9-eclipse-temurin-17-alpinescript:-mvn clean compileartifacts:paths:-**/target/classes/-**/target/generated-sources/# 如有代码生成器expire_in:1 daytest:stage:testimage:maven:3.9-eclipse-temurin-17-alpinescript:-mvn testdependencies:-compileartifacts:when:alwaysreports:junit:**/target/surefire-reports/TEST-*.xmlpaths:-**/target/surefire-reports/expire_in:6 dayspackage:stage:packageimage:maven:3.9-eclipse-temurin-17-alpinescript:-mvn package-DskipTestsdependencies:-compile-testartifacts:paths:-**/target/*.jar-**/target/*.warexpire_in:1 weekrules:-if:$CI_COMMIT_BRANCH masterdeploy:stage:deployimage:maven:3.9-eclipse-temurin-17-alpinescript:-echo 开始部署当前构建产物...-ls-la app/target/*.jar# 实际部署命令示例# - scp **/target/*.jar userserver:/deploy/path/# - mvn deploy -DskipTestsdependencies:-packagerules:-if:$CI_COMMIT_BRANCH master说明代码推送到 GitLab 仓库或发起合并请求时会触发 CI/CD 流水线。示例中仅master分支执行打包和部署。四、踩坑实录与解决方案问题一Runner 注册成功但 Job 执行时无法访问宿主机 Docker1.现象Runner 注册正常但实际运行 Job 时报错。ERROR: Failed to remove network for build errornetworksManager is undefined WARNING: Preparation failed: getting docker info: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?2.原因GitLab Runner 容器无法访问宿主机 Docker daemon。Linux 容器内需要 Unix socket 文件但默认路径下没有可用的 socket因为启动 Runner 容器时未挂载宿主机 socket。3.解决启动 Runner 容器时挂载 Docker socket。Windows Docker Desktop 下推荐写法-v//var/run/docker.sock:/var/run/docker.sock注意 Windows 路径开头使用双斜杠//避免被 shell 或 Docker CLI 转义。问题二无法下载镜像文件1.现象Failed to pull image with policy always: Error response from daemon: failed to resolve reference docker.io/library/maven:3.9-eclipse-temurin-17-alpine: failed to do request: Head https://registry-1.docker.io/v2/library/maven/manifests/3.9-eclipse-temurin-17-alpine2.原因Runner 通过宿主机 Docker 启动 Job 容器时无法从 Docker Hub 下载 Maven 镜像。3.解决先通过镜像加速站或代理将镜像下载到本地然后在注册 Runner 时添加--docker-pull-policy if-not-present优先使用本地镜像默认always, 笔者使用的docker镜像网站为https://docker.aityp.com/。若 Runner 已注册可修改其配置文件dockercpgitlab-runner:/etc/gitlab-runner/config.toml config.toml编辑config.toml在[runners.docker]段中添加或修改[runners.docker] image maven:3.9-eclipse-temurin-17-alpine pull_policy if-not-present保存后复制回容器并重启dockercpconfig.toml gitlab-runner:/etc/gitlab-runner/config.tomldockerrestart gitlab-runner问题三Runner 注册成功但 Job 执行时无法从 GitLab 拉取代码1.现象Runner 执行 Job 时无法拉取代码因为 GitLab 生成的仓库地址不可达。2.原因GitLab 启动时使用了external_url http://localhost:8012该地址仅对宿主机有效Runner 容器无法通过localhost访问 GitLab。3.解决方案一重新构建 GitLab 容器将external_url改为容器可识别的宿主机地址-eGITLAB_OMNIBUS_CONFIGexternal_url http://host.docker.internal:8012;方案二进入 GitLab 容器编辑/etc/gitlab/gitlab.rb修改external_urlhttp://host.docker.internal:8012然后重新配置并重启gitlab-ctl reconfigure gitlab-ctl restart问题四多模块项目 Artifacts 上传失败1.现象mvn package构建成功但artifacts上传时报错WARNING: target/*.jar: no matching files2.原因项目为 Maven 多模块结构JAR 包生成在子模块目录中例如app/target/app-0.1.0-SNAPSHOT.jar。而artifacts配置的target/*.jar只匹配根目录下的target/。3.解决使用递归通配符**/target/*.jar匹配所有层级子目录中的 JAR 包。同样编译阶段的target/classes/也应改为**/target/classes/。artifacts:paths:-**/target/*.jar五、进阶模拟 Merge Request 流程基础流水线跑通后模拟真实的 MR 协作流程创建功能分支git checkout -b dev提交代码git push origin dev发起 MR在 GitLab 网页端创建从dev到master的合并请求自动触发流水线MR 创建后GitLab 自动针对源分支运行 CI 流水线合并后自动部署MR 合并入master后触发deploy阶段完成自动部署MR 不仅是合并代码的入口更是质量卡点通过 CI 流水线自动验证代码质量避免问题代码进入主分支。六、总结与展望通过本次实践从零开始在 Windows 环境下搭建了一套完整的 GitLab CI/CD 系统核心收获包括Runner 采用拉取模式主动轮询 GitLab 领取任务。Docker 执行器的作业流程为准备 → 预作业克隆代码、恢复缓存→ 作业执行构建→ 后作业上传制品。Windows 下 Docker 套接字的特殊写法//var/run/docker.sock对应命名管道\\.\pipe\docker_engine。多模块项目应使用递归通配符**/target/*.jar匹配子模块制品。后续可探索的方向包括使用 Kubernetes 执行器实现 Runner 弹性伸缩、配置分布式缓存支持多 Runner 共享依赖、集成安全扫描实现 DevSecOps。希望这份实践记录能为你的 GitLab CI/CD 实践提供帮助。如遇到问题欢迎在评论区交流讨论。愿你我都能在各自的领域里不断成长勇敢追求梦想同时也保持对世界的好奇与善意!
返回列表