告别手动部署!Docker + Drone 前端自动化部署指南

但行好事,莫问前程

前言

本文不只是配置文件的堆砌,也解释是什么和为什么,希望大家能耐心学习😽。

现在的项目大多通过各种 CI/CD工具 (例如著名的 JenkinsgitLab,github推出的 github actions)来进行 自动化部署

它们已成为市场主流,是项目基建中不可或缺的一环。

开发人员只需开发完成后,一个代码推送/合并,项目便会自动部署到服务器上运行,呈现给用户。

持续部署(Continuous Deployment,CD):

  • 指自动化部署已通过测试的代码到生产环境,以实现快速、可靠的软件交付。
  • CD 流程包括自动化构建部署流程、自动化测试、环境配置管理等步骤,以确保部署的软件质量和稳定性。
  • 目的是缩短软件交付周期,降低部署风险,提高部署的可重复性和一致性

相比于古早缓慢且充满风险的手动部署,它们能将项目 自动化的构建、测试和部署到线上环境以实现交付的高质量和效率

无论你是什么方向的开发者,学习+使用它们都是一个极具性价比的选择。

接下来我们一起搭建自动化部署平台,如果对你有所帮助,还望点赞、收藏、关注三连😽。

简介

本文要分享的是后起之秀 Drone ,它免费、轻量、简洁、支持私有化,更重要的是它的 yaml写法pipeline流水线 非常适合对运维陌生的同学去理解相关流程。

如果对 linux 和 docker 不熟悉的同学需要先简单了解相关知识,本文使用 docker compose 来编排容器。

Drone 深度集成了多个 SCM 网站,包括 GitHub、GitLab、Gitee等。它的每个构建都在一个隔离的 Docker 容器中运行;另外它也支持插件,可以使用你熟知的语言轻松的扩展它们。

当前一切都部署好后,只需在代码仓库目录下添加一个描述文件 .drone.yml,就可以完成 CI/CD 配置。

Drone 需要创建两个容器

  • Server: 负责任务调度、提供视图、用户权限配置 . . .
  • Runner: 执行 Pipeline 具体任务、创建隔离的容器环境、上报日志和状态 . . .

流程 & 文档

我使用的服务器:4核4G - CentOS - 40G SSD (其实2核2G即可,Drone资源占用很少)

搭建自动化部署的流程如下

  1. 配置 Github - OAuth Application
  2. 安装、配置 DockerDrone ServerDrone Runner
  3. 编写 docker-compose.yml 编排容器,用于管理 Drone ServerDrone Runner
  4. 了解 pipeline,了解常用插件,在代码仓库中加入 .drone.yml
  5. 推送代码测试打包效果

相关文档

drone server 服务端 docs.drone.io/server/over...

drone runer linux docs.drone.io/runner/dock...

drone pieline 配置 docs.drone.io/pipeline/ov...

drone plugins plugins.drone.io/

常用指令:

docker compose down <image-name> 关闭指定容器(不指定则默认所有)

docker compose up -d <image-name> 启动指定容器(不指定则默认所有)

docker compose logs -f <image-name> 打印容器的日志

docker compose exec <image-name> bash 进入指定容器的shell

docker ps 查看正在运行的容器

docker images 查看下载的镜像

netstat -tulnp 显示进程与占用的端口

实践

Github OAuth

GitHub OAuth 的作用是: "让用户安全地授权第三方应用代表自己执行特定操作"

在Drone的使用场景中,它提供了:

  • 🔐 安全登录 - 不用为Drone单独创建账号
  • 🔄 自动同步 - Drone自动获取你的仓库列表
  • ⚡ 自动触发 - Drone有权限设置webhook,代码推送即触发构建
  • 🎯 权限可控 - 你可以随时在GitHub上撤销Drone的访问权限

