GitLab CI 中动态环境 URL 应使用 $CI_ENVIRONMENT_SLUG 构建,如 https://$CI_ENVIRONMENT_SLUG.example.com,并配合泛域名解析或中转服务实现自动预览;静态环境可直接写死 URL。

在 Linux 环境中利用 GitLab CI 的 environment.url 实现部署成功后的动态预览链接,核心在于让每次部署(尤其是动态环境如 Review App)生成唯一、可访问、且自动关联的 URL,并确保该 URL 能被 GitLab 正确识别并展示在 UI 中(如合并请求、环境列表、部署详情页)。这不是单纯写死一个地址,而是结合 CI 变量、服务发现与轻量路由逻辑来实现。
明确环境类型:用对静态 vs 动态环境
GitLab 将环境分为两类,适用场景不同:
-
静态环境(如
staging、production):URL 固定,适合长期运行的服务。直接在.gitlab-ci.yml中写死url: https://staging.example.com即可,GitLab 会自动渲染按钮。 -
动态环境(如
review/$CI_COMMIT_REF_SLUG):用于每个分支或 MR 的临时预览,URL 必须动态生成。这是实现“部署即预览”的关键场景。
动态 URL 的标准写法:依赖 CI 变量和命名规范
GitLab 原生支持基于预定义变量构造 URL。最常用、最稳妥的方式是:
- 使用
CI_ENVIRONMENT_SLUG—— 它由 GitLab 自动计算,合法、URL-safe、唯一,适合作为子域名或路径段; - 配合你已有的服务入口(如 Nginx 入口、Ingress 控制器、或统一网关),将
$CI_ENVIRONMENT_SLUG映射到对应后端实例。
示例配置(适用于 Review App):
deploy-review:
stage: deploy
script:
- echo "Deploying review app for $CI_COMMIT_REF_NAME"
# 这里执行实际部署,例如 kubectl apply 或 rsync 到服务器
environment:
name: review/$CI_COMMIT_REF_SLUG
url: https://$CI_ENVIRONMENT_SLUG.example.com
only:
- branches
except:
- main
- staging
- production只要你的 DNS 或反向代理(如 Nginx、Traefik)能通配解析 *.example.com 并路由到对应服务,GitLab 就会自动在 MR 页面、环境页显示「Visit app」按钮,点击即跳转。
没有通配 DNS?用中转服务兜底
若无法配置泛域名(如内网环境、测试平台无 DNS 权限),可自建轻量中转服务,把动态 slug 映射为真实地址:
- 部署一个极简 HTTP 服务(如 Python Flask 或 Node.js Express),监听
/r/:slug; - CI 阶段在部署完成后,调用该服务 API 写入映射:
POST /api/mapping { "slug": "$CI_ENVIRONMENT_SLUG", "target": "http://10.0.1.123:8080" }; - 环境 URL 改为:
url: https://gateway.example.com/r/$CI_ENVIRONMENT_SLUG; - 中转服务收到请求后查表并 302 重定向到真实地址。
这种方式不依赖基础设施变更,适合对接 fir、蒲公英等第三方分发平台,也适用于前端静态资源托管场景。
确保 URL 生效的关键细节
即使写了 url,GitLab 也可能不显示按钮,注意以下几点:
- 作业必须成功完成(exit code 0),且
environment块不能放在before_script或after_script中; - URL 必须以
http://或https://开头,否则 GitLab 会忽略; - GitLab 15.3+ 已移除
soft_validation_on_external_url标志,任意合法 URL 均可保存,无需额外开启; - 如果使用自签名证书或内网地址,GitLab UI 仍会显示链接,只是浏览器可能拦截——这属于终端访问问题,不影响 URL 生成逻辑。











