Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to use Docker Image to build Go Application

2025-03-17 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/01 Report--

This article mainly introduces the relevant knowledge of how to use Docker image to build Go application, the content is detailed and easy to understand, the operation is simple and quick, and has certain reference value. I believe you will gain something after reading this article on how to use Docker image to build Go application. Let's take a look at it.

Practice background

I worked overtime day and night to develop the simplest Go Hello world app. Although I just ran to print and quit, my boss also asked me to launch the only app I could write.

The project structure is as follows:

. ├── go.mod └── hello.go

The hello.go code is as follows:

Package mainfunc main () {println ("hello world!")}

Moreover, the boss asked to deploy with docker, which makes us keep up with the trend and be a little taller.

The first attempt

After visiting some of my martial arts friends, I found that it would be nice to throw the whole process into docker to compile it. After thinking about it, I got the following Dockerfile:

FROM golang:alpineWORKDIR / buildCOPY hello.go .Run go build-o hello hello.goCMD [". / hello"]

Build an image:

$docker build-t hello:v1.

Done. Let's take a closer look.

$docker run-it-- rm hello:v1 ls-l / buildtotal 1260-rwxr-xr-x 1 root root 1281547 Mar 6 15:54 hello-rw-r--r-- 1 root root 55 Mar 6 14:59 hello.go

Boy, the code I finally wrote is also in it. It seems that the code can't be written badly, otherwise the operation and maintenance girl will sneer at me and laugh at me.

Let's take a look at how big the mirror image is. It is said that pulling the mirror image will be slower when it is bigger.

$docker images | grep hellohello v1 2783ee221014 44 minutes ago 314MB

Wow, there is 314MB. Does docker build suddenly become Java? Not everything is the bigger the better.

Let's see why it's so big!

Look, we had already 300+MB before we ran the first instruction (WORKDIR). It's a little fierce!

Anyway, let's run and have a look.

$docker run-it-rm hello:v1hello world!

No problem, at least you can work.

The second attempt

After a period of smoking and drinking, coupled with the guidance of friends, we found that the basic image we used was too big.

$docker images | grep golanggolang alpine d026981a7165 2 days ago 313MB

And my friend told me that I could compile the code first, and then copy it into it, so I didn't have to use that huge basic image, but it was easy to say, I did some good work, and in the end, Dockerfile looks like this:

FROM alpineWORKDIR / buildCOPY hello .CMD [". / hello"]

Try to run.

$docker build-t hello:v2.... = > ERROR [3gamma 3] COPY hello. 0.0s-> [3amp 3] COPY hello.:-failed to compute cache key: "/ hello" not found: not found

No, hello can't be found. I forgot to compile hello.go first. Come again.

$go build-o hello hello.go

Run docker build-t hello:v2 again, no problem, take two steps to try.

$docker run-it-- rm hello:v2standard_init_linux.go:228: exec user process caused: exec format error

Failure! All right, the format is wrong. It turns out that our development machine is not linux. Come again.

$GOOS=linux go build-o hello hello.go

The re-docker build is finally done. Run quickly.

$docker run-it-rm hello:v2hello world!

No problem. Let's take a look at the content and size.

$docker run-it-- rm hello:v2 ls-l / buildtotal 1252-rwxr-xr-x 1 root root 1281587 Mar 6 16:18 hello

There is only the executable file hello, so I don't have to worry about other people's disdain for my code anymore.

$docker images | grep hellohello v2 0dd53f016c93 53 seconds ago 6.61MBhello v1 ac0e37173b85 25 minutes ago 314MB

Wow, 6.61MB, absolutely!

Look, we run the first instruction (WORKDIR) before only 5.3MB, happy ah!

The third attempt

After a show-off, some people despise me and say what kind of multi-stage construction is popular now, so what's wrong with the second way? After careful consideration, we found that we need to be able to build a docker image from Go code, which is divided into three steps:

Native compilation of Go code, if it involves cgo cross-platform compilation will be more troublesome

Build a docker image with compiled executable files