配置

  1. 头像 -> Settings -> Developer settings -> OAuth Apps -> New OAuth App

  2. 填写项目名

  3. HomePage URL ------ Github允许调用登录的URL,我们设置为drone server运行的端口

  4. Authorization callback URL ------ 认证成功后的回调网址,在drone里为 url + /login

  1. 点击 New Secret
  1. 拿到 Client IDClient Secret,记录下来!后续用于 Drone 的配置

127.0.0.1 只为预设,实际使用时请替换为自己的真实域名 或 IP+端口

Docker

bash 复制代码
# 安装docker
sudo dnf config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

sudo dnf install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

# 启动指令
sudo systemctl start docker
sudo systemctl enable docker

# 测试指令
sudo docker run hello-world

# 配置镜像加速 + 重启服务 
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": [
    "https://registry.docker-cn.com",
    "https://docker.mirrors.ustc.edu.cn",
    "https://hub-mirror.c.163.com"
  ]
}
EOF

# 重启服务
sudo systemctl restart docker

镜像加速部分,个人服务器访问 "docker.1ms.run" 最快,大家结合自身情况配置

Docker Compose

Docker Compose 可以定义和运行多个 Docker 容器应用的工具。它允许你使用一个单独的文件(通常称为 docker-compose.yml)来配置应用程序的服务,然后使用该文件快速启动整个应用的所有服务。

Drone

使用docker安装drone的两个容器,Server端 - 控制调度和提供视图,Runner 端 - 执行流水线和上报状态

bash 复制代码
docker pull drone/drone:latest 
docker pull drone/drone-runner-docker:latest

同时创建一个共享密钥,用于 Server 和 Runner 之间的通信认证,使用此密钥填充环境变量 DRONE_RPC_SECRET

bash 复制代码
openssl rand -hex 16
c1da0391axxxxxxxxxxxxxxxxx

drone-server

/opt/docker/docker-compose.yml

yml 复制代码
services:
  # drone 服务端
  drone-server: 
    container_name: drone-server
    image: drone/drone:latest
    restart: always
    ports:
      #  端口映射
      - 8082:80  
      - 4443:443

    volumes:
      # 挂载数据目录,持久化 Drone 的配置信息和数据库
	# 容器 /data 目录 -> 宿主机当前 ./drone-data 目录
      - ./drone-data:/data

    environment:
      # Git OAuth - Client ID
      - DRONE_GITHUB_CLIENT_ID=Ov23lxxxxxxxxx
      # Git OAuth - Client Secret
      - DRONE_GITHUB_CLIENT_SECRET=d60645938xxxxxxxxxxxxxxxxxxxxx
      # Drone Server 和 Runner 之间的 RPC 认证密钥,需保持一致
      - DRONE_RPC_SECRET=c1da0391axxxxxxxxxxxxxxxxx
      # Drone Server的公网地址
      - DRONE_SERVER_HOST=<服务器的公网IP>:<端口>
      # 通信协议
      - DRONE_SERVER_PROTO=http
      # 创建管理员账户
      - DRONE_USER_CREATE=username:XiwE1,admin:true
  • ports - 为宿主机与容器的端口映射

  • DRONE_GITHUB_CLIENT_IDDRONE_GITHUB_CLIENT_SECRET

    • 对应上文 Git OAuthClient IDClient Secret,用于身份认证
  • DRONE_RPC_SECRET - 是刚刚生成的共享密钥,用于 Server 与 Runner 通信

  • DRONE_SERVER_HOST - 改为服务器的真实IP和设置运行的端口

  • DRONE_SERVER_PROTO - 我只用到了 http,如有证书可设置 https

  • DRONE_USER_CREATE - 设置账户,name 为 github 账号名

此时我们启动服务

docker compose up -d drone-server

访问对应的公网网址,完成登录后(记得在Github修改 homepageURL + Authorization callback URL),即可看到自己仓库的所有项目。

我们选中一个测试项目的进行激活。

可以看到 github - 项目 - webhooks 已经激活了。

