Stopping a golang container quickly

Hi there! I think I’m using a standard Golang/Docker recipe from 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?

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.)

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

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: ?

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 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 script can do the (static) compilation. It would look something like this:

host:~/project$ mkdir x
host:~/project$ cd x
host:~/project/x$ ../
host:~/project/x$ ls
Dockerfile  program
host:~/project/x$ cat Dockerfile
FROM scratch
COPY program /
ENTRYPOINT ["/program"]
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

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

RE… I see but it doesn’t seem to offer much value over does it?

The last thing that puzzles me is how to prevent Docker caching

Seems to be all or nothing?! :slight_smile:

I find to be a handy hook to do any sort of build-time setup, but in my system many of the 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 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.

1 Like

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 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!