Skip to content

A service template in go with a brief docker tutorial

Notifications You must be signed in to change notification settings

OrkhanHuseynli/service_template_golang

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

20 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Golang

Run

go run ./src/main.go

Build

go mod tidy
go mod vendor
go build -mod=vendor ./src/main.go

Tests

go test -cover ./...
go test ./... -bench=. -benchmem

Profiling

The address to the profiling page: http://localhost:8080/debug/pprof/

Docker

NOTE: Commands and instructions below are valid for Windows machines

1. Basic commands

1.1. Use the --rm flag to keep our filesystem clean after we stop our container.

Once we start our image with the following command it becomes a container

docker start -i --rm [image-name] sh

1.2 Start a sleeping container interactively

docker start -i [container-id]

  • Type a linux command, i.e. ls to list all files/folders inside the current directory of the container

2. Adding Volumes

  • bind mounting a host-directory in a container (docker run -v /some/host/dir/:/container/path/) uses the files that are present on the host. If the host-directory doesn't exist, a new, empty directory is created on the host and mounted in the container (this will change in future, and an error is shown in stead)
  • using a "nameless" volume (docker run -v /container/path) will create a new volume, and copy the contents of /container/path into that volume
  • using a "named" volume (docker run -v somename:/container/path) will create a new volume, named "somename", or use the existing "somename" volume, and use the files that are present inside that volume. If the volume is newly created, it will be empty.
    docker run --rm -it -v C:/go-work/src/github.com/service_template/:go/src/service_template golang:alpine /bin/sh

3. Docker ports

Note: pwd is a source path for the app

docker run -it --rm -v $(pwd):/src -w /src -p 8080:8080 golang:alpine /bin/sh

  • Now you can run your app inside the docker simply by running go run main.go *The -w flag we are passing is to set the working directory that means that any command we run in the container will be run inside this folder.
  • We are not using alpine:latest, which is a lightweight version of Linux, we are using golang:alpine, which is a version of Alpine with the most recent Go tools installed.
  • We will add the -p argument to specify the port. Like volumes, this takes a pair of values separated by a colon (:). The first is the destination port on the host that we would like to bind to the second is the source port on the Docker container to which our application is bound.

4. Docker networking

By default, Docker supports the following network modes:

  • bridge
  • host
  • none
  • overlay
4.1 Connect docker to the custom network
  1. Create network
    docker network create testnetwork
  2. Attach your service to the network
    docker run --rm -it -v C:/go-work/src/github.com/service_template/:/go/src/mic_tem -w /go/src/service_template/src --name server_a --network=testnetwork golang:alpine /bin/sh
  3. Run the service
    go run main.go
  4. Open a new terminal and do a curl request to the service in the specified network (i.e. "testnetwork")
    docker run --rm --network=testnetwork appropriate/curl:latest curl -i -XPOST server_a:8080/product -d "{\"product\":\"Nike\"}"

5. Running the Dockerfile

  1. Build the image:
    docker build ./ -t imagename
  2. Create container from the image
    docker run -p 8080:8080 imagename
  3. Do POST request to localhost:8080/product with the body {"product": "some product"}.
    You should get the response: {"message":"new product name: new product","date":"","id":"0"}

NOTE: If you requests fail in Windows machines then you can check in the Oracle WM if guest ports are linked to the ones in the host. Go to VM's settings (usually with the general name "default") -> Network -> Advanced -> Port Forwarding -> Adds new port forwarding rule -> put Host IP 127.0.0.1 and Host port 8080, also add Guest port 8080

6. docker-compose

Inside docker-compose.yml file you can define services that will make up your application. In example, we are describing two services: our example code that we have just built and the second is a simple service that curls this API.

By default Compose sets up a single network for your app. Each container for a service joins the default network and is both reachable by other containers on that network, and discoverable by them at a hostname identical to the container name.

To avoid conflicts when starting a stack, we can pass -p projectname to the docker-compose up command; this will prefix the name of any of our containers with the specified project name.

To start all services defined in docker-compose.yaml file, run:
docker-compose up

To stop containers and removes containers, networks, volumes, and images created by up, run:
docker-compose down

Also, to remove any stopped container that you have started with dockercompose, we can use the particular compose command rm and pass the -v argument to remove any associated volumes:
docker-compose rm -v

Remove all containers:
docker container prune

Appendix

1. Go Build
1.1 go versions <=1.1

CGO_ENABLED=0 GOOS=linux GOARCH=386 go build -a -installsuffix cgo -ldflags '-s' -o server

  • CGO_ENABLED=0 Cgo enables the creation of Go packages that call C code. By setting it to 0, we make it unavailable.
  • GOARCH=386 This is pronounced “gore-ch”, and stands for Go Architecture.
  • GOOS=linux GOARCH=386 The key-value pair starts with the GOOS, which in this example would be linux, referring to the Linux OS. The GOARCH here would be 386, which stands for the Intel 80386 microprocessor.
  • -ldflags for details follow the link.
  • -ldflags '-s', this argument passes the -s argument to the linker when we build the application and tells it to statically link all dependencies.
  • -o output
  • -a force rebuilding of packages that are already up-to-date

Note: A statically linked binary has all of the required library code built in, so it's big but will run on just about any system of the same type it was compiled on. If the binary is dynamically linked (uses shared libraries), all systems it is to run on must have a copy of all the required libraries. For more info read "Static and Dynamic Libraries".

1.2 go versions > 1.1

GOOS=linux GOARCH=386 go build -a -ldflags '-s' -o server

About

A service template in go with a brief docker tutorial

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published