Do you want to run your Golang application with docker? Read this post. We will try two methods of running a golang application with docker. You can see which method is more suitable for you.
To run a go app with docker, we need to create a docker container. Then run the container with the necessary resources. But before going to the docker part, of course, we need to have a go app first.
The Go application
This is a simple web server that we are going to use.
package main
import (
"fmt"
"net/http"
"github.com/gorilla/mux"
)
func main() {
r := mux.NewRouter()
r.HandleFunc("/get_city", cityHandler)
fmt.Println("listening..")
http.ListenAndServe(":5005", r)
}
func cityHandler(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(`{"city":["jakarta","bandung","bandar lampung"]}`))
}
To create a docker container, we need a Dockerfile.
Create a file named Dockerfile
in your go application root directory.
As written in the beginning, we will try two methods of running the go app with docker. Now let’s start with method one.
Method 1: Build Go app binary in docker
In this method, we copy our source code to the container. Then fetch vendor libraries and build the application in the docker. We use a multi-staged build to omit the source code in the resulting image. So even though the source code is copied, the resulting image will only contain the application binary. This can significantly reduce the image size.
Below is the Dockerfile for this method.
|
|
The first stage is builder, we use golang:1.15.8-alpine
image as the base image for our container. You can change the Go version if you need to use another version. We name the first stage builder
as you can see on the first line. On line 4, we copy all our source code to the container. If you want to exclude something such as the vendor folder, you can put it in the .dockerignore
file. Then we fetch vendor libraries and build the application on the next line. I use go mod for this example. You may need to modify this if you use another tool other than go mod.
The next stage starts from line 11. We create the container from scratch because we only need the application binary to run the application. So we copy only the binary from the builder stage to the last stage. Entrypoint specifies which application to run when the container is run, which is our Go application.
Use this command to build the image.
docker build -t godocker .
After it is built, you can see it in your image list with the command docker images
or docker image ls
.
To create and run the container using the image, use this command.
docker run -p 5005:5005 --rm godocker
-p 5005:5005
is to publish container port 5005 to host port 5005. This means that by sending a request to the host port, the request will go to our container.
The option --rm
is to remove the container if it is stopped.Now, your go application should already be running in docker. To see it, you can use the command docker ps
or docker container ls
.
That’s it for method 1. Now let’s see method 2.
Methods 2: Copy the binary only
In this method, the binary is built in another environment, such as our local environment. We only copy the Go app binary to docker. But we need to set variables CGO_ENABLED=0
and GOOS=linux
when building the Go app so that it can run on the docker container. You can simplify the command by using a tool like Makefile. Below is our command to build the app.
CGO_ENABLED=0 GOOS=linux go build -o myapp
This is the Dockerfile for this method.
FROM scratch
COPY myapp /
ENTRYPOINT ["/myapp"]
It is similar to the last stage of method 1. The difference is that we copy the binary from the host machine rather than build it in the docker.
Conclusion
We have tried 2 methods to run Golang application with docker. You may choose which one is more suitable for you. Or maybe you have another method besides these two, like pulling the source code from git in the docker. Leave a comment.