Score:2

Docker ENTRYPOINT With a Piped Command

in flag

I am trying to create a dockerfile that uses a combination of rtlamr and rtlamr-collect to collect information about my utility meters. I cannot get the ENTRYPOINT in docker to be rtlamr | rtlamr-collect.

Here's my dockerfile:

FROM golang:latest AS build
RUN CGO_ENABLED=0 GOOS=linux go install github.com/bemasher/rtlamr-collect@latest
RUN CGO_ENABLED=0 GOOS=linux go install github.com/bemasher/rtlamr@latest

# Use a multi-stage build to reduce our image size
FROM alpine:latest AS runtime
COPY --from=build /go/bin/rtlamr /usr/bin/rtlamr
COPY --from=build /go/bin/rtlamr-collect /usr/bin/rtlamr-collect

# Really wish this would just work as expected:
ENTRYPOINT ["rtlamr | rtlamr-collect"]

As a work around I have found that I can create a simple shell script and have that serve as the entry point, but that wasn't ideal because of the need for an extra file. I would not be opposed to a solution that somehow created the extra file on the fly however:

Working dockerfile:

FROM golang:latest AS build
RUN CGO_ENABLED=0 GOOS=linux go install github.com/bemasher/rtlamr-collect@latest
RUN CGO_ENABLED=0 GOOS=linux go install github.com/bemasher/rtlamr@latest

# Use a multi-stage build to reduce our image size
FROM alpine:latest AS runtime
COPY --from=build /go/bin/rtlamr /usr/bin/rtlamr
COPY --from=build /go/bin/rtlamr-collect /usr/bin/rtlamr-collect

# I cannot for the life of me get `rtlamr | rtlamr-collect` to work as entry
# point to work around this limitation I created this small shell script that
# basically does it, and set that as the entry point which works.
ADD run.sh /usr/bin/run.sh
RUN chmod 777 /usr/bin/run.sh
ENTRYPOINT ["/usr/bin/run.sh"]

Content of run.sh:

#!/bin/sh
rtlamr | rtlamr-collect

I believe a simple test case to play with might be something like this:

dockerfile:

FROM alpine:latest
ENTRYPOINT ["echo 'hello world' | grep ell"]

Attempting to run this shows:

docker: Error response from daemon: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "echo 'hello world' | grep ell": executable file not found in $PATH: unknown.

However if you login to the Docker Container Shell and perform the same command it works as expected:

/ # echo 'hello world' | grep ell
hello world
Score:2
in flag

Thank you to enchbladexp in the Docker Discord Server for helping come up with the solution:

FROM golang:latest AS build
RUN CGO_ENABLED=0 GOOS=linux go install github.com/bemasher/rtlamr-collect@latest
RUN CGO_ENABLED=0 GOOS=linux go install github.com/bemasher/rtlamr@latest

# Use a multi-stage build to reduce our image size
FROM alpine:latest AS runtime
COPY --from=build /go/bin/rtlamr /usr/bin/rtlamr
COPY --from=build /go/bin/rtlamr-collect /usr/bin/rtlamr-collect

# Fully qualify the paths to the binaries
ENTRYPOINT ["/bin/sh", "-c", "/usr/bin/rtlamr | /usr/bin/rtlamr-collect"]

The root cause appears to have been that for whatever reason I had to fully qualify the paths of the binaries, along with provide /bin/sh as the entry point.

Score:1
US flag

Depending on the complexity of the command you can embed it into the Dockerfile like this:

FROM alpine:latest

RUN \
    echo "#!/bin/ash" > /entrypoint.sh &&\
    echo "echo 'hello world' | grep ell" >> /entrypoint.sh &&\
    chmod 755 /entrypoint.sh

ENTRYPOINT ["/entrypoint.sh"]

Output:

PS C:\Users\me\Desktop\test> docker build -t test ./
PS C:\Users\me\Desktop\test> docker run -it test:latest
hello world

If you need something more elaborate let me know and I'll have another dig through my previous work.

aolszowka avatar
in flag
Thanks for the Response Harry! As you can see in the rest of the question that is the solution I started using, is there a way to avoid having the additional shell script, or is that my only option?
Harry avatar
md
Hi @aolszowka - my mistake, here is another approach.
aolszowka avatar
in flag
Awesome that worked as well, however I was able to find a way to solve the root cause and have posted it below, thank you again for your help!
Harry avatar
md
Yeah, that's a great solution, but depends on how elaborate you need your entrypoint script. Glad you got what you needed!
I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.