Docker分享-CI/CD之路(2)

简介: Docker分享-CI/CD之路(2)

Docker分享-CI/CD(2)

第一篇内容,分享了大神介绍如何容器化项目的经历,我真的看着么久,唯一看到大神介绍多平台交叉编译的。因为绝大多数的docker项目都只提供linux产品。当然只会容器化我们的项目还远远不够,CI/CD的目的能让团队协同工作,持续集成持续部署。保持开发环境一直是另一个大问题。

添加额外的依赖

上个教程,我们基本没有使用第三方依赖,但是实际开发中,为了更加专注于开发我们自己的功能,可能会有很多3PP的辅助。大神也用了个简单的例子

package main
import (
   "fmt"
   "os"
   "strings"
   "github.com/pkg/errors"
)
func echo(args []string) error {
   if len(args) < 2 {
       return errors.New("no message to echo")
   }
   _, err := fmt.Println(strings.Join(args[1:], " "))
   return err
}
func main() {
   if err := echo(os.Args); err != nil {
       fmt.Fprintf(os.Stderr, "%+v\n", err)
       os.Exit(1)
   }
}

简单的echo功能,使用go modules做包管理,跑一下

go mod init
go mod tidy

有了依赖之后,明显的效率低下并且减慢了速度。我们可以通过在Dockerfile中单独下载依赖项目来解决这个问题。

FROM --platform=${BUILDPLATFORM} golang:1.14.3-alpine AS build
WORKDIR /src
ENV CGO_ENABLED=0
COPY go.* .
RUN go mod download
COPY . .
ARG TARGETOS
ARG TARGETARCH
RUN GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build -o /out/example .
FROM scratch AS bin-unix
COPY --from=build /out/example /
...

与之前的一版dockerfile对比,这一版加了两行内容

COPY go.* .

RUN go mod download

大神说先添加所有go.*的文件,然后下载依赖这样会让Docker缓存下载的modules,dockerfile会少重跑一些内容。

将下载依赖和构建分开是相当大的改进,但是每次构建都要从头开始编译,对于小型项目这没什么,但是随着项目越来越大,我们就应该考虑Go的编译器缓存。

再更新一次dockerfile看看怎么改

# syntax = docker/dockerfile:1-experimental
FROM --platform=${BUILDPLATFORM} golang:1.14.3-alpine AS build
ARG TARGETOS
ARG TARGETARCH
WORKDIR /src
ENV CGO_ENABLED=0
COPY go.* .
RUN go mod download
COPY . .
RUN --mount=type=cache,target=/root/.cache/go-build \
GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build -o /out/example .
FROM scratch AS bin-unix
COPY --from=build /out/example /
...

大神在dockerfile的顶部加了一个语句,选择了试验性的docker前端,外加--mount。这意味着每次运行go build命令的时候,容器都会将缓存挂在到Go的编译器缓存文件夹中。大神说无缓存构建该例子需要11秒,但是使用缓存的话,用了不到2秒,不可思议。

加入单元测试

我发誓我之后如果做个人项目一定认真写单元测试,大神也说了,不几乎我读过的每个文档都提到了单元测试的重要性。贴上测试代码:

package main
import (
    "testing"
    "github.com/stretchr/testify/require"
)
func TestEcho(t *testing.T) {
    // Test happy path
    err := echo([]string{"bin-name", "hello", "world!"})
    require.NoError(t, err)
}
func TestEchoErrorNoArgs(t *testing.T) {
    // Test empty arguments
    err := echo([]string{})
    require.Error(t, err)
}

CI测试来了

这里是我认为应该学习的地方,大神在dockerfile里的构建阶段,加入了单元测试

# syntax = docker/dockerfile:1-experimental
FROM --platform=${BUILDPLATFORM} golang:1.14.3-alpine AS base
WORKDIR /src
ENV CGO_ENABLED=0
COPY go.* .
RUN go mod download
COPY . .
FROM base AS build
ARG TARGETOS
ARG TARGETARCH
RUN --mount=type=cache,target=/root/.cache/go-build \
GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build -o /out/example .
FROM base AS unit-test
RUN --mount=type=cache,target=/root/.cache/go-build \
go test -v .
FROM scratch AS bin-unix
COPY --from=build /out/example /
...

Go的测试使用了与构建相同的缓存,也是为了能在测试的时候更快。

更新makefile

all: bin/example
test: unit-test
PLATFORM=local
.PHONY: bin/example
bin/example:
    @docker build . --target bin \
    --output bin/ \
    --platform ${PLATFORM}
