Go Micro

Building a Microservice with Docker and Go

It seems hard to avoid the word “microservice” these days if you are a software engineer. It’s the thing that everyone is excited and talking about lately. My experience as an engineer early on was shaped by Services Oriented Architecture(SOA) along with distributed system using middle-wares like Weblogic, Jboss as well as JMS implementations for asynchronous messaging services. That said…Microservices is a familiar concept but yet a departure from the way I’ve helped build systems with services in the past. These days I am excited about learning all things Go and Docker and I thought it would be a good way to explain the Microservice concept.

What is a Microservice?

Martin Fowler’s does a good job of articulating what Microservices are in my opinion.

In short, the microservice architectural style is an approach to developing a single application as a suite of small services, each running in its own process and communicating with lightweight mechanisms, often an HTTP resource API.

Microservices are a particular way of building services but not the only way. Some advantages of building a microservice is that they tend to be smaller in scope and singularly focused.

Building services with Go

Go is becoming one of my favorite programming languages mainly because it allows me to express my logic in a clean and succinct manner without a lot of boiler plate. Here is a basic RESTFUL service in go that just returns a greeting to the user. Rather contrived but serves our purpose rather well. Save this file as “helloService.go”

package main

import (
"fmt"
"net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello World from a MicroService!")
}

func main() {
http.HandleFunc("/", handler)
http.ListenAndServe(":8080", nil)
}

Dockering your service

Now that we have our service all we need is a way to expose it to the world. Docker is a great tool for architecting Immutable Services (more about Immutability in another post) and a great choice for encapsulating bounded contexts as services. So to create a Dockerfile, add the following contents to a file called “Dockerfile” in the same directory where the Go service file from previous step resides.

FROM golang:onbuild
EXPOSE 8080

There’s a lot going on in the first line but essentially we inherit everything needed to set up our Go environment from the golang image and leverage it in our Dockerfile with just that one line. The second line exposes the port from within the container so that we can connect to our service once its running. Now to build the image copy and paste the following command into your terminal where your Dockerfile resides.

$ docker build -t helloservice .

This will take a few seconds the first time you run it but it will build your image assuming you have Docker installed. Moment of truth, lets run it…

$ docker run -p 8080:8080 --name helloservice --rm helloservice

If everything deployed correctly you should be able to go to http://192.168.99.100:8080 and see your service in action. You should see a message “Hello World from a MicroService!”.

That’s it, you now have a Microservice that returns a greeting message and it is containerized and deployed using Docker and written in Go.

gomirco on github.