Book Image

Mastering Go - Second Edition

By : Mihalis Tsoukalos
Book Image

Mastering Go - Second Edition

By: Mihalis Tsoukalos

Overview of this book

Often referred to (incorrectly) as Golang, Go is the high-performance systems language of the future. Mastering Go, Second Edition helps you become a productive expert Go programmer, building and improving on the groundbreaking first edition. Mastering Go, Second Edition shows how to put Go to work on real production systems. For programmers who already know the Go language basics, this book provides examples, patterns, and clear explanations to help you deeply understand Go’s capabilities and apply them in your programming work. The book covers the nuances of Go, with in-depth guides on types and structures, packages, concurrency, network programming, compiler design, optimization, and more. Each chapter ends with exercises and resources to fully embed your new knowledge. This second edition includes a completely new chapter on machine learning in Go, guiding you from the foundation statistics techniques through simple regression and clustering to classification, neural networks, and anomaly detection. Other chapters are expanded to cover using Go with Docker and Kubernetes, Git, WebAssembly, JSON, and more. If you take the Go programming language seriously, the second edition of this book is an essential guide on expert techniques.
Table of Contents (20 chapters)
Title Page

Using Docker

In the last section of this chapter, you will learn how to use a Docker image in order to compile and execute your Go code inside the Docker image.

As you might already know, everything in Docker begins with a Docker image; you can either build your own Docker image from scratch or begin with an existing one. For the purposes of this section, the base Docker image will be downloaded from Docker Hub and we will continue with building the Go version of the Hello World! program inside that Docker image.

The contents of the Dockerfile that will be used are as follows:

FROM golang:alpine 
 
RUN mkdir /files 
COPY hw.go /files 
WORKDIR /files 
 
RUN go build -o /files/hw hw.go 
ENTRYPOINT ["/files/hw"] 

The first line defines the Docker image that will be used. The remaining three commands create a new directory in the Docker image, copy a file (hw.go) from the current user directory into the Docker image, and change the current working directory of the Docker image, respectively. The last two commands create a binary executable from the Go source file and specify the path of the binary file that will be executed when you run that Docker image.

So, how do you use that Dockerfile? Provided that a file named hw.go exists in the current working directory, you can build a new Docker image as follows:

$ docker build -t go_hw:v1 .
Sending build context to Docker daemon  2.237MB
Step 1/6 : FROM golang:alpine
alpine: Pulling from library/golang
cd784148e348: Pull complete
7e273b0dfc44: Pull complete
952c3806fd1a: Pull complete
ee1f873f86f9: Pull complete
7172cd197d12: Pull complete
Digest: sha256:198cb8c94b9ee6941ce6d58f29aadb855f64600918ce602cdeacb018ad77d647
Status: Downloaded newer image for golang:alpine
 ---> f56365ec0638
Step 2/6 : RUN mkdir /files
 ---> Running in 18fa7784d82c
Removing intermediate container 18fa7784d82c
 ---> 9360e95d7cb4
Step 3/6 : COPY hw.go /files
 ---> 680517bc4aa3
Step 4/6 : WORKDIR /files
 ---> Running in f3f678fcc38d
Removing intermediate container f3f678fcc38d
 ---> 640117aea82f
Step 5/6 : RUN go build -o /files/hw hw.go
 ---> Running in 271cae1fa7f9
Removing intermediate container 271cae1fa7f9
 ---> dc7852b6aeeb
Step 6/6 : ENTRYPOINT ["/files/hw"]
 ---> Running in cdadf286f025
Removing intermediate container cdadf286f025
 ---> 9bec016712c4
Successfully built 9bec016712c4
Successfully tagged go_hw:v1
  

The name of the newly created Docker image is go_hw:v1.

If the golang:alpine Docker image is already present on your computer, the output of the preceding command will be as follows:

$ docker build -t go_hw:v1 .
Sending build context to Docker daemon  2.237MB
Step 1/6 : FROM golang:alpine
 ---> f56365ec0638
Step 2/6 : RUN mkdir /files
 ---> Running in 982e6883bb13
Removing intermediate container 982e6883bb13
 ---> 0632577d852c
Step 3/6 : COPY hw.go /files
 ---> 68a0feb2e7dc
Step 4/6 : WORKDIR /files
 ---> Running in d7d4d0c846c2
Removing intermediate container d7d4d0c846c2
 ---> 6597a7cb3882
Step 5/6 : RUN go build -o /files/hw hw.go
 ---> Running in 324400d532e0
Removing intermediate container 324400d532e0
 ---> 5496dd3d09d1
