While poking the official rabbitmq container (3.6.0: 6c1bb940499a) I've noticed that I cannot easily run rabbitmqctl. When I attempt to pass rabbitmqctl as the container command it hangs:
$ docker run --rm -ti rabbitmq rabbitmqctl
<Several seconds pass, hit ctrl-c>
^C
BREAK: (a)bort (c)ontinue (p)roc info (i)nfo (l)oaded
(v)ersion (k)ill (D)b-tables (d)istribution
a
The BREAK appears to be coming from erlang. I've tried several combinations of options which all hang:
/bin/bash entrypoint, rabbitmqctl command fails slightly differently with an error about being unable to open ./rabbitmq-env, but I believe that's unrelated.
Interestingly, though, if I enter the container with a command of /bin/bash and run rabbitmqctl interactively it works. I haven't yet found what the differentiating factor is.
This is currently a blocker for me for using the official container as I need to be able to wrap rabbitmqctl for use outside the container. I wish to run Rabbit in a container but need rabbitmqctl to work from the host both for a management tool which assumes rabbitmqctl is installed locally. My intention is to wrap a command similar to the docker run above in a script which sets the node and erlang cookie.
EDIT: One of the cases I'd marked has hanging fails differently.
This is a hacky workaround: docker run -it --rm --link some-rabbit:my-rabbit -e RABBITMQ_ERLANG_COOKIE='secret cookie here' rabbitmq:3 bash -c 'rabbitmqctl -n rabbit@my-rabbit list_users && true'. My best guess is that the /usr/lib/erlang/erts-7.2/bin/beam.smp process tries to kill itself with a sigint but since it is pid 1 when bash is not there, it just stays alive indefinitely.
Thanks, that worked. In case others find it useful I've settled on this script do have the rabbitmqctl command on the host operate against the container:
#!/bin/bash
#
# rabbitmqctl helper: Helper script to run rabbitmqctl against the Rabbit container
# Use the similar longname logic as out of the container starter script
# https://github.com/docker-library/rabbitmq/blob/d9c4635649edacf6728bd2a28aedc97c77ac47f9/docker-entrypoint.sh#L15-L18
if [ "$(hostname -f)" != "$(hostname -s)" ]; then
LONGNAME_VAR="RABBITMQ_USE_LONGNAME=true "
else
LONGNAME_VAR=""
fi
# Command hackiness via https://github.com/docker-library/rabbitmq/issues/68
# Command variable required to make back handle arguments and quoting correctly.
COMMAND="${LONGNAME_VAR}/usr/sbin/rabbitmqctl"
# The following is lifted off https://github.com/rabbitmq/rabbitmq-server/blob/aae969130172ec5afc98a391f6f66a14cdd0a853/packaging/common/rabbitmq-script-wrapper
for arg in "$@" ; do
# Wrap each arg in single quotes and wrap single quotes in double quotes, so that they're passed through cleanly.
arg=`printf %s "$arg" | sed $SED_OPT -e "s/'/'\"'\"'/g"`
COMMAND="${COMMAND} '${arg}'"
done
COMMAND="${COMMAND} && /bin/true"
#echo "\"$COMMAND\""
# This uses an exec as rabbitmq-plugins needs filesystem access.
# As an exec generally works better than a separate container
# (no cookie, hostname, or erlang issues) it was picked as the path of least resistance.
# No sudo: restrict to root/docker admins
docker exec RabbitMQ bash -c "$COMMAND"
exit $?
Notes:
Also note that '-n rabbit@my-rabbit' doesn't work as the hostname has to match for erlang distribution to work. So if you link in as suggested you have to link as the hostname of the rabbit container. Erlang distribution, in my opinion, is ... fussy.
Erlang is not suited to work as pid 1 because it can't handle exits of processes it didn't start. Detailed discussion is at http://erlang.org/pipermail/erlang-questions/2015-December/thread.html#87141
bash process mentioned above just reserves pid 1 for itself, and erlang can happily work in this circumstances.
This looks like it was solved. Closing old issue.
Most helpful comment
This is a hacky workaround:
docker run -it --rm --link some-rabbit:my-rabbit -e RABBITMQ_ERLANG_COOKIE='secret cookie here' rabbitmq:3 bash -c 'rabbitmqctl -n rabbit@my-rabbit list_users && true'. My best guess is that the/usr/lib/erlang/erts-7.2/bin/beam.smpprocess tries to kill itself with a sigint but since it is pid 1 when bash is not there, it just stays alive indefinitely.