docker-iojs
docker-iojs copied to clipboard
Run as a non-privileged user by default
This is a proposal for resolving #23. It does two things:
- A non-privileged user called
app
is created in all images. The user is explicitly created with highuid
andgid
, in order to make collisions with the host improbable. - The default
CMD
commands are changed to execute asapp
instead ofroot
(usingsu -c ...
). This matters most foronbuild
, which is most likely to use the default command, but is also useful in the other variants (as an example for proper invocation).
I decided not to use USER app
for changing the user, because that would have unwanted side effects and would likely break many derivative images. For example, derivatives would have to change back to USER root
in order to install additional distro packages.
There is one caveat with this change. Apps can no longer write inside their src directory by default (as it is owned by root
). IMHO this is a feature, not a bug - apps should not be able to modify their own source. They should use /home/app
for storage instead, or a volume, or another location with explicitly set permissions.
/cc the Docker team as well @tianon @yosifkit @jfrazelle
// CC @rvagg
There is one caveat with this change. Apps can no longer write inside their src directory by default (as it is owned by root)
When you refer to their source directory, are you referring to /usr/src/app in the ONBUILD
container? Would it be safe to have the new app
user take ownership of that folder?
hmmm maybe take a look at https://github.com/jfrazelle/irssi for a good way to run as another user, I know personally I'm not a fan of su
for CMD
, but that's not to say someone from docker might disagree with me :) and like it
While I'm definitely +1 with trying to run as a different user whenever possible, "su" has very odd characteristics that make it generally unsuitable for the task -- for one, it stays resident (so our actual process will be a child of "su", which screws up signals), and for another it does strange things with the TTY.
I'm still in the camp that this probably isn't something we can do automatically for users of language stacks in the general case, and that documenting how to appropriately use USER in a dependent Dockerfile is going to be a more robust solution.
The biggest problem I see is for developers. Unless they chmod all their code world readable the container will not be able to read the files. There could be an entrypoint script that chowns or chmods the files to the correct user, but then that hurts users that are bind mounting their code as they would be unable to edit it (or forced to have world readable). I am really with @tianon, that this is a docs problem (https://github.com/joyent/docker-node/issues/1#issuecomment-71889626).
+1 for the solution from @jfrazelle The modification could be (for the onbuild Dockerfile): (edited because it seems COPY cannot set rights on files copied, let me know if I'm wrong)
FROM iojs:1.2.0
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
+ENV HOME /home/user
+RUN useradd --create-home --home-dir $HOME user \
+ && chown -R user:user /usr/src/app
ONBUILD COPY package.json /usr/src/app/
ONBUILD RUN npm install
ONBUILD COPY . /usr/src/app
+ ONBUILD RUN chown -R user:user /usr/src/app
+ ONBUILD USER user
CMD [ "npm", "start" ]
And so the container can read and write the files. @yosifkit
I would prefer make things easier (and by default) for users to run securely application instead of having to dig in the documentation to know how to do it. @tianon
I think the hardest part here is that this still doesn't cover the developer that wants to bind mount in their code so that they can edit it on their host machine and see changes as they develop using something like node-supervisor (ex: docker run -it --rm -v /my/code:/usr/src/app my-node
). That way they do not have to docker stop
, docker build
, and docker run
for every change.
I have another concern: in some secure conscious environment the system administrator remains the only user who is granted access to the docker commands.
The administrator can't keep up with reviewing the changes in the Dockerfiles. So he always runs the containers with a non-root user and enforces that on the command-line:
docker run --user app ...
.
In my case the app
user is not granted access to chown
and chmod
as enforced by SELinux on Redhat.
So I would not be able to take advantage of this image.
Is this something we can address here?
For the :onbuild
image I think we could chown /usr/src/app
to the app
user, and let it be up to the person starting the container if they want to run it as --user app
or default root
(both should work in this case). I do not think it should create any problems for those who wish to continue to run their containers as root. I'll give it a try when I get the time.
@Starefossen ok got it. Thanks.