diff --git a/.drone.yml b/.drone.yml new file mode 100644 index 0000000..12b698e --- /dev/null +++ b/.drone.yml @@ -0,0 +1,17 @@ +workspace: + base: /srv/gitbook-src + path: . +pipeline: + build: + image: yeasy/docker_practice:latest + # pull: true + environment: + - TZ=Asia/Shanghai + secrets: [key1, key2] + commands: + # - echo $${key1} + # - echo $KEY2 + - docker-entrypoint.sh build + when: + event: [push, pull_request, tag, deployment] + branch: master diff --git a/SUMMARY.md b/SUMMARY.md index 0416aa8..d89bb28 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -133,6 +133,8 @@ * [Debian Ubuntu](cases/os/debian.md) * [CentOS Fedora](cases/os/centos.md) * [本章小结](cases/os/summary.md) +* [实战案例-CI/CD](cases/ci/README.md) + * [Drone](cases/ci/drone.md) * [附录](appendix/README.md) * [附录一:常见问题总结](appendix/faq/README.md) * [附录二:热门镜像介绍](appendix/repo/README.md) @@ -146,3 +148,4 @@ * [Node.js](appendix/repo/nodejs.md) * [附录三:Docker 命令查询](appendix/command/README.md) * [附录四:资源链接](appendix/resources/README.md) + * [附录五:Docker 中文资源](appendix/resources/cn.md) diff --git a/appendix/resources/README.md b/appendix/resources/README.md index c099be2..8773926 100644 --- a/appendix/resources/README.md +++ b/appendix/resources/README.md @@ -15,7 +15,7 @@ ## 实践参考 -* Dockerfile 参考:https://docs.docker.com/reference/builder/ +* Dockerfile 参考:https://docs.docker.com/engine/reference/builder/ * Dockerfile 最佳实践:https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/ ## 技术交流 diff --git a/appendix/resources/cn.md b/appendix/resources/cn.md new file mode 100644 index 0000000..333db2c --- /dev/null +++ b/appendix/resources/cn.md @@ -0,0 +1,7 @@ +# Docker 中文资源 + +* [Docker 问答录(100 问)](https://blog.lab99.org/post/docker-2016-07-14-faq.html) + +* [Docker CE 变更日志中文翻译](https://github.com/allencloud/docker-changelog-chinese) + +* [Dockerfile 最佳实践中文翻译](http://blog.csdn.net/guyue35/article/details/53891862) diff --git a/cases/.image/drone-build.png b/cases/.image/drone-build.png new file mode 100644 index 0000000..0c6c009 Binary files /dev/null and b/cases/.image/drone-build.png differ diff --git a/cases/.image/drone-github.png b/cases/.image/drone-github.png new file mode 100644 index 0000000..9e84569 Binary files /dev/null and b/cases/.image/drone-github.png differ diff --git a/cases/ci/README.md b/cases/ci/README.md new file mode 100644 index 0000000..4091018 --- /dev/null +++ b/cases/ci/README.md @@ -0,0 +1,7 @@ +# CI/CD + +持续集成(Continuous integration)是一种软件开发实践,每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽早地发现集成错误。 + +持续部署(continuous deployment)是通过自动化的构建、测试和部署循环来快速交付高质量的产品。 + +与 `Jenkins` 不同的是,基于 Docker 的 CI/CD 每一步都运行在 Docker 镜像中,所以理论上支持所有的编程语言。 diff --git a/cases/ci/demo/drone/.drone.yml b/cases/ci/demo/drone/.drone.yml new file mode 100644 index 0000000..6c599cb --- /dev/null +++ b/cases/ci/demo/drone/.drone.yml @@ -0,0 +1,16 @@ +workspace: + base: /srv/drone-demo + path: . + +pipeline: + build: + image: golang:alpine + # pull: true + environment: + - KEY=VALUE + secrets: [key1, key2] + commands: + - echo $$KEY + - pwd + - ls + - CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app . diff --git a/cases/ci/demo/drone/app.go b/cases/ci/demo/drone/app.go new file mode 100644 index 0000000..0141105 --- /dev/null +++ b/cases/ci/demo/drone/app.go @@ -0,0 +1,7 @@ +package main + +import "fmt" + +func main(){ + fmt.Printf("Hello World!"); +} diff --git a/cases/ci/demo/drone/docker-compose.yml b/cases/ci/demo/drone/docker-compose.yml new file mode 100644 index 0000000..c1e4439 --- /dev/null +++ b/cases/ci/demo/drone/docker-compose.yml @@ -0,0 +1,35 @@ +version: '3' +services: + + drone-server: + image: drone/drone:0.8-alpine + ports: + - 443:443 + # - "${PRO_PUBLIC_IP}:8000:8000" + volumes: + - drone-data:/var/lib/drone/:rw + # - ${SSL_PATH}:/etc/certs + restart: always + environment: + - DRONE_SECRET=drone + - DRONE_OPEN=false + - DRONE_ADMIN=GITHUB_SERNAME + - DRONE_HOST=https://drone.yeasy.com + - DRONE_GITHUB=true + - DRONE_GITHUB_CLIENT=${DRONE_GITHUB_CLIENT_PRO} + - DRONE_GITHUB_SECRET=${DRONE_GITHUB_SECRET_PRO} + + drone-agent: + image: drone/agent:0.8-alpine + restart: always + depends_on: + - drone-server + volumes: + - /var/run/docker.sock:/var/run/docker.sock:rw + environment: + - DRONE_SECRET=drone + - DRONE_SERVER=drone-server:9000 + dns: 114.114.114.114 + +volumes: + drone-data: diff --git a/cases/ci/drone.md b/cases/ci/drone.md new file mode 100644 index 0000000..6b469bf --- /dev/null +++ b/cases/ci/drone.md @@ -0,0 +1,183 @@ +## Drone + +基于 `Docker` 的 `CI/CD` 工具 `Drone` 所有编译、测试的流程都在 `Docker` 容器中进行。 + +开发者只需在项目中包含 `.drone.yml` 文件,将代码推送到 git 仓库,`Drone` 就能够自动化的进行编译、测试、发布。 + +本小节以 `GitHub` + `Drone` 来演示 `Drone` 的工作流程。当然在实际开发过程中,你的代码也许不在 GitHub 托管,那么你可以尝试使用 `Gogs` + `Drone` 来进行 `CI/CD`。 + +### 要求 + +* 拥有公网 IP、域名 (如果你不满足要求,可以尝试在本地使用 Gogs + Drone) + +* 域名 SSL 证书 (目前国内有很多云服务商提供免费证书) + +* 熟悉 `Docker` 以及 `Docker Compose` + +* 熟悉 `Git` 基本命令 + +* 对 `CI/CD` 有一定了解 + +### 新建 GitHub 应用 + +登录 GitHub,在 https://github.com/settings/applications/new 新建一个应用。 + +![](../.image/drone-github.png) + +接下来点击这个应用详情,记录 `Client ID` 和 `Client Secret`,之后配置 Drone 会用到。 + +### 配置 Drone + +我们通过使用 `Docker Compose` 来启动 `Drone`,编写 `docker-compose.yml` 文件。 + +```yaml +version: '3' +services: + + drone-server: + image: drone/drone:0.8-alpine + ports: + - 443:443 + # - "${PRO_PUBLIC_IP}:8000:8000" + volumes: + - drone-data:/var/lib/drone/:rw + - ${SSL_PATH}:/etc/certs:rw + restart: always + environment: + - DRONE_SECRET=drone + - DRONE_OPEN=false + - DRONE_ADMIN=${GITHUB_SERNAME} + - DRONE_HOST=${DRONE_HOST} + - DRONE_GITHUB=true + - DRONE_GITHUB_CLIENT=${DRONE_GITHUB_CLIENT} + - DRONE_GITHUB_SECRET=${DRONE_GITHUB_SECRET} + - DRONE_SERVER_CERT=/etc/certs/drone.domain.com.crt + - DRONE_SERVER_KEY=/etc/certs/drone.domain.com.key + + drone-agent: + image: drone/agent:0.8-alpine + restart: always + depends_on: + - drone-server + volumes: + - /var/run/docker.sock:/var/run/docker.sock:rw + environment: + - DRONE_SECRET=drone + - DRONE_SERVER=drone-server:9000 + dns: 114.114.114.114 + +volumes: + drone-data: +``` + +替换 `${SSL_PATH}` 为你网站的 SSL 证书路径。 + +替换 `${GITHUB_SERNAME}` 为你部署 GitHub 的用户名,该用户将成为 Drone 的管理员。 + +替换 `${DRONE_HOST}` 为你部署 Drone 的域名。 + +替换 `${DRONE_GITHUB_CLIENT}` 为你 GitHub 应用的 `CLIENT` + +替换 `${DRONE_GITHUB_SECRET}` 为你 GitHub 应用的 `SECRET` + +*注意:* 如果你的服务器占用了 `443` 端口,请配置 Nginx 代理,这里不再赘述。 + +#### 启动 Drone + +```bash +$ docker-compose up -d +``` + +### Drone 关联项目 + +在 Github 新建一个名为 `drone-demo` 的仓库。 + +打开我们已经部署好的 Drone 网站,使用 GitHub 登录,在界面中关联刚刚新建的 `drone-demo` 仓库。 + +### 编写项目源代码 + +在本机初始化一个 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!"); +} +``` + +编写 `.drone.yml` 文件 + +```yaml +workspace: + base: /srv/drone-demo + path: . + +pipeline: + build: + image: golang:alpine + # pull: true + environment: + - KEY=VALUE + secrets: [key1, key2] + commands: + - echo $$KEY + - pwd + - ls + - CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app . + - ./app +``` + +`workspace` 指明 git 源代码克隆的目标路径,本例中 git 源代码将被克隆到 golang 容器中的 `/srv/drone-demo` 目录中。 + +`pipeline` 指明构建所需的 Docker 镜像,环境变量,编译指令等。 + +现在目录结构如下 + +```bash +. +├── .drone.yml +└── app.go +``` + +### 推送项目源代码到 GitHub + +```bash +$ git add . + +$ git commit -m "test drone ci" + +$ git push origin master +``` + +### 查看项目构建过程及结果 + +打开我们部署好的 `Drone` 网站,即可看到构建结果。 + +![](../.image/drone-build.png) + +当然我们也可以把构建结果上传到 GitHub,Docker Registry,云服务商提供的对象存储,或者生产环境中。 + +本书 GitBook 也使用 Drone 进行 CI/CD,具体配置信息请查看本书根目录 [`.drone.yml`](https://github.com/yeasy/docker_practice/blob/master/.drone.yml) 文件。 + +## 参考链接 + +* [Drone Github](https://github.com/drone/drone) + +* [Drone 文档](http://docs.drone.io/) diff --git a/revision.md b/revision.md index cdc8fa1..902304f 100644 --- a/revision.md +++ b/revision.md @@ -8,7 +8,11 @@ * 更新 `CoreOS` 章节 -* 0.9-rc1: 2017-11-30 + * 增加 Docker 中文资源链接 + + * 增加介绍基于 Docker 的 CI/CD 工具 Drone + +* 0.9-rc1: 2017-11-29 * 根据最新版本(v17.09)修订内容