Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

entrypoint defined in docker-compose.yml wipes out CMD defined in Dockerfile #3140

Closed
mericano1 opened this issue Mar 15, 2016 · 34 comments
Closed

Comments

@mericano1
Copy link

@mericano1 mericano1 commented Mar 15, 2016

Hi, I am following the example on https://docs.docker.com/compose/startup-order/ to make sure the database is running before I start the application.
My Dockerfile contains the command

CMD ["/usr/bin/java", "-jar", "/usr/lib/gumtree/api-server/server/api-server.war"]

and in my docker-compose.yml I have

entrypoint: ["/usr/bin/wait-for-it.sh", "postgres001:5432", "-t", "120", "--"]

but after the postgres database starts the service container just exits straight away.

api_1        | wait-for-it.sh: postgres001:5432 is available after 42 seconds
postgres001_1 | LOG:  database system is ready to accept connections
api_api_1 exited with code 0

Looking inside the running container I can see the entrypoint does not have the command appended

docker exec b456a362e587 ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.2  0.0  21816  3200 ?        Ss   22:12   0:00 bash /usr/bin/wait-for-it.sh postgres001:5432 -t 120 --

If both command and entrypoint are in the same place (either in the Dockerfile or in the docker-compose.yml) the application starts up properly.

› docker exec 6cafdb9fdcf2 ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.2  0.0  21816  3208 ?        Ss   22:10   0:00 bash /usr/bin/wait-for-it.sh postgres001:5432 -t 120 -- java -jar /usr/lib/gumtree/api-server/server/api-server.war

Any idea is this is a bug or I am doing something wrong?

Thanks

@dnephin dnephin added the area/config label Mar 16, 2016
@dnephin
Copy link
Contributor

@dnephin dnephin commented Mar 16, 2016

hmm, it does kind of feel like a bit in this case, but I think it's been this way for a while. The output of docker inspect <container name> would be good to verify exactly what the engine is receiving.

@mericano1
Copy link
Author

@mericano1 mericano1 commented Mar 16, 2016

Indeed @dnephin, the CMD gets wiped out

› docker inspect 172ab44fb462
...
"Cmd": null,
"Image": "api-server",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": [
  "/usr/bin/wait-for-it.sh",
  "postgres001:5432",
  "-t",
  "120",
  "--"
]
@dnephin dnephin added the kind/bug label Mar 16, 2016
@igr
Copy link

@igr igr commented Apr 6, 2016

Same here.

@max-zelinski
Copy link

@max-zelinski max-zelinski commented May 2, 2016

the same, had to put CMD in compose yaml for now...

@NMichas
Copy link

@NMichas NMichas commented May 7, 2016

Same here on Docker beta for OSX:

  • Docker version 1.11.1, build-5604cbe
  • docker-compose version 1.7.0, build-0d7bf73

Adding the CMD in docker-compose (or re-specifying it after -- on wait-for-it) works, but it is not such a good solution considering it tightly couples the docker-file with the underlying image.

@derekmahar
Copy link

@derekmahar derekmahar commented May 12, 2016

I also encounter this issue as I describe in "How can I make my Docker compose “wait-for-it” script invoke the original container ENTRYPOINT or CMD command?" and demonstrate using example docker-compose-wait-for-file.

derek@derek-lubuntu:~/Projects/docker-compose-wait-for-file$ docker-compose up
Creating dockercomposewaitforfile_create_1
Creating dockercomposewaitforfile_wait_1
Attaching to dockercomposewaitforfile_create_1, dockercomposewaitforfile_wait_1
create_1  | Sleeping for 10 s.
wait_1    | Waiting for file [/wait/done].
wait_1    | Waiting for file [/wait/done].
wait_1    | Waiting for file [/wait/done].
wait_1    | Waiting for file [/wait/done].
wait_1    | Waiting for file [/wait/done].
wait_1    | Waiting for file [/wait/done].
wait_1    | Waiting for file [/wait/done].
wait_1    | Waiting for file [/wait/done].
wait_1    | Waiting for file [/wait/done].
wait_1    | Waiting for file [/wait/done].
create_1  | Created file /wait/done.
dockercomposewaitforfile_create_1 exited with code 0
wait_1    | Found file [/wait/done].
dockercomposewaitforfile_wait_1 exited with code 0

Adding a CMD to image ubuntu-wait-for-file doesn't help:

