June 3, 2023

Golang / Go Crash Course 07 | Building a Docker Container for our REST API

In this article we are going to build a docker container for our Golang application and before doing that we are going to quickly setup Go Modules that will allow us to manage the application dependencies efficiently and also will help us to down load those libraries to build and run the application using docker containers.

Remember on our previous article we have the Golang application that’s applying a clean architecture approach so we are independent of the database, we are independent of the HTTP router that we want to use in this case we are using MUX but we can also use CHI router or we can use Gin-gonic . And in this case we are using SQLite as the database, but we can use any other database such as Firebase, MySQL, Postgres or any other database engine.

Now we are going to setup Go Modules in our application and then we are going to make a few changes mostly related to package names and after that we are going to create a Dockerfile to build the docker image.

Initialize the module for the application

First we are going to initialize the module for the application so we are going to run the command go mod init repoURL ... and here the convention is to use the repo URL

$ go mod init github.com/favtuts/golang-mux-api

If we have initialized the module, then now we are going to change the new module name, the you can run the command

$ go mod edit -module github.com/favtuts/golang-mux-api

To rename all imported module from OLD_MODULE to NEW_MODULE

find . -type f -name '*.go' \
  -exec sed -i -e 's,{OLD_MODULE},{NEW_MODULE},g' {} \;

Here is specific in our cases

find . -type f -name '*.go' \
  -exec sed -i -e 's,golang-mux-api,github.com/favtuts/golang-mux-api,g' {} \;

More details you can check on the gist file: go mod rename module.sh

Allow pass PORT value via environment

First we need to export the PORT environment variable

$ export PORT="8000"
$ echo $PORT

Then we are going to make change the server code to use port value from environment variable

package main

import (

	router "github.com/favtuts/golang-mux-api/http"

var (
	//postRepository repository.PostRepository = repository.NewFirestoreRepository()
	postRepository repository.PostRepository = repository.NewSQLiteRepository()
	postService    service.PostService       = service.NewPostService(postRepository)
	postController controller.PostController = controller.NewPostController(postService)
	httpRouter     router.Router             = router.NewMuxRouter()
	//httpRouter router.Router = router.NewChiRouter()

func main() {

	httpRouter.GET("/posts", postController.GetPosts)
	httpRouter.POST("/posts", postController.AddPost)

	httpRouter.SERVE(":" + os.Getenv("PORT"))

We can test to verify if the change is correct or not and just to check that everything is still working

$ go run *.go
Mux HTTP server running on port :8000

Create Dockerfile to build Docker image

We are going to create the Dockerfile with the content as bellow

# Start from the latest golang base image
FROM golang:latest

# Add Maintainer Info
LABEL maintainer="Favtuts.COM <favtuts@gmail.com>"

# Set the Current Working Directory inside the container

# Copy Go Modules dependency requirements file
COPY go.mod .

# Copy Go Modules expected hashes file
COPY go.sum .

# Download dependencies
RUN go mod download

# Copy all the app sources (recursively copies files and directories from the host into the image)
COPY . .

# Set http port

# Build the app
RUN go build 

# Run the app
CMD ["./golang-mux-api"]

Build and run docker container

First, we are going to build docker image

$ docker build -t golang-api .

Then we can run the docker container

$ docker run -p 8000:8000 golang-api
Mux HTTP server running on port :8000

Download Source Code

$ git clone https://github.com/favtuts/golang-mux-api.git
$ cd golang-mux-api

$ git checkout golang-docker
$ go build

$ go run .

Leave a Reply

Your email address will not be published. Required fields are marked *