On 26/02/2015 15:38, John Regan wrote:
When you build a Docker image, the ENTRYPOINT is what program you want
to run as PID1 by default. It can be the path to a program, along with some
arguments, or it can be null.

CMD is really just arguments to your ENTRYPOINT, unless ENTRYPOINT is
null, in which case it becomes your effective ENTRYPOINT.

At build-time, you can specify a default CMD, which is what gets run
if no arguments are passed to docker run.

 OK, got it.


I'm going to call these case 1 (command with no supervision environment), case
2 (default supervision environment), and case 3 (supervision environment with
a provided command).

Here's a breakdown of each case's invocation, given a set ENTRYPOINT and CMD:

ENTRYPOINT = null, CMD = /init

* Case 1: `docker run image commandline`
* Case 2: `docker run image
* Case 3: `docker run image /init commandline`

ENTRYPOINT = /init, CMD = null

* Case 1: `docker run --entrypoint="" image commandline`
* Case 2: `docker run image`
* Case 3: `docker run image commandline`

 Makes sense so far.


Now, something worth noting is that none of these command run interactively -
to run interactively, you run something like 'docker run -ti ubuntu /bin/sh'.

-t allocates a TTY, and -i keeps STDIN open.

So, I think the right thing to do is make /init check if there's a TTY
allocated and that STDIN is open, and if so, just exec into the passed
arguments without starting the supervision tree.

 ... but here I disagree.
 Performing different actions when a fd is a tty from when it is not
breaks the principle of least surprise. It's counter-intuitive,
generally bad practice, and simply not what you want in most cases.
It's okay for simple user interface stuff, such as programs that
pretty-print their output when stdout is a terminal, but in the
docker container case I don't think it's justified.


ENTRYPOINT = /init (with TTY/STDIN detection), CMD = null

* Case 1: `docker run -ti image commandline`
* Case 2: `docker run image`
* Case 3: `docker run image commandline`

So basically, if you want to run your command interactively with no execution
environment, you just pass '-ti' to 'docker run' like you normally do. If
you want it to run under the supervision tree, just don't pass the '-ti'
flags. This makes the image work like pretty much every image ever, and
the user doesn't ever need to type out "/init".

 The main problem with that approach is that there's no way to run an
interactive command with the supervision environment - but it's something
that users are very likely to need. What if I want my services to run,
but at the same time I want a shell inside the container to explore and
debug things ?

 I think you're better off with:

 * Case 1 : docker run --entrypoint="" image commandline
(with or without -ti depending on whether you need an interactive terminal)
 * Case 2 : docker run image
 * Case 3: docker run image commandline
(with or without -ti depending on whether you need an interactive terminal)

 docker run --entrypoint="" -ti image /bin/sh
would start a shell without the supervision tree running

 docker run -ti image /bin/sh
would start a shell with the supervision tree up.


Laurent, how hard is it to check if you're attached to a TTY or not?

 It's not hard at all:
 http://pubs.opengroup.org/onlinepubs/9699919799/functions/isatty.html
 (then you need a command line that does this, but I think busybox
provides one, and in the worst case it's trivial to write.)
 However, I don't think it's a good idea to do so in this case.

--
 Laurent

Reply via email to