当前位置:首页 > 文章列表 > 文章 > linux > GitLabCI/CD部署到阿里云ECS教程

GitLabCI/CD部署到阿里云ECS教程

2025-08-22 23:04:54 0浏览 收藏

本文详细介绍了如何利用 GitLab CI/CD 自动化部署项目到阿里云 ECS,旨在帮助开发者提升效率与可靠性。核心在于在 ECS 上配置 GitLab Runner,并通过编写 `.gitlab-ci.yml` 文件定义部署流程。文章涵盖了从 ECS 实例准备、GitLab Runner 安装注册(推荐 Docker 方式)、SSH Key 与 CI/CD 变量配置,到 `.gitlab-ci.yml` 文件的编写,包括 stages 定义、变量使用、构建缓存、artifacts 传递,以及部署阶段的 SSH 安全连接与命令执行。同时,强调了安全最佳实践,如避免使用 root 用户、采用专用用户和最小权限原则。此外,还探讨了 GitLab CI/CD 的优势,如一体化理念、易用性、强大的集成能力和成本效益,并提供了 `.gitlab-ci.yml` 文件的编写技巧,包括条件执行、错误处理和 Docker 部署流程,助力开发者构建安全、可控、可维护的自动化流水线。

GitLab CI/CD 自动化部署到阿里云 ECS 的核心是通过在 ECS 上配置 GitLab Runner 并编写 .gitlab-ci.yml 文件实现。1. 在 ECS 上使用 Docker 安装 GitLab Runner,并注册到 GitLab 项目,推荐使用 docker executor 以实现环境隔离;2. 在 GitLab 项目中配置 CI/CD 变量,包括 SSH_PRIVATE_KEY(文件类型)、ECS_HOST 和 ECS_USER,确保安全访问;3. 编写 .gitlab-ci.yml 文件定义 stages(如 build、deploy),利用 cache 加速构建,artifacts 传递产物,并在 deploy 阶段通过 SSH 安全连接 ECS 执行部署命令;4. 遵循最佳实践:避免使用 root 用户,采用专用用户和最小权限原则,挂载持久化卷保存 Runner 配置,限制并发任务数,结合阿里云监控资源使用;5. .gitlab-ci.yml 支持变量注入、条件执行(only/manual)、错误处理(set -e)和 Docker 部署流程(build/push/pull)。该方案实现代码提交后自动测试、构建与部署,提升效率与可靠性,且配置文件纳入版本控制,具备高可追溯性,最终形成安全、可控、可维护的自动化流水线。

用 GitLab CI/CD 部署项目到阿里云 ECS 实战教程

用 GitLab CI/CD 将项目部署到阿里云 ECS,本质上就是把原来那些手动复制、粘贴、登录服务器、执行命令的繁琐步骤,通过一套预设的自动化流程彻底解放出来。它把代码的提交、测试、构建到最终上线,变成了一个流水线式的自动过程,大大提升了开发效率和部署的可靠性。

解决方案

