It's _probably_ wrong to run stack as root, at least in almost all cases. This came up in another thread: https://github.com/commercialhaskell/stack/issues/464#issuecomment-117391353
Thanks @radix.
@manny-fp Perhaps you have thoughts on this?
Yeah big +1, I'm up for an error and exit unless --as-root is given as an option.
There are two Docker-related cases that come to mind where you might want to run stack as root:
1) Your system isn't setup to let non-root uses connect to the Docker daemon. Using sudo stack is not recommended as a solution to this problem anyway, since it will mess up the permissions of any files it writes on your host filesystem. Instead, best course of action is to allow non-root connections or use a wrapper script that automatically sudos any docker commands.
2) Occasionally you might want to poke around in a container as the root user, in which case sudo stack docker exec bash can be handy. But that should be rare so needing an override argument would be just fine.
So +1 from me.
-1. I don't see why this behavior is wanted. Running as root is common nowadays, both in docker and with various virtual machines to simplify deployment. When I fork out $5 to buy a VM for some testing, root is what I get, and there is no reason to add a non-root user to such a machine.
I would not want this behavior. I suggest stack only print a warning, if anything at all. I'd like to understand what problem this is solving that is worth making the semantics of stack depend on EUID?
both in docker and with various virtual machines to simplify deployment.
Creating a non privileged user is IMO part of a "simple" deployment. There is no need to break the least amount of (EDIT:) permissions rule to attribute deployments with "simple".
It is pretty common to run Docker stuff as root when using "trusted" containers, and I think it'll cause enough users grief if we prevent it that this shouldn't be an error. But running as root is different than running under sudo (without -i), which I think is at least something we should warn about and perhaps prevent (but make overridable).
How can you differentiate between running as root and running under sudo?
In both cases I get
Prelude> import System.Posix.User
Prelude System.Posix.User> getEffectiveUserID
0
Prelude System.Posix.User> getLoginName
*** Exception: getLoginName: does not exist (No such file or directory)
Prelude System.Posix.User> getRealUserID
0
The condition we'd really looking for is when Stack is running as root, but the ~/.stack or <project>/.stack-work directory isn't owned by root. sudo doesn't change $HOME by default, so this would detect the most common case and prevent permissions problems. But if you're running in a true root shell (with $HOME pointing to the root user's actual home directory) and building projects owned by root, Stack would continue as usual.
Looks like I should really get this done. :)
Fixed with #1599.
To summarize, for a non expert both in stack and docker, what I have to do run a program in a docker image that uses a script hardcoded that uses stack and does not include the --allow-different-user? flag?
@agocorona You can set allow-different-user: true in your project config or global config.
Running stack should work in the docker container without changing user, though, hmm.
The problem is that the project config is also created automatically
I found another workaround: creating an user in the docker instance and running everithing under this user:
RUN useradd -ms /bin/bash newuser && su newuser
Maybe I'm wrong about this, but I think stack still can't bootstrap ghcjs when running as root. The requirement to add allow-different-user: true infects the ghc-build so ghcjs (and maybe ghc) needs to be patched as well.
What's the expected behavior for bootstrapping compilers when running as root?
@agocorona creating a user in the docker image creates endless pain when you want to mount your build environment into the docker container.
(the reason being that uids in docker containers depend on the order in which users are added and thus does not compose in any meaningful way)
that's definitively an anti-pattern, and a reason why stack absolutely should work flawlessly as root and another reason why the basis for this issue is wrong.
I'm doing that currently with stack, because it's the only way to get it to work with ghcjs, but it's awful, and there's nothing but this feature request that is creating all of this pain.
@alexanderkjeldaas .Yes I experienced these problems. I agree with you. stack shouldn't care about permissions more than the user of stack itself and the Operating System. It should not dictate what are good or bad practices, specially since the usage cases evolve fast. My experience is that --allow-different-user do not work in medium to large compilations for unknown reasons. For this reason I use cabal under docker, but in this case, stack is imposed.
Here's another class of common use cases where this is a problem: building a project located on a file system that does not fully support the native permissions system of the shell you are running in. More specifically, you will run into this when your project is in NTFS and you try to build with stack from a unix-like environment. There are many combinations:
In these kinds of cases, all of the files you create show as being owned by root, even though you are not root. So stack refuses to run, claiming that you are not the owner, even though actually you yourself created the files normally without sudo.
adding:
allow-different-user: true
in config.yaml in the
solved all my problems.
It seems to be more general than adding it to the command line
Thanks, @agocorona. I would list the situation I ran into just FYI: running Windows Subsystem for Linux, having the source code (of hledger) on a Windows drive and trying to compile the project results in the "another-user" error (Retry with '--allow-different-user' to disable this precaution.)
Adding this line to project's stack.yaml helps.
Most helpful comment
adding:
in config.yaml in the/.stack/config.yaml
solved all my problems.
It seems to be more general than adding it to the command line