skip to Main Content

I have a Dockerfile

FROM eclipse-temurin:17-jre-alpine
LABEL authors="sort-architectures"

WORKDIR /app/kafka

COPY ./kafka-3.5.1-src .

CMD ls -lisa bin | grep kafka-s

ENTRYPOINT ["top", "-b"]

but when I build it and run it

docker build .
docker run IMAGE-SHA256

I get the message

top: unrecognized option: /
BusyBox v1.36.1 (2023-11-07 18:53:09 UTC) multi-call binary.

Usage: top [-bmH] [-n COUNT] [-d SECONDS]

Show a view of process activity in real time.
Read the status of all processes from /proc each SECONDS
and show a screenful of them.
Keys:
        N/M/P/T: show CPU usage, sort by pid/mem/cpu/time
        S: show memory
        R: reverse sort
        H: toggle threads, 1: toggle SMP
        Q,^C: exit
Options:
        -b      Batch mode
        -n N    Exit after N iterations
        -d SEC  Delay between updates
        -m      Same as 's' key
        -H      Show threads

What’s the reason? Without the line CMD ls -lisa bin | grep kafka-s it actually works. What am I doing wrong?

2

Answers


  1. IMHO the issue here has nothing to do with the CMD command. I tested both with and without it and got the error in both cases.

    The problem is that the base image does some initialisation via ENTRYPOINT. That initialisation turns out to be important! When you specify your own ENTRYPOINT you are bypassing the initialisation from the base image.

    It’s not clear what you are trying to accomplish, but this will at least work:

    FROM eclipse-temurin:17-jre-alpine
    
    WORKDIR /app/kafka
    
    RUN wget https://archive.apache.org/dist/kafka/3.5.1/kafka-3.5.1-src.tgz && 
        tar -zxvf kafka-3.5.1-src.tgz && 
        mv kafka-3.5.1-src/* . && 
        rm -rf kafka-3.5.1-src
    
    CMD ls -lisa bin | grep kafka-s
    
    ENTRYPOINT ["/bin/sh", "-c", "/__cacert_entrypoint.sh && top -b"]
    

    To make this self-contained I’m downloading the Kafka distribution during the build process. However, this is not actually germane to the problem.

    Depending on what you are wanting to achieve you might consider rather running the top -b command via CMD.

    enter image description here

    Login or Signup to reply.
  2. When you combine ENTRYPOINT and CMD, it’s not intuitively obvious how it works.

    Docker only runs a single command when the container starts. If you have both an ENTRYPOINT and a CMD, the CMD is appended after the ENTRYPOINT into a single command.

    Your Dockerfile has both

    CMD ls -lisa bin | grep kafka-s
    ENTRYPOINT ["top", "-b"]
    

    After they’re combined, the final command that Docker uses to start your container is

    top -b 'ls -lisa bin | grep kafka-s'
    

    That complains about the ‘l’ being an unknown option and not a ‘/’ like you have. I don’t know why that is. It might be because your Dockerfile has changed and the error message you show isn’t from the version of the Dockerfile that you show.

    To run more than one command on container startup, there are different ways you can do it. Either write a script that runs the commands you need or string them together using the && or & shell operators and run them all in an single ENTRYPOINT or CMD statement.

    If you have both ENTRYPOINT and CMD, the ‘normal’ practice is to have the command in the ENTRYPONT and any parameters in the CMD. The CMD is easily overridden in the docker run command, so if you want different options, it’s easy to do. For instance if you have

    ENTRYPOINT top
    CMD -b
    

    That will run top -b on startup.

    You can then switch out the -b option for something else on docker run. If you wanted to use -c instead, you’d do

    docker run image -c
    

    and the command run on container startup would be top -c.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search