moby: Permission denied on /dev/stderr

The following Docker run command returns the showed error message:

docker run -u $(id -u) -v $PWD:$PWD -w $PWD ubuntu sh -c 'echo Hola > /dev/stderr'  
sh: 1: cannot create /dev/stderr: Permission denied

Removing the -u command option it works fine.

This issue make impossible to run that apps that use the /dev/stderr output stream to report warning messages or other info.

About this issue

  • Original URL
  • State: closed
  • Created 10 years ago
  • Comments: 48 (17 by maintainers)

Commits related to this issue

Most upvoted comments

@willydee I have found that the above named pipe code may deadlock on a busy system. The fix was to change it into:

mkfifo -m 600 /tmp/logpipe
cat <> /tmp/logpipe 1>&2 &

where <> opens the pipe both for reading and writing before setting it as fd 0 for the cat. This way there is always a writer to the pipe and the cat never see EOF from the pipe due to absence of writers. Another improvement was to move mkfifo into the image to minimize container startup time.

For those coming here trying to figure out how to write access to /dev/stderr after having dropped privileges with gosu/su-exec/etc, I’ve added the following to my entrypoint script:

# Allow `nobody` user to write to /dev/stderr
mkfifo -m 600 /tmp/logpipe
chown nobody:nobody /tmp/logpipe
cat <> /tmp/logpipe 1>&2 &

The only difference from @ibukanov’s version is that I’m changing the owner of /tmp/logpipe to nobody as opposed to it being root (as the container starts as a privileged user and will create /tmp/logpipe with root as the owner). I’m using the nobody user in my container, but it could just as easily be www-data, nginx, etc. Thanks again, @ibukanov!

The new command logs promotes the use of /dev/stdout but only root can write there. But, for security, the use of root is not recommended. It’s kinda problematic, isn’t it.

As a workaround for docker versions before 1.9 I start an application when running non-root container from a wrapper shell script that does the following:

# Create a named pipe and redirect anything that comes to it
# to stderr connected to Docker.
mkfifo -m 600 /tmp/logpipe
cat < /tmp/logpipe 1>&2 &
exec original app command line 

Then I instruct the app (php5-fpm in my case) to log to /tmp/logpipe.

Depending on your usage of stdout. If you just want to print it to terminal so you can watch, you can workaround it by using

/dev/tty

instead of /dev/stderr or /dev/stdout.

As a workaround for docker versions before 1.9 I start an application when running non-root container from a wrapper shell script that does the following:

# Create a named pipe and redirect anything that comes to it
# to stderr connected to Docker.
mkfifo -m 600 /tmp/logpipe
cat < /tmp/logpipe 1>&2 &
exec original app command line 

Then I instruct the app (php5-fpm in my case) to log to /tmp/logpipe.

For those coming here tried FIFO but container crashed due to big blob of log, changing to unbuffer will prevent container from crashing

mkfifo -m 600 /tmp/logpipe
unbuffer cat /tmp/logpipe &

unbuffer from expect package

Docker 1.12.5 - this is still is an issue. non-root cannot write to /dev/stdout or /dev/stderr?

I read this thread twice and didn’t see it “dismissed”. Just a work around script for:

mkfifo -m 600 /tmp/logpipe
cat <> /tmp/logpipe 1>&2 &

And while this does work, it’s hacky and not documented.

Fix is here and I’ll update docker after it’s merged in runc/libcontainer

https://github.com/opencontainers/runc/pull/280