要实现 GitLab CI/CD 到阿里云 ECS 的自动化部署,核心在于在 ECS 上安装并配置一个 GitLab Runner,并编写一个 .gitlab-ci.yml 文件来定义部署流程。

  1. ECS 实例准备与 GitLab Runner 配置

    • 确保你的阿里云 ECS 实例可以被 GitLab 访问(通常是出站网络),并且安装了你项目运行所需的环境(如 Node.js, Python, Docker 等)。
    • 在 ECS 实例上安装 GitLab Runner。最推荐的方式是使用 Docker 安装,因为它隔离性好,易于管理。
      # 假设你已经安装了 Docker
      sudo docker run -d --name gitlab-runner --restart always \
        -v /srv/gitlab-runner/config:/etc/gitlab-runner \
        -v /var/run/docker.sock:/var/run/docker.sock \
        gitlab/gitlab-runner:latest
    • 注册 Runner 到你的 GitLab 项目。你需要从 GitLab 项目的 "Settings" -> "CI/CD" -> "Runners" 页面获取注册 URL 和 Token。
      sudo docker run --rm -it -v /srv/gitlab-runner/config:/etc/gitlab-runner gitlab/gitlab-runner:latest register \
        --url YOUR_GITLAB_URL \
        --token YOUR_REGISTRATION_TOKEN \
        --description "My ECS Runner" \
        --executor "shell" # 或者 "docker" 如果你的项目在容器中运行

      选择 shell executor 意味着 Runner 会直接在 ECS 宿主机上执行命令。如果你的部署流程涉及 Docker 镜像构建和运行,选择 docker executor 更合适。

  2. GitLab 项目配置:SSH Key 与 CI/CD 变量

    • SSH Key: 这是部署安全的关键。在 GitLab 项目的 "Settings" -> "CI/CD" -> "Variables" 中添加一个类型为 "File" 的变量,例如 SSH_PRIVATE_KEY,将你的 ECS 部署用户(例如 root 或一个专门的部署用户)的私钥内容粘贴进去。确保这个私钥对应的公钥已经添加到 ECS 部署用户的 ~/.ssh/authorized_keys 文件中。
    • ECS 连接信息: 添加其他变量,如 ECS_HOST (你的 ECS 公网 IP 或域名) 和 ECS_USER (部署用户,如 root)。
  3. 编写 .gitlab-ci.yml 文件 在你的项目根目录创建 .gitlab-ci.yml 文件,定义构建、测试和部署的阶段。这是一个简化的 Node.js 项目部署示例:

    stages:
      - build
      - deploy
    
    variables:
      # 部署到 ECS 的目标路径
      DEPLOY_DIR: "/www/your-project"
    
    cache:
      paths:
        - node_modules/
    
    build_job:
      stage: build
      image: node:16-alpine # 使用一个 Node.js 镜像来构建
      script:
        - echo "开始构建项目..."
        - npm install --registry=https://registry.npmmirror.com # 使用国内镜像加速
        - npm run build
        - echo "项目构建完成。"
      artifacts:
        paths:
          - dist/ # 假设你的构建产物在 dist 目录下
        expire_in: 1 day # 缓存一天
    
    deploy_job:
      stage: deploy
      # 确保这个 job 只有在 main 分支更新时才运行
      only:
        - main
      script:
        - echo "开始部署到 ECS..."
        # 确保 SSH 私钥文件权限正确
        - chmod 600 "$SSH_PRIVATE_KEY"
        # 使用 ssh-agent 添加私钥,避免每次 SSH 都提示
        - eval $(ssh-agent -s)
        - ssh-add "$SSH_PRIVATE_KEY"
        # 关闭严格主机密钥检查,避免首次连接提示
        - mkdir -p ~/.ssh
        - echo -e "Host *\n\tStrictHostKeyChecking no\n\tUserKnownHostsFile=/dev/null" > ~/.ssh/config
        # 通过 SSH 连接到 ECS 并执行部署命令
        - ssh ${ECS_USER}@${ECS_HOST} "
            mkdir -p ${DEPLOY_DIR} &&
            cd ${DEPLOY_DIR} &&
            # 备份旧版本(可选)
            # mv current_release old_release || true &&
            # 从 GitLab 仓库拉取最新代码
            git pull origin main || git clone https://gitlab.com/your-group/your-project.git . &&
            # 安装依赖(如果需要)
            npm install --production --registry=https://registry.npmmirror.com &&
            # 重启服务,这里以 PM2 为例
            pm2 reload ecosystem.config.js || pm2 start ecosystem.config.js
          "
        - echo "部署完成!"

GitLab CI/CD 的核心优势是什么?为什么选择它?

对我而言,GitLab CI/CD 最打动人的地方在于它的“一体化”理念。你想想看,代码仓库、版本控制、问题追踪、CI/CD 流水线,所有这些都在同一个平台里,触手可及。这不像以前,代码在 GitHub,CI/CD 在 Jenkins,项目管理在 Jira,每次切换上下文都像是在不同房间里找工具,效率低不说,还容易出错。

选择 GitLab CI/CD,我觉得主要有几点:

首先,学习曲线相对平缓。它的 .gitlab-ci.yml 语法直观,基于 YAML,配置起来很顺手,即使是初学者也能很快上手。而且,它提供了大量的模板和示例,很多时候你只需要稍作修改就能满足需求。

