Dockerizing a Compiled Server

Let’s Dockerize a simple Go web server. First, if you have Go installed, you can build a server locally.

Note: If you don’t want to build it locally, you can just read along to understand the concepts!

The Go Server Code (main.go)

package main

import (
	"fmt"
	"log"
	"net/http"
	"os"
	"time"
)

func main() {
	m := http.NewServeMux()
	m.HandleFunc("/", handlePage)

	port := os.Getenv("PORT")
	if port == "" {
		port = "8010"
	}

	srv := http.Server{
		Handler:      m,
		Addr:         ":" + port,
		WriteTimeout: 30 * time.Second,
		ReadTimeout:  30 * time.Second,
	}

	fmt.Println("server started on", port)
	err := srv.ListenAndServe()
	log.Fatal(err)
}

func handlePage(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "text/html")
	w.WriteHeader(200)
	w.Write([]byte("<html><body><p>Hello from Docker! I'm a Go server.</p></body></html>"))
}

If you compile this (go build -o goserver), you get a standalone binary file.

Dockerizing the Server

To run this inside Docker, we need to:

  1. Create a Dockerfile
  2. COPY the compiled binary into the image
  3. Use CMD to run it

Create a Dockerfile:

FROM debian:stable-slim

# COPY source destination
COPY goserver /bin/goserver

# Expose a port variable
ENV PORT=8991

# Start the server
CMD ["/bin/goserver"]

The COPY and ENV Commands

  • COPY: Copies files from your host machine into the container image.
  • ENV: Sets environment variables inside the container environment. We updated the Go code above to read the PORT environment variable.

Building and Running

Build the image:

# If building on Mac/Windows for a Linux container, compile with:
# GOOS=linux GOARCH=amd64 go build -o goserver

docker build . -t goserver:latest

Run the container, making sure to forward the configured port:

docker run -p 8991:8991 goserver

You can now visit http://localhost:8991 to see your Dockerized Go server!