Go compiler can produce a binary file which is can natively on any machine(given its built for that). However, there are times it is more convenient to containerize your application and this tutorial will help you to build a basic RESTFul API built-in go and containerize it.
Building a Web Server in Go#
We will write a simple Go application which exposes a simple greeting when a call is made to URI http:localhost:8080
. In order to build
this first, we will create a folder, and let’s say we call it as Go-App
and inside it we will create a folder called server
which is the home for all the back-end code we are going to write. The final folder structure will look like this
Next, we will create a Go Module which is a collection of Go packages stored in a file tree with a go.mod
file at its root but running the command inside the server folder
cd server
go mod init go-app
Now here we will create a very simple server that can handle HTTP requests. To do this we’ll create a new file called main.go
and include the below code snippet into the file
package main
import (
"fmt"
"log"
"net/http"
)
func main() {
http.HandleFunc("/", hello)
fmt.Println("Server started")
log.Fatal(http.ListenAndServe(":8080", nil))
}
func hello(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Header().Set("Content-Type", "application/json")
w.Write([]byte(`{"message":"hello world!"}`))
}
Now if we read through this file
main() function#
The main()
function acts as the entry point of the executable programs. It does not take any argument nor return anything and Go automatically calls the function when you execute to run the program
In main() function, the HandleFunc
call tells the HTTP package to handle all requests to the webroot ("/") with our hello
function. And when program control reached http.ListenAndServe
, specifies that our code should listen on port 8080
If we now run the command go run main.go
and navigate to localhost:8080
on our web browser, we should see something like this.
Now we have a basic Go application that serves response on URL http://localhost:8080
now next task is to build a docker image and run our application in a container. To do this create a file called Dockerfile in the project root directory and paste the below content
FROM golang:1.15-alpine AS GO_BUILD
COPY . /server
WORKDIR /server/server
RUN go build -o /go/bin/server/server
FROM alpine:3.10
WORKDIR app
COPY --from=GO_BUILD /go/bin/server/ ./
EXPOSE 8080
CMD ./server
The reasoning behind each line inside the docker file
Two important things in this Dockerfile:
- This file uses Docker multi-stage build in Docker, which is just a way of saying that we can build multiple Docker images defined in the same file. Here in this scenario, we use one image to build our Go application and another for running it.
- The next one is about caching. For a faster build process, Docker caches the result of each line of a Dockerfile. Order of lines is important inside the Dockerfile, and you should generally perform actions that don’t change very often earlier in the Dockerfile than things that do change more often.
FROM golang:1.15-alpine AS GO_BUILD` ensures Docker pulls the [offical Go image](https://hub.docker.com/_/golang/) as a base image n this case, we use the tag `1.15-alpine` .We mark the resulting image as `GO_BUILD
WORKDIR /server/server
sets the working directory.
COPY . /server
copies content over
RUN go build -o /go/bin/server/server
builds your app into a binary located at /bin/server
.
FROM alpine:3.10
uses alpine as our runner image in which our GO application will run
COPY --from=GO_BUILD /go/bin/server/ ./
copies the binary built earlier into the image
EXPOSE 8080
exposes application over port 8080
CMD ./server
sets the default command to run when the container is run
To build the docker image execute the below command on the project root directory
docker build -t api .
This builds a docker image with a name as api
and to run this image execute the below command
docker run -it -p 8080:8080 api
Conclusion#
You now know how to create a Restful Go API and containerize your application into a production-ready image.