对项目进行简单的配置 Trusted -> SAVE。

drone-runer

/opt/docker/docker-compose.yml

yml 复制代码
  # drone 执行者(runer)
  drone-runner: 
    container_name: drone-runner
    image: drone/drone-runner-docker:latest
    restart: always
    ports:
      - 3000:3000  

    volumes:
      # 允许 Runner 在宿主机上操作 Docker 容器
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - DRONE_RPC_PROTO=http
      # 与 drone server 的container_name一致
      - DRONE_RPC_HOST=drone-server
      # Drone Server 和 Runner 之间的 RPC 认证密钥,需保持一致
      - DRONE_RPC_SECRET=c1da0391xxxxxxxxxxxxxxxx
      # 设置并发任务数上限
      - DRONE_RUNNER_CAPACITY=3
      - DRONE_RUNNER_NAME=drone-runner
    depends_on:
      - drone-server
  • volumes - runner 执行流水线时需要不断地创建镜像容器,需要允许其操作 Docker
  • DRONE_RPC_HOST - 同服务器可内部访问使用 container-name 即可,如果跨服务器请填写 Drone Server 的域名 或 IP+端口
  • DRONE_RPC_SECRET - 共享密钥,与Server保持一致

自动构建与部署等功能都依赖于 Drone Runner。

pipeline & .drone.yml

流水线(Pipeline)在软件工程中,特别是在持续集成和持续部署(CI/CD)中,是一个自动化流程,它将软件从代码到交付的多个步骤串联起来。

每个步骤都会完成一个特定的任务(例如编译、测试、部署),并且这些步骤按顺序执行,如果其中一个步骤失败,整个流程就会停止,从而保证软件质量。

简单来说,Pipeline 是把手动重复的软件发布过程,变成全自动的标准化流水线。无需人工干预,提高了效率并减少了人为错误。

YAML 是流水线的「说明书」,语法易于阅读和表达,能用结构化的文字描述整个自动化流程

Drone 通过在项目的根目录中放置 .drone.yml 文件来配置流水线。

