Hi Big Ben go mod

The official endorsement of the Go Mod saved my code cleanliness bug!Copy the code

The environment

  • Go v1.12
  • Docker ce 18.09.0
  • gitlab ce latest

godep

Dependency management may not be that important to you if you’re writing go alone, or if you’re just writing a gadget for fun.

However, in commercial engineering projects, where multiple people cooperate, the dependency management of GO is particularly important. There are not many options before, and most of the implementation methods provided by the community are similar, such as GODEp I used before. So the project will have a vendor folder to store external dependencies like this:

This way, every time an external dependency is updated, someone else has to pull down a pile of…

go mod

Let’s look at using the official Module to manage dependent engineering structures:

Is not, relaxed and clinking, the project also whole thin body!

Let’s briefly talk about go mod help, as for the steps to start go mod, other web articles are a lot of, I will not copy. After all, this article is about go engineering CI/CD.

In the current go v1.12 version, the command go mod help results in the following:

The commands are:

	download    download modules to local cache
	edit        edit go.mod from tools or scripts
	graph       print module requirement graph
	init        initialize new module in current directory
	tidy        add missing and remove unused modules
	vendor      make vendored copy of dependencies
	verify      verify dependencies have expected content
	why         explain why packages or modules are needed
Copy the code

The download command is needed for CI/CD.

dockerfile

Here is my project dockerfile:

FROM golang:1.12 as build

ENV GOPROXY https://go.likeli.top
ENV GO111MODULE on

WORKDIR /go/cache

ADD go.mod .
ADD go.sum .
RUN go mod download

WORKDIR /go/release

ADD.
RUN GOOS=linux CGO_ENABLED=0 go build -ldflags="-s -w" -installsuffix cgo -o app main.go

FROM scratch as prod

COPY --from=build /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
COPY --from=build /go/release/app /
COPY --from=build /go/release/conf.yaml /

CMD ["/app"]
Copy the code

My project has some external dependencies, which have been adjusted and compiled in the local development environment. Two files, go.mod and go.sum, have been generated in the local development environment

In the first step of dockerfile, start module mode first, and configure proxy, because some package services outside the wall can not be downloaded back without ladder, the proxy domain name here is my own, if necessary, can also use.

When the RUN Go mod Download directive is executed, it builds a cache that contains all of the dependencies for the item. If go.mod and go.sum are not changed in the code submitted later, the cache will be directly used to speed up the build and there is no need to download the dependencies from the Internet repeatedly. If the two files change, the cache layer is rebuilt.

The effects of building with caching:

The acceleration effect is significant.

Reducing the volume

Go build command use-ldflags="-s -w"

Command_Line specifies the meaning of the -s -w parameter.

  • -s: omits the symbol table and debugging information
  • -w: omitting DWARF symbol table

Looks good 🙂

Using Scratch Images

After building the application with Golang :1.12 development image, use Scratch to wrap and generate binaries.

For minimum base images, Docker has these categories:

  • Scratch: Empty base image, minimum base image
  • Busybox: Comes with some common tools for easy debugging, and some extensions to busybox:glibc
  • Alpine: Another commonly used base image, with package management features, easy to download other dependent packages

Mirror image slimming final effect

Well, let’s see what the final application looks like:

The size of the built image is 16.4MB

CI/CD

Gitlab-ci.yml: Gitlab-ci.yml:

before_script:
- if [[ $(whereis docker-compose | wc -l) -eq 0 ]]; Then the curl - L "https://github.com/docker/compose/releases/download/1.23.2/docker-compose-$(uname - s) - $(uname -m)" - o /usr/local/bin/docker-compose && chmod +x /usr/local/bin/docker-compose; fi # ****************************************************************************************************** # * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * test environment configuration * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * # * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *deploy-test-tour:
  stage: deploy
  tags:
    - build
  only:
    - The release/v2.0
  script:
    - export PRODUCTION=false
    - docker-compose stop
    - docker-compose up -d --build


# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * the production environment configuration * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

deploy-prod-tour:
  stage: deploy
  tags:
    - release
  only:
    - master
  script:
    - export PRODUCTION=true
    - docker-compose stop
    - docker-compose up -d --build
Copy the code

I use Docker-compose for container control, so I added this step in the before_script process for full automation of the new machine.

I did a little engineering on this project, so it was a little more formal, and there were two environments, test and production. Bind to different branches.

The following three lines are executed:

export PRODUCTION=false
docker-compose stop
docker-compose up -d --build
Copy the code
  • exportControl the temporary environment variables so that you can publish different environments.
  • docker-compose stopStop old containers
  • docker-compose up -d --buildOrchestrating a new container and starting it uses the previous cache layering image, so the speed is uneven except for the first build.

See a screenshot of the actual release:

The total time is 1 minute 22 seconds

Build with cache, total: 33 seconds