Launch a Golang web server using Docker
If you want to create a web server using Go the simplest way to deploy is using Docker. Golang code is compiled to a binary and does not need a special environment to run.
Here is the simplest web server code in Go to get started. Save this as webserver.go
package main import ( "fmt" "log" "net/http" "runtime" ) func main() { http.HandleFunc("/", indexHandlerHelloWorld) log.Fatal(http.ListenAndServe(":8080", nil)) } func indexHandlerHelloWorld(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello world, I'm running search on %s with an %s CPU ", runtime.GOOS, runtime.GOARCH) }
We can use the simplest docker image scratch and add a directive to copy the binary to the server. Save as Dockerfile.
FROM scratch MAINTAINER Maria De Souza <[email protected]> ADD go-webserver go-webserver ENTRYPOINT ["/go-webserver"] EXPOSE 8080
We setup a start shell script to build and kick up the docker
#!/bin/bash GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -a -o go-webserver webserver.go || exit 1 if [ "$(docker ps -q -f name=go-web-server)" ]; then docker stop $(docker ps -a -q --filter name=go-web-server --format="{{.ID}}") fi docker build -t go-web-server . || exit 1 docker run -p 8000:8080 go-web-server || exit 1
You can use the -h option to add the hostname to the webserver
Voila! Now your webserver is running. Navigate to http://localhost:8000/ to test.
Known Issue
If you make any SSL requests from your webserver, you will see the following error when running the webserver using Docker:
x509: failed to load system roots and no roots provided
This is because the /etc/ssl/certs/ca-certificates.crt, is missing from the scratch image that is read by the golang tls package.
To avoid this copy the cert to your docker image from your local system. I normally add this to my bash script that will copy it based on OS.
if [ ! -e ca-certificates.crt ]; then if [[ $(uname) = "Darwin" ]]; then cp /usr/local/etc/openssl/cert.pem ca-certificates.crt || exit 1 else cp /etc/ssl/certs/ca-certificates.crt ca-certificates.crt || exit 1 fi fi
This is what your Dockerfile should then look like:
FROM scratch MAINTAINER Maria De Souza <[email protected]> COPY ca-certificates.crt /etc/ssl/certs/ca-certificates.crt ADD go-webserver go-webserver ENTRYPOINT ["/go-webserver"] EXPOSE 8080