derek@derek-lubuntu:~/Projects/docker-compose-wait-for-file$ git diff
diff --git a/ubuntu-wait-for-file/Dockerfile b/ubuntu-wait-for-file/Dockerfile
index 20e92c0..ccbabb7 100644
--- a/ubuntu-wait-for-file/Dockerfile
+++ b/ubuntu-wait-for-file/Dockerfile
@@ -1,3 +1,4 @@
 FROM ubuntu
 ADD wait-for-file.sh /
 RUN chmod +x /wait-for-file.sh
+CMD ["echo", "'Can you see me?'"]
derek@derek-lubuntu:~/Projects/docker-compose-wait-for-file$ docker-compose build
Building create
Step 1 : FROM ubuntu
 ---> b549a9959a66
Step 2 : ADD create-file.sh /
 ---> Using cache
 ---> 67e5db59f8e2
Step 3 : RUN chmod +x /create-file.sh
 ---> Using cache
 ---> c7e361b4408e
Step 4 : ENTRYPOINT /create-file.sh
 ---> Using cache
 ---> 0360027060ca
Successfully built 0360027060ca
Building wait
Step 1 : FROM ubuntu
 ---> b549a9959a66
Step 2 : ADD wait-for-file.sh /
 ---> Using cache
 ---> db75cb689f0e
Step 3 : RUN chmod +x /wait-for-file.sh
 ---> Using cache
 ---> d9a991cdd174
Step 4 : CMD echo 'Can you see me?'
 ---> Using cache
 ---> 19f4ad2a167c
Successfully built 19f4ad2a167c
derek@derek-lubuntu:~/Projects/docker-compose-wait-for-file$ docker-compose up
Creating dockercomposewaitforfile_create_1
Creating dockercomposewaitforfile_wait_1
Attaching to dockercomposewaitforfile_create_1, dockercomposewaitforfile_wait_1
create_1  | Sleeping for 10 s.
wait_1    | Waiting for file [/wait/done].
wait_1    | Waiting for file [/wait/done].
wait_1    | Waiting for file [/wait/done].
wait_1    | Waiting for file [/wait/done].
wait_1    | Waiting for file [/wait/done].
wait_1    | Waiting for file [/wait/done].
wait_1    | Waiting for file [/wait/done].
wait_1    | Waiting for file [/wait/done].
wait_1    | Waiting for file [/wait/done].
wait_1    | Waiting for file [/wait/done].
create_1  | Created file /wait/done.
dockercomposewaitforfile_create_1 exited with code 0
wait_1    | Found file [/wait/done].
dockercomposewaitforfile_wait_1 exited with code 0
@Satchitananda
Copy link

@Satchitananda Satchitananda commented May 24, 2016

Same, why docker guys not to fix it?

@ransingh
Copy link

@ransingh ransingh commented Jun 2, 2016

I am having the same issue.
entrypoint in docker-compose is wiping out CMD specified inside the dockerfile.

Here is the inspect output of the container

           "Cmd": null,
            "Image": "ransingh/siglee-api:61e2686",
            "Volumes": {
                "/home/siglee/siglee-api/log": {}
            },
            "WorkingDir": "/home/siglee/siglee-api",
            "Entrypoint": [
                "./wait_for_db",
                "db"
            ],
@gannicottb
Copy link

@gannicottb gannicottb commented Jun 9, 2016

