0

Building a cpp binary inside a docker builder with cmake

FROM ubuntu:focal as builder
WORKDIR /var/lib/project
RUN cmake ... && make ...

Then copying the built binary to final image which also is ubuntu:focal, to a WORKDIR.

WORKDIR /var/lib/project

COPY --from=builder /usr/src/project/bin/binary ./binary

EXPOSE 8080

CMD ["./binary"]

Running the docker with docker run hangs the docker (even with -d), no input and output. To stop the docker, I have to kill it from another terminal. However, if I exec into that same container while it is hanging, and run the binary from the shell inside the docker, it will work as expected.

Command used to build the docker

docker build . --platform=linux/amd64 --file docker/Dockerfile --progress=plain -c 32 -t mydocker:latest

Tried:

CMD ["/bin/bash", "-c" , "./binary"]
CMD ["/bin/bash", "-c" , "exec", "./binary"]

And same configurations with ENTRYPOINT too. Same behavior.

I'm guessing there is a problem with how the binary is built, maybe some specific flags are needed, because if I do docker run ... ls or any other built in command it will work and output to my stdout.

Expecting to have my binary std* redirected to my std* just like any other command inside docker.

There is another related question, as of now, unanswered.

Update: Main binary is built with these

CXX_FLAGS= -fno-builtin-memcmp -fPIC -Wfatal-errors -w -msse -msse4.2 -mavx2

Update: Main part of the binary code, The version is apache arrow 10.0.1

int main() {
   arf::Location srv_loc = arf::Location::ForGrpcTcp("127.0.01", 8080).ValueUnsafe();
   arf::FlightServerOptions opt(srv_loc);
   auto server = std::make_unique<MyService>();
   ARROW_RETURN_NOT_OK(server->Init(opt));
   std::printf("Starting on port: %i\n", server->port());
   return server->Serve().ok();
}

UPDATE: The problem seems to be here:

While the container is hanging, I entered into it, and did a ps aux. The binary gets PID=1, I don't know why this happens, but hardly this is the correct behavior.

USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root           1  0.2  0.0 341520 13372 ?        Ssl  07:52   0:00 ./binary
root          12  0.5  0.0   4116  3412 pts/0    Ss   07:52   0:00 /bin/bash
root          20  0.0  0.0   5900  2884 pts/0    R+   07:52   0:00 ps aux

UPDATE: ./binary is executable, chmod +x is useless.

Adding printfs to multiple places did not work, unless the last line server->Serve() is commented out, or prints are really large, then everything gets printed.

Separating return statement from server->Server() makes no difference.

UPDATE:

Running the built container with docker --init -d flag, works. Tough is this the right way? and if so how can this be forced in dockerfile?

ishkhan23
  • 11
  • 5
  • You can try building your C++ binary with the flag "-fPIC". https://stackoverflow.com/questions/5311515/gcc-fpic-option – Shivani Dec 29 '22 at 08:48
  • It is built with that flag anyway. – ishkhan23 Dec 29 '22 at 08:50
  • Try running bash instead of your binary to test if it works. If it works, then check if binary is in the working directory. If it doesn't work, then you are doing something wrong. – kiner_shah Dec 29 '22 at 10:00
  • What does `binary` actually do; would including some of its code in the question help clarify things? Is the container actually starting; when you say it "hangs the docker", what part(s) of the system become unresponsive? My suspicion is that your Docker setup is probably correct but you might be having trouble routing stdin to the container (`docker run -i` option) or there's a code issue; if the `CMD` is wrong that usually results in an immediate error. – David Maze Dec 29 '22 at 11:16
  • @kiner_shah Bash works, and all other built in commands work too, as stated in the question. And the binary is working when I `exec` into container and run it there. – ishkhan23 Dec 29 '22 at 11:21
  • @DavidMaze The binary is an apache arrow, server. I'll update the question to include the main part of the code. – ishkhan23 Dec 29 '22 at 11:24
  • @DavidMaze Yes the container is starting, and hanging there, without any output, and not taking any input like Ctrl+C. While it is in that state I can `exec` into it from another shell, and running `ps aux` shows that my `binary` is actually running – ishkhan23 Dec 29 '22 at 11:25
  • Try with `int main() { printf("soemthing\n"); }`. Add `RUN chmod +x ./binary` to your Dockerfile. `why this happens, but hardly this is the correct behavior.` ? It happens because this is docker with separate PID namespace and this is the correct behavior. `here is a problem with how the binary is built` Create an [MCVE]. How do _I_ reproduce the issue? _Remove_ the code, all the options, until you are left with the smallest amount of settings to reproduce the problem. For starters, I propose to remove everything from main and try with simple printf. – KamilCuk Jan 09 '23 at 08:20
  • @KamilCuk Will try your suggestions, and update asap. – ishkhan23 Jan 09 '23 at 08:39

1 Answers1

0

This problem is related to the pid of the process in the container. You can use the --init flag to avoid the problem. for more information visit this site- https://docs.docker.com/engine/reference/run/#specify-an-init-process

  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jan 09 '23 at 13:23
  • Yes, it worked, but, somehow this must be forced in `dockerfile`. – ishkhan23 Jan 09 '23 at 13:30
  • These problems happen when there are many processes in one container. It's good practice to have one process per container, but to solve your problem for your images, you should use ready-made images that already have the tiniest and simplest initializer available for containers. The name of this process is tini. There are official images for both Ubuntu and Centos. You can read these articles for more information. https://github.com/krallin/tini https://computingforgeeks.com/use-tini-init-system-in-docker-containers/ – Gurgen Yegoryan Jan 10 '23 at 10:25