Split chapter 20

This commit is contained in:
Baohua Yang
2026-02-22 15:33:20 -08:00
parent 24d26c0797
commit 4ca47b0ea1
30 changed files with 365 additions and 325 deletions

View File

@@ -1,4 +1,6 @@
命名空间 (Namespace) Linux 内核的一个强大特性为容器提供了隔离的运行环境
# 12.2 命名空间Namespace
命名空间Namespace Linux 内核的一个强大特性为容器提供了隔离的运行环境
## 12.2 什么是 Namespace

View File

@@ -1,7 +0,0 @@
# 第二十章实战案例
本章将介绍 Docker 在不同场景下的实战案例
* [实战案例 - 操作系统](os/README.md)
* [实战案例 - CI/CD](ci/README.md)
* [ IDE 中使用 Docker](ide/README.md)

View File

@@ -1,6 +0,0 @@
# CI/CD
**持续集成 (Continuous integration)** 是一种软件开发实践每次集成都通过自动化的构建 (包括编译发布自动化测试) 来验证从而尽早地发现集成错误**持续部署 (continuous deployment)** 是通过自动化的构建测试和部署循环来快速交付高质量的产品
`Jenkins` 不同的是基于 Docker CI/CD 每一步都运行在 Docker 容器中所以理论上支持所有的编程语言

View File

