DEV Community

Simone Gentili
Simone Gentili

Posted on • Updated on

Little http go server inside docker container

Before starting

We are going to create a new project with go. First time to do is to create a folder with our project name. My personal suggestion is to create a development folder in our home. And inside dev folder all our projects such this:

  • ~/development/github.com/sensorario/go-docker.

On Github

This project is made following this project. In main branch you can find same code you can see here. The project went on since a wrote this article as draft. You are free to check first release (v1.0.0) here.

Go Http server

What we need for this trivial example is the code of the simplest http server. Obviously written using go. Because the focus is not to write a complete go example but only its integration inside a docker container the example will be nothing more a simple hello world http server.

package main

import (
    "fmt"
    "net/http"
)

func main() {
    http.HandleFunc("/", HelloServer);
    http.ListenAndServe(":5000", nil);
}

func HelloServer(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hello, world!");
}
Enter fullscreen mode Exit fullscreen mode

This content must be saved in file main.go inside the root folder of our project. We will not build the file in our machine but we will do it inside the container and specifically inside the Dockerfile.

Dockerfile

Let's go on the creation of this exercise creating the Dockerfile. First of all we must specify the go image we want to start from.

FROM golang
Enter fullscreen mode Exit fullscreen mode

Because of we are not specifying the go version, it will be the latest. Second command we need is the creation of the app folder. This folder will contains sources of our program.

RUN mkdir /app
Enter fullscreen mode Exit fullscreen mode

Once created, folder designed to contain sources of our application, we will copy all the content of our project in the app folder.

ADD . /app
Enter fullscreen mode Exit fullscreen mode

And then, we will specify the desire to execute every next command like we are placed inside app/ folder. In other words, we now will set app/ folder as working folder.

WORKDIR /app
Enter fullscreen mode Exit fullscreen mode

After the copy of all the code here, we need to build our go application. The command tu run is very very simple and it means that our go project will generate an executable called main in current folder (-o main .).

RUN go build -o main .
Enter fullscreen mode Exit fullscreen mode

We are close to finish Dockerfile. As the most attentive readers will have noticed the go program listen port 5000. The port exposed by the container is 5000. Value is arbitrary. Expose a port is necessary to the container to be reached from our host. Host is our machine.

EXPOSE 5000
Enter fullscreen mode Exit fullscreen mode

Last but not least, the command that run the just created executable.

CMD ["/app/main"]
Enter fullscreen mode Exit fullscreen mode

The following is the final result.

FROM golang
RUN mkdir /app
ADD . /app
WORKDIR /app
RUN go build -o main .
EXPOSE 5000
CMD ["/app/main"]
Enter fullscreen mode Exit fullscreen mode

Easy! Isn't it?

docker-compose.yaml

To make our life easier, we create a docker-compose file in which configuring and managing docker in general becomes easier. In this file it says where the Dockerfile is, which ports are exposed and then it says that you want to share the volume. What is the folder of our project corresponds to the folder /opt/app/api.

version: "3.9"
services:
    app:
        build:
            dockerfile: Dockerfile
            context: .
        volumes:
            - .:/opt/app/api
        ports:
            - "5000:5000"
Enter fullscreen mode Exit fullscreen mode

Makefile

If you are not familiar with Makefile please read this article.

Sometimes learning so many commands becomes difficult, at least for me. That's why in every project I add a makefile that makes my life easier. In our Makefile we then add a command that allows us to pull up this container.

generally my Dockerfile contains up, down, build, bash_mysql and so on

up:
    docker-compose up -d --build
Enter fullscreen mode Exit fullscreen mode

Then we run the make command. The result should be approximately the following.

โ€‹โ€‹docker-compose up -d --build
Building app
[+] Building 3.5s (11/11) FINISHED
 => [internal] load build definition from Dockerfile
 => => transferring dockerfile: 146B
 => [internal] load .dockerignore
 => => transferring context: 2B
 => [internal] load metadata for docker.io/library/golang:latest
 => [auth] library/golang:pull token for registry-1.docker.io
 => [1/5] FROM docker.io/library/golang@sha256:124966f5d54a41317ee81ccfe5f849d4f...
 => [internal] load build context
 => => transferring context: 465B
 => CACHED [2/5] RUN mkdir /app
 => [3/5] ADD . /app
 => [4/5] WORKDIR /app
 => [5/5] RUN go build -o main .
 => exporting to image
 => => exporting layers
 => => writing image sha256:940d9cb837f6f0ccc21178699ee336ca5195b89d648df3b3...
 => => naming to docker.io/library/go-docker_app
Enter fullscreen mode Exit fullscreen mode

Call the server

We said that our container exposes port 5000 and that we have built a small server to listen in that port. And make is called, ... Now we just have to test it with a simple command like curl.

curl http://localhost:5000
Hello, world!
Enter fullscreen mode Exit fullscreen mode

It works! Thank you!

Top comments (0)