Step 6/6 : ENTRYPOINT ["/files/hw"]
 ---> Running in bbd24840d6d4
    Removing intermediate container bbd24840d6d4
 ---> 5a0d2473aa96
    Successfully built 5a0d2473aa96
    Successfully tagged go_hw:v1
  

You can verify that the go_hw:v1 Docker image exists on your machine as follows:

$ docker images
REPOSITORY    TAG       IMAGE ID      CREATED              SIZE
go_hw         v1        9bec016712c4  About a minute ago   312MB
golang        alpine    f56365ec0638  11 days ago          310MB
  

The contents of the hw.go file are as follows:

package main 
 
import ( 
    "fmt" 
) 
 
func main() { 
    fmt.Println("Hello World!") 
} 

You can use a Docker image that is on your local computer as follows:

$ docker run go_hw:v1
Hello World!
  

There are other more complex ways to execute a Docker image, but for such a naive Docker image, this is the simplest way to use it.

If you want, you can store (push) a Docker image at a Docker registry on the internet in order to be able to retrieve it (pull) from there afterward.

Docker Hub can be such a place, provided that you have a Docker Hub account, which is easy to create and free. So, after creating a Docker Hub account, you should execute the following commands on your UNIX machine and push that image to Docker Hub:

$ docker login
Authenticating with existing credentials...
Login Succeeded
$ docker tag go_hw:v1 "mactsouk/go_hw:v1"
$ docker push "mactsouk/go_hw:v1"
The push refers to repository [docker.io/mactsouk/go_hw]
bdb6946938e3: Pushed
99e21c42e35d: Pushed
0257968d27b2: Pushed
e121936484eb: Pushed
61b145086eb8: Pushed
789935042c6f: Pushed
b14874cfef59: Pushed
7bff100f35cb: Pushed
v1: digest: 
sha256:c179d5d48a51b74b0883e582d53bf861c6884743eb51d9b77855949b5d91dd
e1 size: 1988

The first command is needed to log in to Docker Hub and should be executed only once. The docker tag command is needed for specifying the name that a local image will have on Docker Hub and should be executed before the docker push command. The last command sends the desired Docker image to Docker Hub, hence the rich output it generates. If you make your Docker image public, anyone will be able to pull it and use it.

You can delete one or more Docker images from your local UNIX machine in many ways. One of them is by using the IMAGE ID of a Docker image:

$ docker rmi 5a0d2473aa96 f56365ec0638
Untagged: go_hw:v1
Deleted: 
sha256:5a0d2473aa96bcdafbef92751a0e1c1bf146848966c8c971f462eb1eb242d2
a6
Deleted:
sha256:5496dd3d09d13c63bf7a9ac52b90bb812690cdfd33cfc3340509f9bfe6215c
48
Deleted:
sha256:598c4e474b123eccb84f41620d2568665b88a8f176a21342030917576b9d82
a8
Deleted:
sha256:6597a7cb3882b73855d12111787bd956a9ec3abb11d9915d32f2bba4d0e92e
c6
Deleted:
sha256:68a0feb2e7dc5a139eaa7ca04e54c20e34b7d06df30bcd4934ad6511361f2c
b8
Deleted:
sha256:c04452ea9f45d85a999bdc54b55ca75b6b196320c021d777ec1f766d115aa5
14
Deleted:
sha256:0632577d852c4f9b66c0eff2481ba06c49437e447761d655073eb034fa0ac3
33
Deleted:
sha256:52efd0fa2950c8f3c3e2e44fbc4eb076c92c0f85fff46a07e060f5974c1007
a9
Untagged: golang:alpine Untagged:
golang@sha256:198cb8c94b9ee6941ce6d58f29aadb855f64600918ce602cdeacb01
8ad77d647
Deleted:
sha256:f56365ec0638b16b752af4bf17e6098f2fda027f8a71886d6849342266cc3a
b7
Deleted:
sha256:d6a4b196ed79e7ff124b547431f77e92dce9650037e76da294b3b3aded709b
dd
Deleted:
sha256:f509ec77b9b2390c745afd76cd8dd86977c86e9ff377d5663b42b664357c35
22
Deleted:
sha256:1ee98fa99e925362ef980e651c5a685ad04cef41dd80df9be59f158cf9e529
51
Deleted:
sha256:78c8e55f8cb4c661582af874153f88c2587a034ee32d21cb57ac1fef51c610
9e
Deleted:
sha256:7bff100f35cb359a368537bb07829b055fe8e0b1cb01085a3a628ae9c187c7
b8
Docker is a huge and really important topic that we will revisit in several chapters of this book.