@@ -1,32 +0,0 @@
# GitHub Actions
GitHub [Actions](https://github.com/features/actions) 是 GitHub 推出的一款 CI/CD 工具。
我们可以在每个 `job` `step` 中使用 Docker 执行构建步骤
```yaml
on: push
name: CI
jobs:
my-job:
name: Build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
with:
fetch-depth: 2
- name: run docker container
uses: docker://golang:alpine
with:
args: go version
```
## 20.9 概述
总体概述了以下内容
## 20.9 参考资料
* [Actions Docs](https://docs.github.com/en/actions)

View File

@@ -1,101 +0,0 @@
# Drone
基于 `Docker` `CI/CD` 工具 `Drone` 所有编译测试的流程都在 `Docker` 容器中进行
开发者只需在项目中包含 `.drone.yml` 文件将代码推送到 git 仓库`Drone` 就能够自动化的进行编译测试发布
本小节以 `GitHub` + `Drone` 来演示 `Drone` 的工作流程当然在实际开发过程中你的代码也许不在 GitHub 托管那么你可以尝试使用 `Gogs` + `Drone` 来进行 `CI/CD`
## 20.10 Drone 关联项目
Github 新建一个名为 `drone-demo` 的仓库
打开我们已经[部署好的 Drone 网站](install.md)或者 [Drone Cloud](https://cloud.drone.io),使用 GitHub 账号登录,在界面中关联刚刚新建的 `drone-demo` 仓库。
## 20.10 编写项目源代码
初始化一个 git 仓库
```bash
$ mkdir drone-demo
$ cd drone-demo
$ git init
$ git remote add origin git@github.com:username/drone-demo.git
```
这里以一个简单的 `Go` 程序为例该程序输出 `Hello World!`
编写 `app.go` 文件
```go
package main
import "fmt"
func main(){
fmt.Printf("Hello World!\n");
}
```
编写 `.drone.yml` 文件
```yaml
kind: pipeline
type: docker
name: build
steps:
- name: build
image: golang:alpine
pull: if-not-exists # always never
environment:
KEY: VALUE
commands:
- echo $KEY
- pwd
- ls
- CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .
- ./app
trigger:
branch:
- master
```
现在目录结构如下
```bash
.
├── .drone.yml
└── app.go
```
## 20.10 推送项目源代码到 GitHub
运行以下命令
```bash
$ git add .
$ git commit -m "test drone ci"
$ git push origin master
```
## 20.10 查看项目构建过程及结果
打开我们部署好的 `Drone` 网站或者 Drone Cloud即可看到构建结果
![](../../../_images/drone-build.png)
当然我们也可以把构建结果上传到 GitHubDocker Registry云服务商提供的对象存储或者生产环境中
本书 GitBook 也使用 Drone 进行 CI/CD具体配置信息请查看本书根目录 [`.drone.yml`](https://github.com/yeasy/docker_practice/blob/master/.drone.yml) 文件。
## 20.10 参考链接
* [Drone Github](https://github.com/drone/drone)
* [Drone 文档](https://docs.drone.io/)
* [Drone 示例](https://github.com/docker-practice/drone-demo)

View File

@@ -1,26 +0,0 @@
# 20.2.3.2 Drone Demo
## Drone CI Demo 项目
这是一个基于 Go 语言编写的简单 Web 应用示例用于演示 Drone CI 的持续集成流程
## 20.2.3.2.1 目录结构
* `app.go`简单的 Go Web 服务器代码
* `.drone.yml`Drone CI 的配置文件定义了构建和测试流程
* `Dockerfile`定义了如何将该应用构建为 Docker 镜像
## 20.2.3.2.2 如何运行
1. 确保本地已安装 Docker 环境
2. 进入本目录构建镜像
```bash
docker build -t drone-demo-app .
```
3. 运行容器
```bash
docker run -p 8080:8080 drone-demo-app
```
4. 访问 `http://localhost:8080` 查看效果

View File

@@ -1,95 +0,0 @@
## 20.2.3.1 部署 Drone
本节涵盖了相关内容与详细描述主要探讨以下几个方面
### 20.2.3.1.1 要求
* 拥有公网 IP域名 (如果你不满足要求可以尝试在本地使用 Gogs + Drone)
* 域名 SSL 证书 (目前国内有很多云服务商提供免费证书)
* 熟悉 `Docker` 以及 `Docker Compose`
* 熟悉 `Git` 基本命令
* `CI/CD` 有一定了解
### 20.2.3.1.2 新建 GitHub 应用
登录 GitHub https://github.com/settings/applications/new 新建一个应用。
![](https://docs.drone.io/screenshots/github_application_create.png)
接下来查看这个应用的详情记录 `Client ID` `Client Secret`之后配置 Drone 会用到
### 20.2.3.1.3 配置 Drone
我们通过使用 `Docker Compose` 来启动 `Drone`编写 `compose.yaml` ( `docker-compose.yml`) 文件
```yaml
services:
drone-server:
image: drone/drone:2.3.1
ports:
- 443:443
- 80:80
volumes:
- drone-data:/data:rw
- ./ssl:/etc/certs
restart: always
environment:
- DRONE_SERVER_HOST=${DRONE_SERVER_HOST:-https://drone.yeasy.com}
- DRONE_SERVER_PROTO=${DRONE_SERVER_PROTO:-https}
- DRONE_RPC_SECRET=${DRONE_RPC_SECRET:-secret}
- DRONE_GITHUB_SERVER=https://github.com
- DRONE_GITHUB_CLIENT_ID=${DRONE_GITHUB_CLIENT_ID}
- DRONE_GITHUB_CLIENT_SECRET=${DRONE_GITHUB_CLIENT_SECRET}
drone-agent:
image: drone/drone-runner-docker:1
restart: always
depends_on:
- drone-server
volumes:
- /var/run/docker.sock:/var/run/docker.sock:rw
environment:
- DRONE_RPC_PROTO=http
- DRONE_RPC_HOST=drone-server
- DRONE_RPC_SECRET=${DRONE_RPC_SECRET:-secret}
- DRONE_RUNNER_NAME=${HOSTNAME:-demo}
- DRONE_RUNNER_CAPACITY=2
dns: 114.114.114.114
volumes:
drone-data:
```
新建 `.env` 文件输入变量及其值
```bash
## 必填 服务器地址,例如 drone.domain.com
DRONE_SERVER_HOST=
DRONE_SERVER_PROTO=https
DRONE_RPC_SECRET=secret
HOSTNAME=demo
## 必填 在 GitHub 应用页面查看
DRONE_GITHUB_CLIENT_ID=
## 必填 在 GitHub 应用页面查看
DRONE_GITHUB_CLIENT_SECRET=
```
#### 概述
总体概述了以下内容
#### 启动 Drone
运行以下命令
```bash
$ docker compose up -d
```

View File

@@ -1,3 +0,0 @@
# IDE 中使用 Docker
使用 IDE 进行开发往往要求本地安装好工具链一些 IDE 支持 Docker 容器中的工具链这样充分利用了 Docker 的优点而无需在本地安装

View File

@@ -1,11 +0,0 @@
## 20.14 VS Code 中使用 Docker
本节涵盖了相关内容与详细描述主要探讨以下几个方面
### 20.14.1 概述
总体概述了以下内容
### 20.14.2 Docker 容器作为远程开发环境
无需本地安装开发工具直接将 Docker 容器作为开发环境具体参考[官方文档](https://code.visualstudio.com/docs/remote/containers)。

View File

@@ -1,9 +0,0 @@
# 操作系统
目前常用的 Linux 发行版主要包括 `Debian/Ubuntu` 系列和 `CentOS/Fedora` 系列
前者以自带软件包版本较新而出名后者则宣称运行更稳定一些选择哪个操作系统取决于读者的具体需求
使用 Docker读者只需要一个命令就能快速获取一个 Linux 发行版镜像这是以往包括各种虚拟化技术都难以实现的这些镜像一般都很精简但是可以支持完整 Linux 系统的大部分功能
本章将介绍如何使用 Docker 安装和使用 `Busybox``Alpine``Debian/Ubuntu``CentOS/Fedora` 等操作系统

9
20_cases_os/README.md Normal file
View File

@@ -0,0 +1,9 @@
# 第二十章 实战案例 - 操作系统
本章将介绍 Docker 在不同操作系统镜像场景下的实战案例
* [Busybox](busybox.md)
* [Alpine](alpine.md)
* [Debian Ubuntu](debian.md)
* [CentOS Fedora](centos.md)
* [本章小结](summary.md)

View File

@@ -1,4 +1,4 @@
## 20.3 Alpine
# 20.3 Alpine
本节涵盖了相关内容与详细描述主要探讨以下几个方面

View File

@@ -1,4 +1,4 @@
## 20.2 Busybox
# 20.2 Busybox
本节涵盖了相关内容与详细描述主要探讨以下几个方面

View File

@@ -1,4 +1,4 @@
## 20.5 CentOS Fedora
# 20.5 CentOS Fedora
本节涵盖了相关内容与详细描述主要探讨以下几个方面

View File

@@ -1,4 +1,4 @@
## 20.4 Debian Ubuntu
# 20.4 Debian Ubuntu
`Debian` `Ubuntu` 都是目前较为流行的 **Debian ** 的服务器操作系统十分适合研发场景`Docker Hub` 上提供了官方镜像国内各大容器云服务也基本都提供了相应的支持

View File

@@ -1,4 +1,4 @@
## 20.6 本章小结
# 20.6 本章小结
本章讲解了典型操作系统镜像的下载和使用

11
21_case_devops/README.md Normal file
View File

@@ -0,0 +1,11 @@
# 第二十一章 实战案例 - Devops
本章将介绍 Docker DevOps 场景下的实战案例
* [DevOps 完整工作流](devops_workflow.md)
* [GitHub Actions](github_actions.md)
* [Drone](drone.md)
* [Drone Demo](drone_demo.md)
* [ IDE 中使用 Docker](ide.md)
* [VS Code](vsCode.md)
* [本章小结](summary.md)

View File

@@ -1,8 +1,8 @@
## 20.8 DevOps 工作流完整示例
# 21.1 DevOps 工作流完整示例
本章将演示一个基于 DockerKubernetes Jenkins/GitLab CI 的完整 DevOps 工作流
本章将演示一个基于 DockerKubernetes Jenkins/GitLab CI 的完整 DevOps 工作流
### 20.8.1 工作流概览
## 21.1.1 工作流概览
1. **Code**开发人员提交代码到 GitLab
2. **Build**GitLab CI 触发构建任务
@@ -12,15 +12,14 @@
6. **Verify**人工或自动化验证
7. **Release (Production)**审批后自动部署到生产环境
### 20.8.2 关键配置示例
## 21.1.2 关键配置示例
本节涵盖了相关内容与详细描述主要探讨以下几个方面
本节通过一组最小可用的片段展示典型 DevOps 流程中与 Docker 相关的关键配置
#### 1. Dockerfile 多阶段构建
### 1. Dockerfile 多阶段构建
使用 Docker 多阶段构建可以有效减小镜像体积
Dockerfile 内容如下
```dockerfile
@@ -39,10 +38,9 @@ COPY --from=builder /app/main .
CMD ["./main"]
```
#### 2. GitLab CI 配置
GitLab CI (gitlab-ci.yml) 配置如下
### 2. GitLab CI 配置
GitLab CI`.gitlab-ci.yml`配置如下
```yaml
stages:
@@ -62,7 +60,8 @@ build_image:
services:
- docker:20.10.16-dind
script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD \
$CI_REGISTRY
- docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA .
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
@@ -74,13 +73,14 @@ deploy_staging:
- kubectl config set-credentials admin --token=$KUBE_TOKEN
- kubectl config set-context default --cluster=k8s --user=admin
- kubectl config use-context default
- kubectl set image deployment/myapp myapp=$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA -n staging
- kubectl set image deployment/myapp myapp=$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
-n staging
only:
- develop
```
### 20.8.3 最佳实践
## 21.1.3 最佳实践
1. **不可变基础设施**一旦镜像构建完成在各个环境 (DevStagingProd) 中都应该使用同一个镜像 tag (通常是 commit hash)而不是重新构建
1. **不可变基础设施**一旦镜像构建完成在各个环境DevStagingProd中都应该使用同一个镜像 tag通常是 commit hash而不是重新构建
2. **配置分离**使用 ConfigMap Secret 管理环境特定的配置不要打包进镜像
3. **GitOps**考虑引入 ArgoCD将部署配置也作为代码存储在 Git 实现 Git 驱动的部署同步

102
21_case_devops/drone.md Normal file
View File

@@ -0,0 +1,102 @@
# 21.3 Drone
基于 `Docker` `CI/CD` 工具 `Drone`所有编译测试的流程都在容器中进行
开发者只需在项目中包含 `.drone.yml` 文件将代码推送到 git 仓库`Drone` 就能够自动化地进行编译测试发布
本小节以 `GitHub` + `Drone` 来演示 `Drone` 的工作流程
当然在实际开发过程中你的代码也许不在 GitHub 托管那么你可以尝试使用 `Gogs` + `Drone` 来进行 CI/CD
## 21.3.1 关联项目
GitHub 新建一个名为 `drone-demo` 的仓库
打开我们已经部署好的 Drone 网站或者 [Drone Cloud](https://cloud.drone.io)
使用 GitHub 账号登录在界面中关联刚刚新建的 `drone-demo` 仓库
## 21.3.2 编写项目源代码
初始化一个 git 仓库
```bash
mkdir drone-demo
cd drone-demo
git init
git remote add origin git@github.com:username/drone-demo.git
```
这里以一个简单的 `Go` 程序为例该程序输出 `Hello World!`
编写 `app.go` 文件
```go
package main
import "fmt"
func main() {
fmt.Printf("Hello World!\n")
}
```
编写 `.drone.yml` 文件
```yaml
kind: pipeline
type: docker
name: build
steps:
- name: build
image: golang:alpine
pull: if-not-exists
environment:
KEY: VALUE
commands:
- echo $KEY
- pwd
- ls
- CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .
- ./app
trigger:
branch:
- master
```
现在目录结构如下
```bash
.
├── .drone.yml
└── app.go
```
## 21.3.3 推送项目源代码到 GitHub
运行以下命令
```bash
git add .
git commit -m "test drone ci"
git push origin master
```
## 21.3.4 查看项目构建过程及结果
打开我们部署好的 `Drone` 网站或者 Drone Cloud即可看到构建结果
![](../../../_images/drone-build.png)
当然我们也可以把构建结果上传到 GitHubDocker Registry
云服务商提供的对象存储或者生产环境中
## 21.3.5 参考链接
* [Drone Github](https://github.com/drone/drone)
* [Drone 文档](https://docs.drone.io/)
* [Drone 示例](https://github.com/docker-practice/drone-demo)

View File

@@ -0,0 +1,22 @@
# 21.4 Drone Demo
## 21.4.1 Demo 项目说明
这是一个基于 Go 语言编写的简单 Web 应用示例用于演示 Drone CI 的持续集成流程
## 21.4.2 目录结构
* `drone_demo.app.go`简单的 Go Web 服务器代码
* `drone_demo.drone.yml`Drone CI 的配置文件定义了构建和测试流程
## 21.4.3 如何使用
1. 确保本地已安装 Docker 环境
2. 将示例文件重命名为 Drone 期望的文件名
```bash
cp drone_demo.app.go app.go
cp drone_demo.drone.yml .drone.yml
```
3. `app.go` `.drone.yml` 推送到你的 `drone-demo` 仓库即可在 Drone 中看到构建结果

View File

@@ -0,0 +1,53 @@
# 21.2 GitHub Actions
GitHub [Actions](https://github.com/features/actions) 是 GitHub 推出的一款 CI/CD 工具。
我们可以在每个 `job` `step` 中使用 Docker 执行构建步骤
## 21.2.1 最小可用示例
在仓库根目录创建 `/.github/workflows/ci.yml`
```yaml
name: CI
on:
push:
pull_request:
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- uses: docker/build-push-action@v6
with:
context: .
push: false
tags: local/test:ci
```
该示例会在 GitHub Actions 中构建当前仓库的 Docker 镜像不推送到 registry
## 21.2.2 最佳实践
* 固定 action 的主版本例如 `@v4` / `@v6`避免使用 `@master` 这类浮动引用
* 设置最小权限例如 `contents: read`需要写入权限时再打开
* 需要依赖缓存时优先使用官方支持的缓存方案例如针对语言包管理器的 cache BuildKit cache
如果你需要在某个步骤里直接运行容器镜像而不是构建镜像可以使用 `docker://` 语法
```yaml
- name: Run container step
uses: docker://golang:alpine
with:
args: go version
```
## 21.2.3 参考资料
* [Actions Docs](https://docs.github.com/en/actions)

53
21_case_devops/ide.md Normal file
View File

@@ -0,0 +1,53 @@
# 21.5 IDE 中使用 Docker
使用 IDE 进行开发往往要求本地安装好工具链一些 IDE 支持 Docker 容器中的工具链这样充分利用了 Docker 的优点而无需在本地安装
本节关注一个核心目标**开发依赖放进容器源码编辑体验留在本地 IDE**
## 21.5.1 适用场景
* 团队希望统一开发环境Go/Node/Python 版本系统依赖编译链
* 本地系统不方便安装依赖例如 Windows公司管控环境
* 项目依赖较重例如需要 `gcc`数据库客户端特定系统库
不太适合的场景强依赖本机 GPU/USB 设备或需要非常低延迟文件 IO 的工程此时可能需要额外调优挂载/同步策略
## 21.5.2 最小可用模式docker compose + 开发容器
下面用一个长期运行的开发容器作为例子 Go 为例你可以替换为 Node/Python
1. 在项目中创建 `compose.yaml`或复用你已有的 compose 文件
```yaml
services:
dev:
image: golang:1.22
working_dir: /work
volumes:
- ./:/work
command: sleep infinity
```
1. 启动开发容器
```bash
docker compose up -d
```
1. 进入容器安装依赖/执行命令
```bash
docker compose exec dev bash
go version
go test ./...
```
这个模式的优点是简单直接IDE 无关缺点是 IDE 需要额外配置
例如配置远程解释器/语言服务或使用 VS Code Dev Containers
## 21.5.3 目录挂载与权限建议
* Linux 下如果遇到容器内写文件权限问题优先确保容器内用户与宿主机 UID/GID 对齐
VS Code Dev Containers 支持自动处理手写 Dockerfile/compose 时也可以显式设置用户
* 如果遇到文件变更监听不生效常见于 macOS/Windows 的虚拟化文件系统
优先使用语言/工具支持的轮询模式或提高 watcher 限制

16
21_case_devops/summary.md Normal file
View File

@@ -0,0 +1,16 @@
# 21.7 本章小结
本章通过一个完整的 DevOps 工作流示例串联了从代码提交自动化测试镜像构建
到部署发布的一整套实践路径
在落地时建议重点把握以下原则
* **不可变交付物**同一份产物镜像在不同环境中流转使用 commit hash 等方式标识版本
* **最小权限与密钥管理**CI 平台权限尽量收敛敏感信息使用 Secret 管理并定期轮换
* **流水线可观测与可回滚**为关键步骤保留日志与制品发布失败时能快速定位并回滚
* **开发环境一致性**通过 Dev Containers / compose 开发容器减少在我电脑上可以的问题
下一步你可以根据团队现状选择一条主线深入
* 已在用 GitHub优先补全 Actions 的缓存制品发布策略
* 自建体系结合私有 RegistryKubernetes GitOps 工具完善部署与审计

62
21_case_devops/vsCode.md Normal file
View File

@@ -0,0 +1,62 @@
# 21.6 VS Code 中使用 Docker
VS Code [Dev Containers](https://code.visualstudio.com/docs/devcontainers/containers)
可以把开发环境放进容器同时保留 VS Code 的编辑补全调试体验
本节提供一个最小可用示例把任意项目 Go 为例变成打开即开发的容器化环境
## 21.6.1 前置条件
* 安装 Docker Desktop Linux 上的 Docker Engine
* VS Code 安装扩展Dev Containers`ms-vscode-remote.remote-containers`
## 21.6.2 最小示例.devcontainer/devcontainer.json
在项目根目录创建 `.devcontainer/devcontainer.json`
```json
{
"name": "docker-practice-dev",
"image": "golang:1.22",
"workspaceFolder": "/work",
"workspaceMount": "source=${localWorkspaceFolder},target=/work,type=bind",
"customizations": {
"vscode": {
"extensions": [
"golang.Go"
]
}
},
"postCreateCommand": "go version"
}
```
然后在 VS Code 命令面板选择
* `Dev Containers: Reopen in Container`
VS Code 会拉取镜像并启动容器随后你就可以在容器内运行
```bash
go test ./...
```
## 21.6.3 结合 Docker Compose可选
如果项目同时依赖数据库/缓存例如 Postgres/Redis可以使用 `dockerComposeFile`
把依赖一起拉起
示例`devcontainer.json` 片段
```json
{
"name": "compose-dev",
"dockerComposeFile": [
"../docker-compose.yml"
],
"service": "dev",
"workspaceFolder": "/work"
}
```
注意`service` 需要对应 compose 里的服务名

View File

@@ -163,21 +163,21 @@
* [19.1 Prometheus](19_observability/prometheus.md)
* [19.2 ELK 套件](19_observability/elk.md)
* [本章小结](19_observability/summary.md)
* [第二十章 实战案例](20_cases/README.md)
* [20.1 实战案例 - 操作系统](20_cases/os/README.md)
* [20.1.1 Busybox](20_cases/os/busybox.md)
* [20.1.2 Alpine](20_cases/os/alpine.md)
* [20.1.3 Debian Ubuntu](20_cases/os/debian.md)
* [20.1.4 CentOS Fedora](20_cases/os/centos.md)
* [本章小结](20_cases/os/summary.md)
* [20.2 实战案例 - CI/CD](20_cases/ci/README.md)
* [20.2.1 DevOps 完整工作流](20_cases/ci/devops_workflow.md)
* [20.2.2 GitHub Actions](20_cases/ci/actions/README.md)
* [20.2.3 Drone](20_cases/ci/drone/README.md)
* [20.2.3.1 部署 Drone](20_cases/ci/drone/install.md)
* [20.2.3.2 Drone Demo](20_cases/ci/drone/demo/README.md)
* [20.3 IDE 中使用 Docker](20_cases/ide/README.md)
* [20.3.1 VS Code](20_cases/ide/vsCode.md)
* [第二十章 实战案例 - 操作系统](20_cases_os/README.md)
* [20.1 Busybox](20_cases_os/busybox.md)
* [20.2 Alpine](20_cases_os/alpine.md)
* [20.3 Debian Ubuntu](20_cases_os/debian.md)
* [20.4 CentOS Fedora](20_cases_os/centos.md)
* [本章小结](20_cases_os/summary.md)
* [第二十一章 实战案例 - Devops](21_case_devops/README.md)
* [21.1 DevOps 完整工作流](21_case_devops/devops_workflow.md)
* [21.2 GitHub Actions](21_case_devops/github_actions.md)
* [21.3 Drone](21_case_devops/drone.md)
* [21.4 Drone Demo](21_case_devops/drone_demo.md)
* [21.5 IDE 中使用 Docker](21_case_devops/ide.md)
* [21.6 VS Code](21_case_devops/vsCode.md)
* [本章小结](21_case_devops/summary.md)
## 附录