0

How do I execute an executable twice in a docker container?

For instance I need to run my application twice, the first time to initialize some stuff, and the second time to listen to a given port defined in an environment variables.

The commands from a shell would be something like this:

[j3d@gonzo test]$ kontrol -initial
[j3d@gongo test]$ kontrol
started... listening on port 6000...

Here below is my Dockerfile:

FROM golang:1.8.3 as builder
RUN go get -u github.com/golang/dep/cmd/dep
RUN go get -d github.com/koding/kite
WORKDIR ${GOPATH}/src/github.com/koding/kite
RUN ${GOPATH}/bin/dep ensure
RUN go install ./kontrol/kontrol
RUN mv ${GOPATH}/bin/kontrol /tmp

FROM busybox
ENV APP_HOME /opt/robotrader
RUN mkdir -p ${APP_HOME}
WORKDIR ${APP_HOME}
COPY --from=builder /tmp/kontrol .
ENTRYPOINT ["./kontrol", "-initial"]
CMD ["./kontrol"]

The container builds successfully... but when I start it I always get the following error message:

kontrol    | standard_init_linux.go:190: exec user process caused "no such file or directory"

Any help would be really appreciated.

EDIT

Thanks to zero298 who helped me to figure out the issue, here below is a working Dockerfile:

FROM golang:1.8.3 as builder
RUN go get -u github.com/golang/dep/cmd/dep
RUN go get -d github.com/koding/kite
WORKDIR ${GOPATH}/src/github.com/koding/kite
RUN ${GOPATH}/bin/dep ensure
RUN CGO_ENABLED=0 go install ./kontrol/kontrol
RUN mv ${GOPATH}/bin/kontrol /tmp

FROM busybox
ENV APP_HOME /opt/robotrader
RUN mkdir -p ${APP_HOME}
WORKDIR ${APP_HOME}
COPY --from=builder /tmp/kontrol .
ENTRYPOINT ["./kontrol", "-initial"]
CMD ["./kontrol"]

The go application should be built with CGO_ENABLED=0 - see this post for more info.

j3d
  • 9,492
  • 22
  • 88
  • 172

3 Answers3

1

If kontrol terminates when you run it with the init flag, then you shuold just use

RUN /opt/robotrader/kontrol -init
CMD ["./kontrol"]

If it doesn't terminate, you'll have to find another way to architect your appp.

Robert Moskal
  • 21,737
  • 8
  • 62
  • 86
1

I think you are running into a different issue than you think you are. Running your Dockerfile and then executing:

docker build -t j3d .
docker run -it --rm --name j3d-test --entrypoint sh j3d

Allows me to run my own commands from within the container.

Using ls lists out the PWD contents:

-rwxr-xr-x    1 root     root       16.8M Jun 21 19:20 kontrol

Everything seems normal. However, trying to run that myself generates the following error:

sh: ./kontrol: not found

To me, this is likely similar to: Linux executable fails with “File not found” even though the file is there and in PATH.

In fact, if you instead:

  1. Copy the compiled kontrol executable out of your builder image
  2. Run the ubuntu container mounting the directory with the copied kontrol executable docker run -it --rm -v $PWD:/mnt/go ubuntu sh
  3. Try to run kontrol

You will get the "correct" error which stipulates you haven't setup your keys correctly:

2018/06/21 19:56:57 cannot read public key file: open : no such file or directory

Your path forward is probably to figure out why you can't cross-compile

zero298
  • 25,467
  • 10
  • 75
  • 100
  • Yes... if I replace busybox with golang:1.8.3, then it works. For sure in busybox there are some missing dependencies... even it it shouldn't as `go` executable should be self-contained. – j3d Jun 21 '18 at 20:14
  • To make it run with `busybox`, I had to compile `kontrol` with `CGO_ENABLED=0`. – j3d Jun 21 '18 at 21:04
1

Create a script that runs it twice:

E.g in "startup.sh"

#!/bin/bash

# Run kontrol twice
./kontrol -initial
./kontrol

Then replace the last two lines in your Dockerfile with:

COPY startup.sh .
CMD ["./startup.sh"]
cheemcheem
  • 114
  • 6