其次,强大的集成能力。因为是原生集成,它能无缝访问你的代码、分支、标签,甚至可以直接操作 GitLab 的 API,实现更复杂的自动化流程,比如在部署成功后自动创建发布标签,或者在测试失败时自动创建 Jira 任务(虽然我更喜欢直接在 GitLab Issues 里处理)。

再来,成本效益。对于小型团队或者个人开发者来说,GitLab 提供了非常慷慨的免费套餐,包含了 CI/CD 功能,这无疑降低了自动化部署的门槛。你不需要额外维护一套 Jenkins 或者其他 CI/CD 服务器,节省了时间和金钱。

最后,也是我个人最看重的,是它能把 CI/CD 配置本身也纳入版本控制.gitlab-ci.yml 文件就和你的代码一起躺在仓库里,每次管道的变更都有迹可循,可以回溯,可以协作,这对于团队协作和审计来说简直是福音。我记得有一次,线上部署出了问题,我们直接回溯 .gitlab-ci.yml 的历史版本,很快就定位到了是某个部署命令的改动导致的,这种可追溯性是无价的。

在 ECS 上配置 GitLab Runner 的最佳实践

在 ECS 上配置 GitLab Runner,这玩意儿,说起来简单,做起来总有些坑。但只要遵循一些最佳实践,就能让它成为你部署流水线里最坚实的基石。

  1. 选择合适的 Executor:

    • Shell Executor: 这是最简单直接的,Runner 直接在 ECS 宿主机上执行命令。如果你对 ECS 环境有完全的控制权,并且部署过程不需要复杂的隔离,这是个不错的选择。缺点是,不同的项目可能会污染宿主机的环境,比如 Node.js 14 和 Node.js 16 项目同时部署,可能会有版本冲突。
    • Docker Executor: 强烈推荐!它会在每次 CI/CD 任务运行时,拉取一个新的 Docker 镜像作为执行环境。这样每个任务都在一个干净、隔离的环境中运行,避免了环境污染和依赖冲突。例如,Node.js 项目用 node:16 镜像,Python 项目用 python:3.9 镜像,互不干扰。这需要你的 ECS 上安装 Docker。
    • Docker-in-Docker (dind): 如果你的 CI/CD 流程本身就需要构建 Docker 镜像,那么 dind 是你的不二选择。Runner 会在一个 Docker 容器内运行另一个 Docker 守护进程。配置起来稍微复杂一点,但功能强大。
  2. 安全性是重中之重:

    • 专用用户: 不要用 root 用户运行 GitLab Runner。创建一个专门的系统用户,例如 gitlab-runner,并限制其权限,只给予必要的目录读写权限,以及执行部署脚本的权限。
    • SSH Key 管理: 部署用的 SSH 私钥绝对不能直接写死在 .gitlab-ci.yml 里。利用 GitLab CI/CD 的变量功能,将私钥作为文件类型变量存储。在 .gitlab-ci.yml 中,通过 chmod 600 $SSH_PRIVATE_KEY 临时设置权限,并在任务结束后自动销毁(GitLab Runner 会清理工作目录)。
    • 网络安全组: 确保 ECS 的安全组只开放必要的端口(如 22, 80, 443),并且限制 Runner 只能访问它需要访问的服务,例如部署目标服务器。
  3. 资源管理与监控:

    • 限制并发:config.toml 文件中,可以设置 Runner 的 concurrent 属性,限制同时运行的任务数量,防止 Runner 占用过多 ECS 资源导致系统卡顿。
    • 日志管理: 定期清理 Runner 的日志文件,或者配置日志轮转,避免日志文件过大。
    • 监控: 结合阿里云的监控服务,监控 ECS 实例的 CPU、内存、磁盘 I/O 等指标,确保 Runner 的运行不会对业务造成影响。
  4. 持久化配置与备份:

    • Runner 的 config.toml 文件非常重要,它包含了 Runner 的注册信息和配置。如果你是用 Docker 运行 Runner,务必将 /etc/gitlab-runner 目录挂载到宿主机的持久化存储卷上(例如 /srv/gitlab-runner/config),这样即使容器被删除,配置也不会丢失。
    • 定期备份 config.toml 文件。