Write a shell script or makefile so that these steps can be obtained with a single command

Multi-stage build is to put it all into a Dockerfile, without source code leakage, no need to script cross-platform compilation, and get the smallest image.

Love learning, the pursuit of perfection, I finally wrote the following Dockerfile, more line is fat, less line is thin:

FROM golang:alpine AS builderWORKDIR / buildADD go.mod .COPY. .run go build-o hello hello.goFROM alpineWORKDIR / buildCOPY-- from=builder / build/hello / build/helloCMD [". / hello"]

The first FROM starts by building an builder image to compile the executable file hello, and the second From starts by copy the executable hello from the first image and uses the smallest possible base image alpine to ensure that the final image is as small as possible. as for why not use a smaller scratch, it is because scratch really does not have anything, there is no chance to take a look at it if there is a problem, and alpine is 5MB. It will not have much impact on our service.

Let's run and check it out:

$docker run-it-rm hello:v3hello world!

No problem, as expected! See what the size is:

$docker images | grep hellohello v3 f51e1116be11 8 hours ago 6.61MBhello v2 0dd53f016c93 8 hours ago 6.61MBhello v1 ac0e37173b85 8 hours ago 314MB

It is exactly the same size as the image built by the second method. And look at the contents of the mirror image:

$docker run-it-- rm hello:v3 ls-l / buildtotal 1252-rwxr-xr-x 1 root root 1281547 Mar 6 16:32 hello

There is only one executable hello file, perfect!

It is basically the same as the second final image, but we have simplified the process. All we need is a Dockerfile and a command. There is no need for me to deal with the arcane shell and makefile.

Shenggong practice

At this point, the team felt perfect and gave me likes one after another! However, for those who both pursue perfection and like to be lazy (fishing), I think that every time I am asked to write such a Dockerfile which is fat by one line and thin by one line, I still find it quite annoying, so I wrote a tool without telling my boss, and I will show it.

# install and write Dockerfile$ goctl docker-go hello.go with one click of $GOPROXY= https://goproxy.cn/,direct go install github.com/zeromicro/go-zero/tools/goctl@latest#

Got it! Look at the generated Dockerfile, ha.

FROM golang:alpine AS builderLABEL stage=gobuilderENV CGO_ENABLED 0ENV GOOS linuxENV GOPROXY https://goproxy.cn,directWORKDIR / buildADD go.mod .ADD go.sum .RUN go mod downloadCOPY. Run go build-ldflags= "- s-w"-o / app/hello. / hello.goFROM alpineRUN apk update-- no-cache & & apk add-- no-cache ca-certificates tzdataENV TZ Asia/ShanghaiWORKDIR / appCOPY-- from=builder / app/hello / app/helloCMD [". / hello"]

Here are a few points to learn:

Cgo is disabled by default

GOPROXY enabled

The debugging information-ldflags= "- s-w" is removed to reduce the image size.

Ca-certificates is installed so that it is no problem to use TLS certificates

The local time zone is automatically set so that what we see in the log is Beijing time.

Let's take a look at the size of the image built with this automatically generated Dockerfile:

$docker images | grep hellohello v4 a7c3baed2706 4 seconds ago 7.97MBhello v3 f51e1116be11 8 hours ago 6.61MBhello v2 0dd53f016c93 8 hours ago 6.61MBhello v1 ac0e37173b85 9 hours ago 314MB

Slightly larger, this is because we installed ca-certificates and tzdata. Verify:

Let's see what's in the mirror image:

$docker run-it-- rm hello:v4 ls-l / apptotal 832-rwxr-xr-x 1 root root 851968 Mar 7 08:36 hello

There are also only hello executable files, and the file size has been reduced from the original 1281KB to 851KB. Run and have a look:

$docker run-it-rm hello:v4hello world! This is the end of the article on "how to use Docker images to build Go applications". Thank you for reading! I believe you all have a certain understanding of "how to use Docker images to build Go applications". If you want to learn more, you are welcome to follow the industry information channel.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report