How To: Build a Containerized Web App In Go
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 yourdocker-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!