How To: Build a Containerized Web App In Go

Pascal Allen
3 min readJun 17, 2023
Photo by Chinmay B on Unsplash

This publication is meant to serve as a very basic set of instructions for spinning up a simple Go web application with Docker.

For simplicity, this publication assumes that you have already downloaded and are running Docker on your host machine. You can download Docker and Docker Compose by going to the links that I’ve listed below in the “Prerequisites” section.

Prerequisites

Initialize Module

First, create a new directory for your Go web app, and cd into it.

mkdir go-web-app && cd go-web-app

Now initialize a Go module by running the command below. This command utilizes the Go Docker image from the Docker Hub to run go mod init example/user/go-web-app, removing the need to have Go installed on your host machine.

docker run --rm \
-v ".":"/app" \
-w "/app" \
golang:1.20 \
go mod init example/user/go-web-app

By now, your project should contain only a go.mod file. The go.mod file describes your module’s properties, including its dependencies on other modules and on versions of Go.

Containerize

Since we don’t want to have to depend on Go locally, we can leverage Docker to containerize our project’s dependencies. One of which is Go. So let’s create a couple of files to facilitate this feature.

First create a file called Dockerfile at the root of your project and add the following code. Code comments have been included for clarity.

# syntax=docker/dockerfile:1

FROM golang:1.20

# Set destination for COPY
WORKDIR /app

# Download Go modules
COPY . ./
RUN go mod download

# Build
RUN CGO_ENABLED=0 GOOS=linux go build -o /go-web-app

# Optional:
# To bind to a TCP port, runtime parameters must be supplied to the docker command.
# But we can document in the Dockerfile what ports
# the application is going to listen on by default.
# https://docs.docker.com/engine/reference/builder/#expose
EXPOSE 9990

# Run
CMD ["/go-web-app"]

Now create a file called docker-compose.yml at the root of your project and add the following code.

version: "3.8"

services:
go-web-app:
build:
context: .
container_name: go-web-app
ports:
- "9990:9990"
volumes:
- .:/app:rw

Great! Let’s keep going.

Your First Go Program

Now that we’ve initialized our Go module and set up Docker, we are ready to write our program. Create a file called main.go at the root of your project and add the following code. This will be the entry point to our application.

package main

import (
"fmt"
"net/http"
)

func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, World!")
})

http.ListenAndServe(":9990", nil)
}

This code provisions a web server and listens to requests on port 9990. When a request is made to the URI: /, you should get back a response of Hello, World!. But not quite yet since we still need to bring up our Docker services. So let’s keep going.

Running Your Program With Docker

To bring up and bring down your Go web app, it’s worth detailing a few key Docker CLI commands. I’ll summarize below:

  • Run docker-compose build to build or rebuild the services as defined in your docker-compose.yml file
  • Run docker-compose up -d to create and start the containers in the background
  • Run docker-compose logs -f to follow log output from the containers
  • Run docker-compose down to stop and remove containers

So, to start our application let’s run the following command from the root of the project.

docker-compose build && docker-compose up -d && docker-compose logs -f

Visit http://localhost:9990/ in your browser to see your Go web app running in action.

And to bring down our application simply run the following command from the root of the project.

docker-compose down

Conclusion

There you have it! Your first containerized Go web application. This tutorial is meant to be a very basic foundation to what’s possible with Docker and Go. I hope you found this to be informative. Have a great day!

--

--