On Wednesday, January 8, 2014 8:37:30 AM UTC, Philippe Lafoucrière wrote:> I know it's working, I'm just saying I can't understand these 3 lines> without reading carefully twice the doc.> It's probably just me :)
It's not just you - I've been messing around with docker for a wee while now and only yesterday had a first stab at playing around with/understanding CMD and ENTRYPOINT and I must say it wasn't immediately obvious what was going on and how I could/should use them, so I do think that there must be a better way.As far as I can tell (I hope I've got it right) it seems that you use CMD on it's own if you want to be able to overwrite the whole command when doing a docker run. You use ENTRYPOINT on it's own if you want to always run the specified command when running the container and anything added when doing a docker run is treated as additional arguments to that command. You use both if you want to specify some default arguments to ENTRYPOINT that can be overwritten when using docker run.Could all this not be handled just using the ENTRYPOINT directive but adding some form of optional parameter syntax, e.g.ENTRYPOINT [ "/entrypoint.sh", { defaults: ["python", "agent.py"] } ]Then we wouldn't need the CMD directive at all. If you need to override the actual command then use the -entrypoint option to docker run instead of using CMD. If -entrypoint is given an empty string it would have the effect of totally ignoring the ENTRYPOINT (so the full command could be specified on the end of the docker run command. If entrypoint is given a non-empty string then it replaces the contaiters entry point. Or I guess the -entrypoint options could be replaced with an -ignnore-entrypoint that dwas just a flag.
On Wednesday, January 8, 2014 1:50:53 AM UTC, gwfran wrote:> I'm not sure why you can't use multiple CMD (or ENTRYPOINT, for that matter)> where the launch of the container would just loop through the list of> commands, execute them, and then return the state of the last CMD.
The complications I can see with this would be what to do if one of the commands fails, do you exit immediately and return it's error code or do you move on to the next command (either behaviour could have undesirable effects depending what you actually want to happen - if you handle this yourself in your single script - it's something you can decide and docker's life is kept simple). Also if you want to stop the container using docker stop and you could at the time be running any one of multiple commands how does docker know which process to send a SIGTERM to?roovo
My 2 cents on the topic of JSON syntax vs. shell syntax. I’ve found some features of the shell syntax are useful in Dockerfiles. Here are a couple of examples:
CMD bundle exec rake db:create && \
bundle exec rake db:migrate && \
bundle exec rails server
I suppose this can still be done in JSON syntax by explicitly calling the shell, so it’s still possible but harder to get right. Something like:
CMD ['sh', '-c', 'bundle exec rake db:create && \
bundle exec rake db:migrate && \
bundle exec rails s']
(I had to look at the sh
man page to remind myself that -c
was the right cmd-line arg, which goes to show you that it’s harder to get right.)
CMD ["su", "postgres", "-c", "/usr/lib/postgresql/$PG_VERSION/bin/postgres -D /var/lib/postgresql/$PG_VERSION/main/ -c config_file=/etc/postgresql/$PG_VERSION/main/postgresql.conf"]
It’s true that even in shell syntax you’d have to remember to put quotes around the command that su
executes:
CMD su postgres -c "/usr/lib/postgresql/$PG_VERSION/bin/postgres -D /var/lib/postgresql/$PG_VERSION/main/ -c config_file=/etc/postgresql/$PG_VERSION/main/postgresql.conf"
but that’s something you’re more used to seeing in scripts, so it doesn’t seem quite so mind-bending.
So in the end, I think it’s nice to have both syntaxes available.
I believe the more confusing point, which I think is in greater need of a change, is the other one people have been discussing: the CMD
and ENTRYPOINT
instructions. Tianon’s example was pretty cool—having an entrypoint that does some configuration and then runs the CMD. I could be convinced to move my rake db:create && rake db:migrate
example to a shell script that runs those two commands as an entrypoint and then runs the cmd. But I do agree with the point someone made, that it’s not immediately obvious what it’s doing. The power is wonderful but if the Dockerfile syntax can be changed to something that makes it more clear what’s going on, that would be nice.
Brian Morearty
Hands on with Docker
http://handsonwith.com/
--
You received this message because you are subscribed to the Google Groups "docker-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to docker-dev+...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
James, can you please elaborate on this part of your original question?
a lexer that recognizes and can parse appropriate shell commands and their flags from a variety of shells in either instruction
What did you mean? Perhaps an example would help.
I have one more thought on this part:
Other alternatives include settling on the JSON exec format.
For me, the JSON exec format is annoying to type. It’s hard to make your fingers get it right with all the brackets, quotes, and commas—even when your brain knows what to do.
So if the desire is to have a single syntax and you prefer not to call out to the shell implicitly, I would propose this: the new syntax should be unbracketed and unquoted, but should be tokenized and exec’d as if it were the JSON syntax. For example:
# This gets exec'd, not run in the shell:
CMD executable flag
As a bonus user-friendly feature, it could watch for unquoted shell tokens (&&
,||
,|
,&
,<
,>
,2>
, etc.) and give a warning:
CMD command1 && command2
$ docker build .
WARNING: for shell syntax use:
sh -c "command1 && command2"
or use quotes to hide this warning:
command1 "&&" command2
And, finally, about quotes: if you do end up keeping the JSON syntax, please add support for single-quoted strings. It’s unintuitive that it looks like JSON but only supports double-quoted strings. See this post for an example of the trouble it can cause.
Brian Morearty
Hands on with Docker trainer
Come to think of it, Upstart’s approach for “exec” is a bit nicer than what I suggested:
Note that if this command-line contains any shell meta-characters, it will be passed through a shell prior to being executed. This ensures that shell redirection and variable expansion occur as expected.
Thanks.I should clarify that when I said "give a warning" I really meant "give an error." :-)When docker build shows warnings, they are hard to see because they're typically in the middle of a bunch of other output.Brian