Docker Community Forums

Share and learn in the Docker community.

Stopping a golang container quickly


(Kai Hendry) #1

Hi there! I think I’m using a standard Golang/Docker recipe from blog.golang.org docker

However I noticed it takes 10s to stop. And it exits with code 137.

When I exec into the running container, I noticed I try kill process 1, it doesn’t seem to quit. Why is the golang binary being run from shell? What am I missing?


(David Maze) #2

The “string” form of CMD and ENTRYPOINT always run /bin/sh -c "...". (And, correspondingly, the signal docker stop sends goes to the shell, not your process, which may be why it needs to be kill -9'd.) Try the JSONish form

ENTRYPOINT ["/go/bin/count", "-port", "9000", "-openbrowser", "false"]

(If the container does other things and getting a shell in it is useful, I might prefer CMD to ENTRYPOINT. If you rebuild the program outside the container, statically link it, and build it into a FROM scratch container such that running the count binary is literally the only thing it can do, ENTRYPOINT makes sense.)


(Kai Hendry) #3

Thank you David! I now get a status=2/invalidargument

http://s.natalian.org/2016-05-31/2.txt

Any ideas why?

I would like to use FROM scratch, but what puzzles me… is how am I supposed to build the binary the static binary in a container to begin with? Can a Dockerfile bootstrap another?

What is best practice for Continuous Integration here? Something like I do here: https://github.com/kaihendry/lk/blob/master/Dockerfile ?


(David Maze) #4

No; but what does docker logs count say? Does it work if you just docker run from the command line? Does it work if you docker run --rm -it count bash, then run the program from there?

In my hand-built environment, every container build has a setup.sh script, which is responsible for producing a Dockerfile and whatever other artifacts are required. That can (with some care) docker run other things, and/or assume it’s being run on a Linux host with an appropriate toolchain available. In that setup, the setup.sh script can do the (static) compilation. It would look something like this:

host:~/project$ mkdir x
host:~/project$ cd x
host:~/project/x$ ../setup.sh
host:~/project/x$ ls
Dockerfile  program
host:~/project/x$ cat Dockerfile
FROM scratch
MAINTAINER Me! <me@example.com>
COPY program /
ENTRYPOINT ["/program"]
EXPOSE 80
host:~/project/x$ docker build -t program .
host:~/project/x$ cd ..
host:~/project$ rm -rf x
host:~/project$ docker run -d -p 80:8080 program

(Kai Hendry) #5

Ah, it was panic returning error code 2! This was the fix:

RE setup.sh… I see but it doesn’t seem to offer much value over https://github.com/kaihendry/lk/blob/master/Dockerfile does it?

The last thing that puzzles me is how to prevent Docker caching https://github.com/kaihendry/count/blob/master/Dockerfile#L2

Seems to be all or nothing?! :slight_smile:


(David Maze) #6

I find setup.sh to be a handy hook to do any sort of build-time setup, but in my system many of the setup.sh scripts are extremely routine “copy the Dockerfile into the target directory” things. Do you care that your image contains a Go toolchain that you don’t need at runtime? If you do, the “precompile a static binary, then build a FROM scratch issue” approach is better; but it’s totally reasonable to say “that doesn’t matter to me”.

Docker layer caching is extremely handy, but it does in fact conflict badly with invoking any kind of source control operation (hg pull -u, go get). There’s a docker build option to forcibly disable it. Another advantage of the setup.sh approach is that you can run these sorts of “must run every time” commands in the setup script, and then take advantage of build caching to not re-run the actual go install compilation step if it’s not necessary.


(Kai Hendry) #7

My end goal really, is to git push my golang changes and have my container restart with the changes in the sanest and ideally fastest possible manner.

My big issue right now, is when I restart the https://github.com/kaihendry/count/blob/master/count.service it takes almost a minute to build/deploy the new Docker image, leaving quite some downtime if my little count Web application was actually a production application!