我曾经犯过一个错误,直接用 root 用户跑 Runner,结果因为一个不小心在 .gitlab-ci.yml 里写了个 rm -rf / 的测试命令(当然是写错了),差点把整个系统删掉。那次经历让我深刻认识到,权限隔离和最小权限原则在自动化运维中有多么重要。

编写 .gitlab-ci.yml 文件:从构建到部署的实践细节

.gitlab-ci.yml 文件是 GitLab CI/CD 的灵魂,它定义了你的自动化流程。编写它就像在给你的项目写一份详细的部署说明书,只不过这份说明书是给机器看的。

  1. 阶段(Stages)的划分与逻辑流: 一个清晰的 stages 定义是良好 CI/CD 管道的基础。常见的阶段包括:

    • build: 编译代码,安装依赖,生成可部署的产物(如 dist 目录、Docker 镜像)。
    • test: 运行单元测试、集成测试、端到端测试。
    • deploy: 将构建好的产物部署到开发、测试或生产环境。
    • cleanup: 清理临时文件或资源。 阶段的顺序决定了任务的执行顺序,比如 test 阶段通常在 build 之后,deploytest 之后。
  2. 变量(Variables)的妙用: 充分利用 GitLab 的 CI/CD 变量功能,可以极大地提高 .gitlab-ci.yml 的灵活性和安全性。

    • 预定义变量: GitLab 提供了大量预定义变量(如 CI_COMMIT_BRANCH, CI_COMMIT_TAG, CI_PROJECT_DIR 等),可以直接在脚本中使用,获取当前构建的上下文信息。
    • 自定义变量: 在 GitLab 项目设置中创建自定义变量,用于存储敏感信息(如 API 密钥、数据库密码、SSH 私钥)或环境相关的配置(如部署目标 IP、路径)。这些变量在 Runner 执行时会自动注入到环境变量中,并且在日志中是屏蔽的,非常安全。
  3. 构建(Build)任务:产物与缓存:

    • 选择合适的镜像: image 关键字决定了构建任务运行的环境。比如 Node.js 项目用 node:latest,Python 项目用 python:3.9-slim
    • 依赖缓存: cache 是一个非常实用的功能,可以缓存任务之间共享的文件,比如 node_modules 或 Maven 的 .m2 目录。这能显著加快后续构建的速度,因为不需要每次都重新下载依赖。
      cache:
        paths:
          - node_modules/ # 缓存 Node.js 依赖
        key: ${CI_COMMIT_REF_SLUG} # 按分支或标签缓存,避免不同分支互相影响
    • 产物(Artifacts): artifacts 定义了构建完成后需要保留的文件。这些文件会上传到 GitLab,可以在后续阶段下载使用,或者手动下载查看。例如,前端项目的 dist 目录就是典型的构建产物。
  4. 部署(Deploy)任务:SSH 与远程执行: 这是最核心的部分。

    • SSH 密钥注入:
      before_script:
        - chmod 600 "$SSH_PRIVATE_KEY"
        - eval $(ssh-agent -s)
        - ssh-add "$SSH_PRIVATE_KEY"
        - mkdir -p ~/.ssh
        - echo -e "Host *\n\tStrictHostKeyChecking no\n\tUserKnownHostsFile=/dev/null" > ~/.ssh/config

      这几行代码是标准操作,用于将私钥安全地加载到 ssh-agent 中,并配置 SSH 客户端跳过首次连接时的安全提示。

    • 远程命令执行: 通过 ssh user@host "command" 的方式,在 ECS 上执行部署脚本。这可以是拉取最新代码、安装依赖、重启服务、更新 Docker 容器等。
      # 假设部署脚本在 ECS 上的 /usr/local/bin/deploy.sh
      ssh ${ECS_USER}@${ECS_HOST} "/usr/local/bin/deploy.sh ${CI_COMMIT_SHA}"
      # 或者直接执行一系列命令
      ssh ${ECS_USER}@${ECS_HOST} "
        cd /path/to/project &&
        git pull origin main &&
        npm install --production &&
        pm2 reload my-app
      "
    • Docker 部署流程: 如果你的应用是 Docker 化部署,流程会稍有不同:
      1. Build Stage: docker build -t my-app:${CI_COMMIT_SHA} .
      2. Push Stage: docker push registry.cn-hangzhou.aliyuncs.com/your-namespace/my-app:${CI_COMMIT_SHA} (推送到阿里云容器镜像服务 ACR 或其他仓库)
      3. Deploy Stage: 通过 SSH 到 ECS,执行 docker pull 拉取最新镜像,然后 docker stop/rm/run 更新容器。
        ssh ${ECS_USER}@${ECS_HOST} "
          docker pull registry.cn-hangzhou.aliyuncs.com/your-namespace/my-app:${CI_COMMIT_SHA} &&
          docker stop my-app || true &&
          docker rm my-app || true &&
          docker run -d --name my-app -p 80:3000 registry.cn-hangzhou.aliyuncs.com/your-namespace/my-app:${CI_COMMIT_SHA}
        "
  5. 条件执行与错误处理:

    • only / except: 控制任务在特定分支、标签或 MR 上运行时才执行。比如部署到生产环境的 deploy_prod 任务通常只在 main 分支合并时才触发。
    • when: manual: 任务需要手动触发。
    • allow_failure: true: 即使这个任务失败,整个管道也继续执行。常用于非关键的测试或通知任务。
    • script 中的错误处理: 在脚本中使用 set -e 可以确保任何命令失败时脚本立即退出,防止后续命令在错误状态下继续执行。

