Ubuntu 上用 GitLab Runner 实现自动化部署
一 架构与前置准备
- 组件与职责
- GitLab 仓库:托管代码与 CI/CD 流水线定义(.gitlab-ci.yml)。
- GitLab Runner:在 Ubuntu 上执行构建、测试、部署作业(可用 Shell 或 Docker 执行器)。
- 目标服务器:承载应用与反向代理(如 Nginx),接收 Runner 的部署指令。
- 基础环境
- 安装必要软件:Git、GitLab Runner、以及目标服务(如 Nginx)。
- 防火墙放行:SSH(22)、HTTP(80)、HTTPS(443);如使用自托管 Runner,确保与 GitLab 网络可达。
- 安全建议:为部署用户配置 sudo 免密仅限于必要命令,或使用受限部署账号与受限 SSH 密钥。
二 安装与注册 GitLab Runner
- 安装 Runner
- Ubuntu 20.04/22.04/24.04 可直接用官方仓库安装:
- 添加仓库与 GPG 并安装:
- curl -L --output /etc/apt/trusted.gpg.d/gitlab.asc https://packages.gitlab.com/gitlab/gitlab-runner/gpgkey
- echo “deb https://packages.gitlab.com/gitlab/gitlab-runner/ubuntu $(lsb_release -cs) main” | sudo tee /etc/apt/sources.list.d/gitlab-runner.list
- sudo apt update && sudo apt install -y gitlab-runner
- 注册 Runner
- 在项目的 Settings → CI/CD → Runners 获取 注册令牌。
- 执行注册:sudo gitlab-runner register,按提示填写:
- GitLab 实例 URL(如 https://gitlab.com 或自托管地址)
- 注册令牌
- Runner 描述与标签(如 deploy、shell)
- 执行器:优先 Shell(便于直接执行部署脚本);也可选 Docker(需准备镜像与挂载)。
三 配置 SSH 免密与部署用户
- 在 Runner 所在机器生成密钥
- ssh-keygen -t rsa -b 4096 -C “gitlab-runner”
- 将公钥分发到目标服务器
- ssh-copy-id user@your_server_ip
- 目标服务器安全配置
- 为部署用户配置 sudo 免密,但仅限部署相关命令(如 systemctl restart your_service),降低风险。
- 建议:使用专用部署账号与最小权限,禁用该账号的终端登录(仅保留密钥登录)。
四 编写 .gitlab-ci.yml 与部署脚本
- 示例一 Shell 执行器直接部署(适合物理机/VM)
- .gitlab-ci.yml
- stages:
- build_job:
- stage: build
- script:
- echo “Building the project…”
-
你的构建命令(如 npm install、mvn package)
- deploy_job:
- stage: deploy
- script:
- echo “Deploying to $DEPLOY_SERVER…”
- scp -r build/ $DEPLOY_USER@$DEPLOY_SERVER:$DEPLOY_PATH
- ssh $DEPLOY_USER@$DEPLOY_SERVER “sudo systemctl restart $SERVICE_NAME”
- only:
- 说明
- 将 $DEPLOY_SERVER、$DEPLOY_USER、$DEPLOY_PATH、$SERVICE_NAME 放入项目 CI/CD Variables(Masked,必要时 Protected),避免明文泄露。
- 示例二 Docker 执行器推送镜像并远程部署
- .gitlab-ci.yml(节选)
- build:
- stage: build
- image: docker:24
- services:
- variables:
- DOCKER_HOST: tcp://docker:2375
- IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
- script:
- docker login -u “$CI_REGISTRY_USER” -p “$CI_REGISTRY_PASSWORD” $CI_REGISTRY
- docker build -t $IMAGE .
- docker push $IMAGE
- deploy:
- stage: deploy
- image: alpine/ssh
- script:
- ssh $DEPLOY_USER@$DEPLOY_SERVER "
docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY &&
docker pull $IMAGE &&
docker stop $APP_CONTAINER || true &&
docker rm $APP_CONTAINER || true &&
docker run -d --name $APP_CONTAINER -p 80:3000 $IMAGE
"
- only:
- 目标服务器部署脚本示例 deploy.sh
- #!/usr/bin/env bash
- set -e
- sudo systemctl stop $SERVICE_NAME || true
- sudo cp -r $DEPLOY_PATH /opt/$APP_NAME.bak-$(date +%F-%H%M%S)
- sudo rsync -a --delete $DEPLOY_PATH/ /opt/$APP_NAME/
- sudo systemctl start $SERVICE_NAME
- echo “Deployed $CI_COMMIT_SHA to $DEPLOY_SERVER:$DEPLOY_PATH”
五 运行、安全与排错要点
- 触发与验证
- 推送代码到 main 分支将自动触发流水线;在 CI/CD → Pipelines 查看作业日志与状态。
- 可在 /ci/lint 对 .gitlab-ci.yml 做语法校验,减少格式错误。
- 安全与合规
- 使用 Masked/Protected 变量存放密钥与服务器信息;避免把私钥写入仓库。
- Runner 与部署账号遵循最小权限原则;必要时用 HashiCorp Vault 或 GitLab 的 Secrets 能力管理凭据。
- 常见问题
- 出现 “此作业已阻塞,因为该项目没有分配任何可用 Runner”:到 Settings → CI/CD → Runners 检查 Runner 是否在线、是否被项目可见、标签是否匹配。
- SSH 连接失败:确认 authorized_keys 已分发、目标服务器 SSH 端口与防火墙策略正确、Runner 能解析目标主机名。
- 权限不足:为部署用户配置必要的 sudo 规则,或改用受限账号 + 受限命令清单。