.PHONY: unit-test
unit-test:
    @docker build . --target unit-test

大神的docker CI三件套,第二篇中讲了如何有效的添加go的依赖,缓存用于加快构建速度,以及对容器化Go开发环境中添加单元测试。

下一篇内容将会将如何添加linter,设置Github Actions CI以及一些额外的构建优化。


相关文章
|
1月前
|
jenkins 测试技术 持续交付
Docker最佳实践:构建高效的CI/CD流水线
【10月更文挑战第17天】在现代软件开发实践中,持续集成(Continuous Integration, CI)和持续部署(Continuous Deployment, CD)已成为提高开发效率和软件质量的重要手段。Docker作为一种容器技术,为构建一致且隔离的开发环境提供了强有力的支撑。本文将探讨如何利用Docker来优化CI/CD流程,包括构建环境的标准化、镜像管理以及与CI/CD工具(如Jenkins、GitLab CI)的集成。
52 5
|
3月前
|
jenkins Shell 持续交付
自动化部署:使用Jenkins和Docker实现CI/CD
【8月更文挑战第31天】 本文旨在引导读者了解如何通过Jenkins和Docker来实现持续集成和持续部署(CI/CD),从而优化开发流程,提升工作效率。文章将详细介绍配置Jenkins服务器、创建Docker镜像以及设置自动化构建和部署的步骤。通过实际操作案例,我们将展示如何将代码变更快速部署到测试或生产环境,确保软件质量与发布速度的双重保障。
|
3月前
|
测试技术 持续交付 开发者
使用Docker构建CI/CD流程:从理论到实践
【8月更文挑战第2天】使用Docker构建CI/CD流程,可以显著提高软件开发的效率和质量。通过容器化技术,开发者可以确保环境的一致性,快速部署和测试应用,并减少人为错误。结合合适的CI/CD工具和最佳实践,可以进一步加速软件交付过程,提高用户满意度。希望本文能为开发者在构建基于Docker的CI/CD流程时提供有价值的参考。
|
4月前
|
Kubernetes Cloud Native 持续交付
云原生架构的核心组成部分通常包括容器化(如Docker)、容器编排(如Kubernetes)、微服务架构、服务网格、持续集成/持续部署(CI/CD)、自动化运维(如Prometheus监控和Grafana可视化)等。
云原生架构的核心组成部分通常包括容器化(如Docker)、容器编排(如Kubernetes)、微服务架构、服务网格、持续集成/持续部署(CI/CD)、自动化运维(如Prometheus监控和Grafana可视化)等。
|
6月前
|
存储 测试技术 持续交付
【Docker 专栏】Docker 与 CI/CD 的集成策略
【5月更文挑战第8天】本文探讨了Docker在CI/CD流程中的作用,强调了环境一致性、快速部署和资源隔离等优势。通过在构建、测试和部署阶段集成Docker,可以提升软件开发效率和质量。具体集成策略包括使用Dockerfile构建镜像、整合CI/CD工具如Jenkins和GitLab。集成带来的好处包括提高效率、增强可靠性、加速交付和简化管理。然而,也需应对镜像管理、网络配置和安全等问题。通过案例分析,证明了Docker与CI/CD集成的有效性和必要性。
124 2
【Docker 专栏】Docker 与 CI/CD 的集成策略
|
6月前
|
jenkins Java 持续交付
Jenkins与Docker的自动化CI/CD实战
Jenkins与Docker的自动化CI/CD实战
|
6月前
|
Devops 开发工具 数据安全/隐私保护
Docker Swarm总结+CI/CD Devops、gitlab、sonarqube以及harbor的安装集成配置(3/5)
Docker Swarm总结+CI/CD Devops、gitlab、sonarqube以及harbor的安装集成配置(3/5)
251 0
|
11天前
|
运维 Cloud Native 虚拟化
一文吃透云原生 Docker 容器,建议收藏!
本文深入解析云原生Docker容器技术,涵盖容器与Docker的概念、优势、架构设计及应用场景等,建议收藏。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
一文吃透云原生 Docker 容器,建议收藏!
|
4天前
|
Kubernetes Linux 开发者
深入探索容器化技术——Docker 的实战应用
深入探索容器化技术——Docker 的实战应用
26 5
|
5天前
|
关系型数据库 MySQL Java
【Docker最新版教程】一文带你快速入门Docker常见用法,实现容器编排和自动化部署上线项目
Docker快速入门到项目部署,MySQL部署+Nginx部署+docker自定义镜像+docker网络+DockerCompose项目实战一文搞定!
下一篇
无影云桌面