编写 .gitlab-ci.yml 是一个迭代的过程。你可能需要多次尝试和调整才能找到最适合你项目的配置。我个人的经验是,先从一个最简单的部署脚本开始,然后逐步添加缓存、测试、Docker 化等复杂功能。每次改动都提交并观察管道运行结果,这样能更快地定位问题。

好了,本文到此结束,带大家了解了《GitLabCI/CD部署到阿里云ECS教程》,希望本文对你有所帮助!关注golang学习网公众号,给大家分享更多文章知识!

堆结构是什么?堆的特点与应用详解堆结构是什么?堆的特点与应用详解
上一篇
堆结构是什么?堆的特点与应用详解
JS缓存问题解决方案大全
下一篇
JS缓存问题解决方案大全
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    542次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    511次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    498次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    484次学习
查看更多
AI推荐
  • 千音漫语:智能声音创作助手,AI配音、音视频翻译一站搞定!
    千音漫语
    千音漫语,北京熠声科技倾力打造的智能声音创作助手,提供AI配音、音视频翻译、语音识别、声音克隆等强大功能,助力有声书制作、视频创作、教育培训等领域,官网:https://qianyin123.com
    231次使用
  • MiniWork:智能高效AI工具平台,一站式工作学习效率解决方案
    MiniWork
    MiniWork是一款智能高效的AI工具平台,专为提升工作与学习效率而设计。整合文本处理、图像生成、营销策划及运营管理等多元AI工具,提供精准智能解决方案,让复杂工作简单高效。
    227次使用
  • NoCode (nocode.cn):零代码构建应用、网站、管理系统,降低开发门槛
    NoCode
    NoCode (nocode.cn)是领先的无代码开发平台,通过拖放、AI对话等简单操作,助您快速创建各类应用、网站与管理系统。无需编程知识,轻松实现个人生活、商业经营、企业管理多场景需求,大幅降低开发门槛,高效低成本。
    226次使用
  • 达医智影:阿里巴巴达摩院医疗AI影像早筛平台,CT一扫多筛癌症急慢病
    达医智影
    达医智影,阿里巴巴达摩院医疗AI创新力作。全球率先利用平扫CT实现“一扫多筛”,仅一次CT扫描即可高效识别多种癌症、急症及慢病,为疾病早期发现提供智能、精准的AI影像早筛解决方案。
    231次使用
  • 智慧芽Eureka:更懂技术创新的AI Agent平台,助力研发效率飞跃
    智慧芽Eureka
    智慧芽Eureka,专为技术创新打造的AI Agent平台。深度理解专利、研发、生物医药、材料、科创等复杂场景,通过专家级AI Agent精准执行任务,智能化工作流解放70%生产力,让您专注核心创新。
    252次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议隐私政策
返回登录
  • 重置密码