rabbitmq icon indicating copy to clipboard operation
rabbitmq copied to clipboard

Setting ENV HOME in this image is a terrible idea

Open nacitar opened this issue 5 years ago • 7 comments

In the dockerfiles you have this

# set home so that any '--user' knows where to put the erlang cookie
ENV HOME $RABBITMQ_DATA_DIR

If building a different container from this one, this gets inherited. The container will then run its own entrypoint, and within it you'll be running as root... with this nonsensical $HOME that is not root's. Of course, if you "su" at this point, the new shell will have the correct $HOME as indicated by /etc/passwd (like a sanely functioning linux system)... because it is not hijacked by this ENV line in the base image.

So, what would a user's options be to undo this? You cannot "unset" the environment variable. You can only set it explicitly to another value, such as /root... but then the environment variable override is STILL controlling the value of HOME; you can never get it to fall back upon the sane standard behavior of the system's passwd file controlling the location/value of $HOME in your entrypoint. This environment variable (and any other, really), once set, permanently ensures that the dockerfile WILL decide what the value will be in every future layer with the only choice being to use your value or some other... never able to make it be unspecified again.

You're typically advised to temporarily set environment variables in limited scopes, applying them to individual commands instead of using ENV... but usually failures to heed this advice are not really that impactful because they usually don't involve core system variables like HOME, USER, UID, etc... but of course this one is an exception.

I'm sure the slight convenience to do with erlang cookies implied by the comment is super neat for some people... but it forces an unfixable behavior that can only be worked around upon anyone layering on top.

nacitar avatar Nov 13 '20 21:11 nacitar

Interesting point -- I wonder if we could accomplish the goals of our current setting by making it part of the entrypoint instead, and having it check whether HOME is empty or set to / (which are the bad fallback behaviors) and have it only modify it in those cases (and then make sure our rabbitmq user has the right HOME value in /etc/passwd, which I hope it already does but haven't checked).

tianon avatar Nov 13 '20 21:11 tianon

That sounds like a viable option. With regard to your check, the value $HOME was set to in the container I observed this in (the :latest at the time of writing) matched that of the rabbitmq user's home.

EDIT: I also wanted to note that this issue was encountered; I didn't find the line in the Dockerfile and just think of the connotations and file this bug. I ran down a confusing problem and this is where I ended up.

nacitar avatar Nov 13 '20 21:11 nacitar

FWIW, setting HOME to the empty string appears to DTRT in Docker:

$ docker pull rabbitmq
Using default tag: latest
latest: Pulling from library/rabbitmq
Digest: sha256:f2e00e45bf9c9456618486f54dc4906eedde3cf1a2824a3bc9a3193da55f323a
Status: Image is up to date for rabbitmq:latest
docker.io/library/rabbitmq:latest

$ docker run --rm --user rabbitmq -e HOME= rabbitmq env | grep '^HOME'
HOME=/var/lib/rabbitmq
$ docker run --rm --user root -e HOME= rabbitmq env | grep '^HOME'
HOME=/root
$ docker run --rm --user nobody -e HOME= rabbitmq env | grep '^HOME'
HOME=/nonexistent


$ docker run --rm --user 1234:1234 -e HOME= rabbitmq env | grep '^HOME'
HOME=/
$ docker run --rm --user 1234:1234 rabbitmq env | grep '^HOME'
HOME=/var/lib/rabbitmq

I'm definitely curious about the use case -- what is it that you're trying to do that caused you to run into this issue?

tianon avatar Nov 13 '20 23:11 tianon

Not my task (I just figured out the problem for them), but it's effectively adding configuration versioning (pushing configuration changes to a repository to be tracked) to the rabbitmq container. The problem encountered was due to a cron job running with the correct HOME (/root) whereas the entry point that set things up for that cron job ran with a different HOME (/var/lib/rabbitmq) and thus wrote files that the cron job cared about (like .gitconfig) to the wrong place. It was extra annoying because opening a shell into the container also had the same overridden HOME, so testing from that context worked perfectly fine... so it manifest as "my script works... but not as a cron job! wtf?".

This use case is certainly not common, sure... but this issue was obscure enough I figured it was worth escalating.

nacitar avatar Nov 13 '20 23:11 nacitar

For this particular use case, as you suggested setting home to an empty string via "ENV HOME=" seems to work, but only because something within the distro is "fixing" it. If you test like this:

ENV FOO=banana
RUN env
ENV FOO=
RUN env

You can see that it is NOT the case that docker said "hey, that's blank... let's just not pass it!" which would be the "unspecified" state I'm after... it's that something within the distro checked and said "oh that's specified, but blank... let's populate it".

The env still prints out FOO as specified, but blank. For this reason I feel that puristically this is a bit meh, but in this specific instance is mitigated due to the distro behavior. The issue remains that it's quite unexpected that $HOME has been changed, and I imagine people trying to build FROM the container running into similar issues that I did... but it can be effectively undone with setting HOME to be blank, due to the distro behavior for this particular value, though technically with side-effect.

As an aside, not a docker expert, but FWIW it seems like ARG is implemented similarly to ENV, but without the inheritance into child Dockerfiles so some options could exist there, too.

nacitar avatar Nov 14 '20 17:11 nacitar

HOME is a special case in Docker itself -- it's the thing that's "fixing" it when it's empty.

tianon avatar Nov 14 '20 18:11 tianon

HOME is a special case in Docker itself -- it's the thing that's "fixing" it when it's empty.

I didn't know that. If that's the case then it's perfectly fixable, so the question becomes if the problems encountered due to this are worth avoiding... I now know that it can be worked around, but anyone else making a container from this one wouldn't know to set home to blank without first encountering this problem and working through it.

In either case, for my purposes this is fixed and sorry for my knowledge deficits along the way. Up to you if it warrants a change.

nacitar avatar Nov 14 '20 18:11 nacitar

Based on @tianon 's comment here and the fact that the behavior appears to be consistent, I'm going to close this issue.

If you'd like to see how I tested this on an up-to-date Arch Linux system, see the Makefile here: https://github.com/lukebakken/docker-library-rabbitmq-448

lukebakken avatar Feb 08 '23 21:02 lukebakken