Same here. :(

CMD defined in the app Dockerfile like so:
CMD ["java", "-jar", "./target/app.jar"]

Entrypoint defined in docker-compose.yml like so:
entrypoint: ["/usr/scripts/wait-for-it.sh", "db:5432", "-- "]

Container inspect on the app:
"Entrypoint": [ "/usr/scripts/wait-for-it.sh", "cotillion_db:5432" ],

Would love to see this fixed so I don't have to copy the CMD from the container into compose (especially as a general practice for many such container + db setups).

@numbnut
Copy link

@numbnut numbnut commented Jul 21, 2016

Same for me on OSX:
docker: Docker version 1.12.0-rc4, build e4a0dbc, experimental
docker-compose: docker-compose version 1.8.0-rc2, build c72c966
It would be very nice to see this fixed.

@aanand
Copy link
Contributor

@aanand aanand commented Jul 21, 2016

I'm not convinced this is a bug. It's consistent with docker run:

FROM alpine
CMD ["echo", "default command"]
$ docker build -t 3140 .

$ docker run --name no-entrypoint 3140
default command

$ docker inspect no-entrypoint
...
            "Cmd": [
                "echo",
                "default command"
            ],
...

$ docker run --name with-entrypoint --entrypoint echo 3140
<outputs a blank line>

$ docker inspect with-entrypoint
...
            "Cmd": null,
...

Apparently, this also happens when you set ENTRYPOINT in a Dockerfile which inherits a CMD from its parent image: see moby/moby#19611.

The discussion in that issue suggests two things:

  • This is by design.
  • It's not well-documented.

On top of that, our startup order document is wrong, as @mericano1 has discovered. So I think this is a docs issue.

@derekmahar
Copy link

@derekmahar derekmahar commented Jul 21, 2016

If it's by design, then I think it might be useful for a container to have a straightforward mechanism to invoke the ENTRYPOINT or CMD of its parent, similar to how many object-oriented programming languages enable a constructor to invoke a parent constructor creating a chain of constructor invocations to the root object.

@numbnut
Copy link

@numbnut numbnut commented Jul 21, 2016

Just an addition about the docker-compose documentation. The docker-compose.yml in the example implies that the command is not deleted, if the entrypoint is set in a compose file. Maybe the example is wrong, but that was the way I ran into this trap.

@aanand
Copy link
Contributor

@aanand aanand commented Jul 21, 2016

Yes, that's what I mean. We should fix that, add a note to the entrypoint documentation in the Compose file doc, and also ensure it's noted in the Engine docs for the ENTRYPOINT Dockerfile instruction and --entrypoint flag.

@aanand aanand added kind/docs and removed kind/bug labels Jul 21, 2016
@aanand
Copy link
Contributor

@aanand aanand commented Jul 21, 2016

@derekmahar That's an interesting idea, but that discussion should probably happen in a new issue on docker/docker.

@shocoladka
Copy link

@shocoladka shocoladka commented Jul 25, 2016

Same bug
Docker version 1.11.2, build b9f10c9
docker-compose version 1.8.0-rc2, build c72c966

@aanand
Copy link
Contributor

@aanand aanand commented Jul 25, 2016

@MrShoco It's not a bug - please read the discussion.

@aanand
Copy link
Contributor

@aanand aanand commented Jul 25, 2016

Compose-side docs updated in #3764.

@aanand
Copy link
Contributor

@aanand aanand commented Jul 25, 2016

Engine-side docs updated in moby/moby#25012.

@shocoladka
Copy link

@shocoladka shocoladka commented Jul 25, 2016

@aanand Thanks, a bug in the documentation misled me.

@lefterisnik
Copy link

@lefterisnik lefterisnik commented Oct 4, 2016

I face a similar problem when I have something like that on the docker-compose file:

entrypoint: /srv/wait-for-it.sh postgres:5432 --
command: bash -c "python manage.py migrate && uwsgi --ini /etc/web/uwsgi.ini --py-autoreload 1"

Also, when I try to run:

docker-compose run web bash -c "python manage.py migrate && uwsgi --ini /etc/web/uwsgi.ini --py-autoreload 1"

I get a python console only.

What am doing wrong?

@adonay28
Copy link

@adonay28 adonay28 commented Nov 13, 2016

I'm facing this issue too:

i have the entrypoint in docker-compose.yml:
entrypoint: ./wait-for-it.sh -t 60 --strict mydb:3306

and the cmd in the Dockerfile:
CMD ["java","-jar","Testone_10006.jar"]

It waits until the db is available but then it doesn't do anything.

@ghost
Copy link

@ghost ghost commented Nov 13, 2016

same problem here

@ngocdaothanh
Copy link

@ngocdaothanh ngocdaothanh commented Nov 24, 2016

Hey, from the discussion above I understand that entrypoint in docker-compose.yml will override CMD in Dockerfile.

But is there a way to embed the original CMD in Dockerfile to entrypoint in docker-compose.yml?

@imaia
Copy link

@imaia imaia commented Dec 27, 2016

Why override CMD when someone is only overriding entrypoint? Maybe, this "feature" just complicates things. Maybe it is a bug.

@james-turner
Copy link

@james-turner james-turner commented Jan 6, 2017

I'm also inclined to say I don't like this behaviour.

It would be preferable to either
a) maintain the original CMD in the parent image, such that when the child image specifies ENTYPOINT the 2 are concatenated (as expected) so you get ENTRYPOINT + CMD.
b) allow the child image to invoke the parent CMD such that you can manually compose ENTRYPOINT + CMD without having to copy/paste CMD from the parent image into your child dockerfile.

