docker support for inner loop
Inner Loop vs Outer Loop
https://opensource.com/article/21/6/open-source-developer-tools
inner loop是开发者的最常做的事情, 编码 运行 验证 调试
outer loop是我们经常提及的CI/CD, 从代码提交入库, 到CI进行测试,测试通过后构建,构建成功后, 进入CD, 或者发布版本, 或者在发布后部署到产品环境中。
The industry is still working on perfecting how a developer's time is spent. We can divide a developer's major tasks into two different "loops":
- Inner loop: These are the most common tasks developers do, the ones that fully utilize their skillsets: code, run, validate, and debug. This is the classical developer loop.
- Outer loop: This is where a developer's code goes through continuous integration and continuous delivery (CI/CD) and gets deployed to production. On Gitlab and similar platforms, a developer's pull request (PR) gets merged to the main branch, CI/CD kicks in and creates the build, runs the necessary tests, and deploys to the specified environments. This is a DevOps loop.
outerloop.png
docker practice
https://docs.docker.com/ci-cd/best-practices/
docker一般被认为是部署工具
即, 在开发者开发完毕代码, 提交到版本库中, 自动进行测试 构建 部署的过程。
但是这并不符合 DEVOPS文化, 其要求开发者的开发环境 和 部署环境要求一致。
所以docker 就提供了 这种功能, 在本地开发者可以通过构造与部署相同的容器环境,在此环境中进行本地化的构建和测试。
Inner and outer loops
To get started, one of the most important things when working with Docker and any CI/CD is to understand when you need to test with the CI, and when you can do this locally. At Docker, we think about how developers work in terms of their inner loop (code, build, run, test) and their outer loop (push changes, CI build, CI test, deployment).
Before you think about optimizing your CI/CD, it is important to think about your inner loop and how it relates to the outer loop (the CI). We know that most users don’t prefer ‘debugging through the CI’. Therefore, it is better if your inner loop and outer loop are as similar as possible. We recommend that you run unit tests as part of your
docker build
command by adding a target for them in your Dockerfile. This way, as you are making changes and rebuilding locally, you can run the same unit tests you would run in the CI on your local machine using a simple command.The blog post Go development with Docker is a great example of how you can use tests in your Docker project and re-use them in the CI. This also creates a shorter feedback loop on issues and reduces the amount of pulls and builds your CI needs to do.
docker技术点
https://docs.docker.com/develop/develop-images/multistage-build/
在dockerfile中支持多target定义。
# syntax=docker/dockerfile:1 FROM golang:1.16 AS builder WORKDIR /go/src/github.com/alexellis/href-counter/ RUN go get -d -v golang.org/x/net/html COPY app.go ./ RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app . FROM alpine:latest RUN apk --no-cache add ca-certificates WORKDIR /root/ COPY --from=builder /go/src/github.com/alexellis/href-counter/app ./ CMD ["./app"]
运行只运行其中一个target
docker build -t alexellis2/href-counter:latest .
样例
https://www.docker.com/blog/containerize-your-go-developer-environment-part-1/
https://www.docker.com/blog/containerize-your-go-developer-environment-part-2/
在dockerfile中定义 unittest test
# 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 / ...
在makefile中定义unittest target, 对应docker build unittest
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
K8S for INNER LOOP
https://medium.com/geekculture/developing-on-kubernetes-the-inner-outer-loop-6957f9597f7a