关于 .drone.yml 文件,通常有以下规则:

  • 每个配置文件都以 kind: pipeline 开头
  • 需要指定执行器类型 ,例如Docker(type: docker
  • 需要设置 触发条件(Trigger) ,控制管道在何时 运行。最常用的是代码的 push 事件
  • 步骤(Steps)
    • 管道由一个或多个步骤组成,每个步骤代表一个独立的任务(例如安装依赖、构建、测试、部署)。
    • 每个步骤通常需要指定:
      • 名称(name) :步骤标识,例如 builddeploy
      • 镜像(image) :执行任务的Docker镜像,这决定了步骤的运行环境
      • 命令(commands) :在容器内执行的Shell命令序列。
  • 挂载卷(Volumes) ,用于在步骤之间持久化数据 或与宿主机共享文件
  • ...

官方文档 docs.drone.io/pipeline/ov...

我们可以在steps里集成插件,drone plugins plugins.drone.io/

例如 用于通知构建状态的 slack,用于文件传输的 rsync,发布资源到S3的 AWS S3/AWS S3 Sync,等等。

我的项目(React + Yarn + Vite)构建配置如下:

./.drone.yml

yml 复制代码
# 定义一个管道
kind: pipeline
# 定义管道类型
# 使用Docker执行器运行流水线
type: docker
name: default

# drone启动时,都会先执行clone代码操作,将对应仓库代码拉取到/drone/src目录下
clone:
  # 重试以防网络问题导致clone失败
  retries: 2

trigger:
  branch:
    - main

volumes:
    # 将node_modules缓存到宿主机指定目录下
    # 避免重新install延迟或者失败
  - name: node_modules
    host:
      path: /home/drone/cache/fe/node_modules
  # - name: pnpm-cache
  #   host:
  #     path: /home/drone/cache/fe/pnpm-store
  # 挂载Docker套接字
  - name: docker-sock
    host:
      path: /var/run/docker.sock
  - name: admin-website
    host:
      path: /home/admin-website

steps:
  # 编译阶段
  - name: build
    image: node:23
    volumes:
      - name: node_modules
        # 挂载到容器内的路径
        # 宿主机 node_modules -> 挂载到容器/drone/src/node_modules目录
        path: /drone/src/node_modules
    #   - name: pnpm-cache
    #     path: /drone/src/.pnpm-store
    commands:
      - echo "============构建前的文件==============="
      - pwd
      - ls -alt
      - echo "======================================"
      - yarn --version || npm install -g yarn
      - yarn install --frozen-lockfile
      - yarn build
      - echo "============构建后的产物==============="
      - ls -la dist || exit 1

  # 部署阶段
  - name: deploy
    image: drillster/drone-rsync
    network_mode: host  # 使用宿主机网络
    settings:
      hosts:
        - localhost
        # 或者服务器ip
      user: root
      key:
        from_secret: deploy_ssh_secret
      port: 22
      source: dist/
      target: /home/admin-website

  # 如果在同一个服务器,可以把代码直接编译进挂载目录或者移入挂载目录
  # - name: deploy
  #   image: alpine:latest
  #   volumes:
  #     - name: admin-website
  #     # 在容器内提供target目录 挂载到宿主机的host目录下
  #       path: /target
  #   commands:
  #     - apk add --no-cache rsync
  #     # 将容器内的dist目录同步到target目录,给volumes挂载
  #     - rsync -av --delete /drone/src/dist/ /target/
  #     # 验证文件是否复制成功
  #     - ls -la /target/ || exit 1

测试自动部署

至此我们就大功告成,可以进行测试了,现在修改代码后 push 远程 main 分支,即可触发自动构建。

改一下项目版本号试试

可以看到任务很快就完成了

访问网站(记得配置 nginx 代理)

结语

整套流程下来并不困难,但需要开发生涯中的多种知识为基础,并加以应用,理解完整的产品开发流程。

希望前端开发的思维不再局限于编码,从局部到全局,从编码到交付,做一个能独立交付产品的程序员。

如果公司里正好缺少对应的基建,便是你大展身手的机会。

还有很多细节值得我们讨论:

  1. 镜像构建时如何缓存,避免重复的无效构建
  2. 如何将项目直接部署到多个服务器运行,而不需要多次配置nginx
  3. 部署后出现问题怎么快速回滚
  4. 自动化测试
  5. . . .

大家感兴趣的话,再写一文讨论。

不要光看不实践哦~ 希望本文能对你有所帮助

持续更新前端知识,脚踏实地不水文,真的不关注一下吗~

写作不易,如果有收获还望 点赞+收藏 🌹

才疏学浅,如有问题或建议还望指教~

相关推荐
实习生小黄14 分钟前
WXT 框架下的 Window 对象获取
前端·浏览器
少卿17 分钟前
Webpack 插件开发指南:深入理解 Compiler Hooks
前端·webpack
一名普通的程序员17 分钟前
Design Tokens的设计与使用详解:构建高效设计系统的核心技术
前端
VaJoy17 分钟前
Cocos Creator Shader 入门 ⒇ —— 液态玻璃效果
前端·cocos creator
suke19 分钟前
听说前端又死了?
前端·人工智能·程序员
肠胃炎24 分钟前
Flutter 线性组件详解
前端·flutter
肠胃炎27 分钟前
Flutter 布局组件详解
前端·flutter
hqzing39 分钟前
介绍一个容器化的鸿蒙环境
c++·docker
Jing_Rainbow39 分钟前
【AI-5 全栈-1 /Lesson9(2025-10-29)】构建一个现代前端 AI 图标生成器:从零到完整实现 (含 AIGC 与后端工程详解)🧠
前端·后端