Otherwise; there is no way for child images to prefix a cmd in a parent image without having to duplicate the parent CMD invocation. The parent CMD might change in a subsequent version of the parent image, consequently causing the child image to break because the copied invocation is incorrect now.

@craigotis
Copy link

@craigotis craigotis commented Jan 7, 2017

This is really confusing to me. It seems crucial for a compose file to prepend to the command that's run by the underlying Dockerfile.

The compose file should not, IMO, be in charge of the commands run by the underlying Dockerfile unless that's the author's intention. This means that every time my Dockerfile commands change, for the multitude of application images I'm using, I have to know to also update my compose file - effectively duplicating config.

There needs to be a way to run a command (specified by the compose file) prior to the execution of the underlying CMD specified by the Dockerfile.

@stas stas mentioned this issue Jul 23, 2017
randomorder added a commit to randomorder/dati-ckan-docker that referenced this issue Nov 23, 2017
@shin-
Copy link
Contributor

@shin- shin- commented Mar 28, 2018

Closing as this is not a Compose issue.

@shin- shin- closed this Mar 28, 2018
@miguelpduarte
Copy link

@miguelpduarte miguelpduarte commented Sep 5, 2018

Is there a way to do this now?

I wish to prepend something to the command specified in the Dockerfile (in my case, a wait-for-it.sh call in order to wait for my DB service to start before the actual service starts) and have no way to call the "child" command (the one specified in the Dockerfile), having to resort to duplicating configuration, as mentioned above...

If there is no way to do this but to duplicate configuration I hereby request the issue to be reopened. Furthermore, this is clearly a compose issue, as defining the entrypoint in the docker-compose.yml file is what clears the command option - thus it cannot be anything BUT a compose issue.

@craigotis
Copy link

@craigotis craigotis commented Sep 5, 2018

I agree with @miguelpduarte's suggestion to reopen. If the maintainers (@shin-) disagree, can you please elaborate as to why this is:

not a Compose issue.

Even if the original Dockerfile command were to be exposed to the Compose file as a variable, that would allow maintainers of the "parent" Compose files to write their own entrypoints which are decoupled from the command logic/behavior of the underlying/"child" Dockerfile. As has been mentioned multiple times in this thread, wait-for-it is a very common use case:

entrypoint: ./wait-for-it.sh -t 60 --strict mydb:3306 && sh -c $DOCKERFILE_CMD

(I don't remember the exact wait-for-it syntax, but you get the idea.)

Thanks

@shin-
Copy link
Contributor

@shin- shin- commented Sep 5, 2018

Please refer to earlier responses in this thread: #3140 (comment)

This is the engine's behavior. We can't do anything about it from Compose's end. If you want to suggest it be changed, you'll need to submit a proposal on the moby/moby repo.

@craigotis
Copy link

@craigotis craigotis commented Sep 5, 2018

@shin- Is it not possible for Compose to offer, even as a secondary option, the ability to prepend the Docker container's command with the entrypoint command defined in the Compose file? As described: #3140 (comment)

It seems if it has the ability to overwrite it, it should also have the ability to add to it, and that's what I think most of the folks in this thread are focused on accomplishing.

@luckymagic7
Copy link

@luckymagic7 luckymagic7 commented Nov 21, 2018

Finally,

I just made another shell script to execute each command for docker-compose

#!/bin/sh

sudo docker-compose -f docker-compose.myfile.yml pull && sudo docker-compose -f docker-compose.myfile.yml up -d && docker exec $container /myfile.sh
@jsera-polyverse jsera-polyverse mentioned this issue Apr 26, 2019
0 of 2 tasks complete
@ceoro9
Copy link

@ceoro9 ceoro9 commented Jan 8, 2020

Any updates? This overriding behavior is really annoying.

The above proposed syntax to call CMD from Dockerfile was good.

entrypoint: ./wait-for-it.sh -t 60 --strict mydb:3306 && sh -c $DOCKERFILE_CMD

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
You can’t perform that action at this time.